Swift生产服务器性能远程监控 - 完全免费版

Get Involved with Perfect!

Star Perfect On Github Stack Overflow Follow Perfect on Twitter Join the Perfect Slack

Swift 3.0 Platforms OS X | Linux License Apache PerfectlySoft Twitter Slack Status

Swift 在服务器端的应用在业界非常热门,但是仍处于方兴未艾。其中有一个较大的影响因素,就是很少有Swift全栈工程师或者管理员知道如何通过浏览器或者手机监控服务器的运行。

幸运的是,Perfect公司公布了最新的免费开源项目Perfect SysInfo,即用于实时获取系统性能指标数据的一组函数库。

作为参考,本文的全部源代码可以在这里获得:
http://github.com/PerfectExamples/SystemMonitor-Demo

请确保您的系统已经安装了Swift 3.1工具链。

下载、编译和运行

请打开终端并执行如下命令行进行下载、编译和运行:


$ git clone https://github.com/PerfectExamples/SystemMonitor-Demo.git
$ cd SystemMonitor-Demo
$ swift build
$ ./.build/debug/SystemMonitor

如果成功的化,终端会输出类似 [INFO] Starting HTTP server localhost on 0.0.0.0:8888 的字样。

此时您可以打开浏览器并输入网址:http://localhost:8888:

源码简介

注意,如果您还不熟悉 Perfect 服务器,请首先尝试学习 Perfect Template 服务器模板项目

接口函数路由

本服务器包含两个基本路由,一个是/api,用于读取服务器的JSON实时报告,而/**则实际上就是映射了index.html作为主页。


"routes":[
  ["method":"get", "uri":"/api", "handler":handler],
  ["method":"get", "uri":"/**", "handler":PerfectHTTPServer.HTTPHandler.staticFiles,
   "documentRoot":"./webroot"]
]

系统信息

考虑到 SysInfo 能够提供的系统指标非常丰富,因此有必要只选择需要的指标进行监控。

下列代码过滤出了少量用于监控的指标,并转换为一个JSON字符串。请注意操作系统的差异:

  • CPU 用量: 平均空闲事件、系统占用和用户占用,所有指标为百分比
  • 空闲内存数量
  • 网络吞吐量
  • 磁盘吞吐量

extension SysInfo {
  static var express: String? {
    get {
      #if os(Linux)
        guard
          let cpu = SysInfo.CPU["cpu"],
          let mem = SysInfo.Memory["MemAvailable"],
          let net = SysInfo.Net["enp0s3"],
          let dsk = SysInfo.Disk["sda"],
          let wr = dsk["writes_completed"],
          let rd = dsk["reads_completed"]
          else {
            return nil
        }
      #else
        guard
          let cpu = SysInfo.CPU["cpu"],
          let mem = SysInfo.Memory["free"],
          let net = SysInfo.Net["en0"],
          let dsk = SysInfo.Disk["disk0"],
          let wr = dsk["bytes_written"],
          let rd = dsk["bytes_read"]
          else {
            return nil
        }
      #endif
      guard
        let idl = cpu["idle"],
        let user = cpu["user"],
        let system = cpu["system"],
        let nice = cpu["nice"],
        let rcv = net["i"],
        let snd = net["o"]
        else {
          return nil
      }

      let total = (idl + user + system + nice) / 100
      let idle =  idl / total
      let usr = user / total
      let sys = system / total
      let MB = UInt64(1048576)
      let report : [String: Int]
          = ["idle": idle, "usr": usr, "sys": sys, "free": mem,
             "rcv": rcv, "snd": snd,
             "rd": Int(rd / MB), "wr": Int(wr / MB)]
      do {
        return try report.jsonEncodedString()
      }catch {
        return nil
      }//end do
    }
  }
}

执行这段代码后,产生的JSON字符串应该看起来像这样:

{"rd":59891,"snd":0,"idle":92,"wr":79394,"sys":3,"usr":4,"free":5671,"rcv":11964}

其中

  • idle:CPU空闲用量百分比,例子中为 92%
  • sys: CPU系统用量百分比,例子中为3%
  • usr: CPU用户用量百分比,例子中为4%
  • free: 当前空闲内存,例子中为5.6GB
  • rev: 当前主网卡收到数据量,大约12MB
  • snd: 当前主网卡发出数据量,基本为0
  • rd:当前主硬盘累积读取数据,约60GB
  • wr:当前主硬盘累积写入数据,大约80GB

请求/响应 处理器

收到请求后,服务器立刻将系统信息的JSON字符串发回给客户:


func handler(data: [String:Any]) throws -> RequestHandler {
    return {
        _ , res in
    guard let report = SysInfo.express else {
      res.status = .badGateway
      res.completed()
      return
    }//end
        res.setHeader(.contentType, value: "text/json")
    .appendBody(string: report)
    .completed()
    }
}

网页渲染监控数据

主页内容就相对简单了:即使用promises(承诺线程)下载服务器数据并在某个绘图框架下渲染,比如使用 ChartJS:

/// 构造一个图表
function setup(api) {
  var ctx = document.getElementById(api).getContext("2d");
  return new Chart(ctx, {
    type: 'line',
    data: {  datasets: datagroups[api]   },
    options: {
        scales: {
            xAxes: [{
                type: 'linear',
                position: 'bottom'
            }]
        }
    }
  });
}//end setup

/// 从服务器下拉实时数据,JSON解码并在图表中渲染
function update(){
  fetch('http://' + window.location.host + '/api',{method: 'get'})
  .then( (resp) => { return resp.json() })
  .then( (obj) => {

    var chart = charts["cpu"];
    var dset = chart.chart.config.data.datasets;
    appendDataTo(dset, "CPU-idle", counter, obj.idle);
    appendDataTo(dset, "CPU-user", counter, obj.usr);
    appendDataTo(dset, "CPU-system", counter, obj.sys);
    chart.update();

    var chart = charts["mem"];
    var dset = chart.chart.config.data.datasets;
    appendDataTo(dset, "MEM-free", counter, obj.free);
    chart.update();

    var chart = charts["net"];
    var dset = chart.chart.config.data.datasets;
    appendDataTo(dset, "NET-recv", counter, obj.rcv);
    appendDataTo(dset, "NET-snd", counter, obj.snd);
    chart.update();

    var chart = charts["ios"];
    var dset = chart.chart.config.data.datasets;
    appendDataTo(dset, "DISK-read", counter, obj.rd);
    appendDataTo(dset, "DISK-write", counter, obj.wr);
    chart.update();

    counter += 1;

  });
}//end function

/// repeatedly polling data every second
window.setInterval(update, 1000);

更多信息

关于本项目更多内容,请参考perfect.org
关注Perfect 源代码仓库并给我们的项目加一个大星星✨:
https://github.com/PerfectlySoft/Perfect

扫一扫 Perfect 官网微信号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值