Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
来自CloudWiki
目录
简介
psutil 是一个跨平台库(http://pythonhosted.org/psutil)能够获取到系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。主要用来做系统监控,性能分析,进程管理。支持 Linux、Mac OS、Windows 系统。
本文以 psutil 模块获取系统信息开发一个监控 Windows 系统的平台。
技术选择
- 监控的系统是 Windows 系统
- 监控系统模块选择 psutil 模块
- Web 框架选择的是 Flask 框架
- 前端 UI 选择的是 Bootstrap UI
- 动态可视化图表选择 Pyecharts 模块
技术准备
安装 psutil
pip3 install psutil
安装 Flask、pyecharts、Bootstrap
Flask 的教程是在公众号文章:Web 开发 Flask 介绍
Pyecharts 的教程在公众号文章:Python 图表利器 pyecharts,按照官网 (http://pyecharts.org/#/zh-cn/web_flask) 文档整合 Flask 框架,并使用定时全量更新图表。
Bootstrap 是一个 前端的 Web UI,官网地址是 (https://v4.bootcss.com)
获取系统信息
CPU信息
通过 psutil 获取 CPU 信息
>>> import psutil # 获取当前 CPU 的利用率 >>> psutil.cpu_percent() 53.8 # 获取当前 CPU 的用户/系统/空闲时间 >>> psutil.cpu_times() scputimes(user=197483.49, nice=0.0, system=114213.01, idle=1942295.68) # 1/5/15 分钟之内的 CPU 负载 >>> psutil.getloadavg() (7.865234375, 5.1826171875, 4.37353515625) # CPU 逻辑个数 >>> psutil.cpu_count() 4 # CPU 物理个数 >>> psutil.cpu_count(logical=False) 2
在监控平台上每 2 秒请求 url 获取 CPU 负载,并动态显示图表:
cpu_percent_dict = {} def cpu(): # 当前时间 now = time.strftime('%H:%M:%S', time.localtime(time.time())) # CPU 负载 cpu_percent = psutil.cpu_percent() cpu_percent_dict[now] = cpu_percent # 保持在图表中 10 个数据 if len(cpu_percent_dict.keys()) == 11: cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0]) def cpu_line() -> Line: cpu() # 全量更新 pyecharts 图表 c = ( Line() .add_xaxis(list(cpu_percent_dict.keys())) .add_yaxis('', list(cpu_percent_dict.values()), areastyle_opts=opts.AreaStyleOpts(opacity=0.5)) .set_global_opts(title_opts=opts.TitleOpts(title = now + "CPU负载",pos_left = "center"), yaxis_opts=opts.AxisOpts(min_=0,max_=100,split_number=10,type_="value", name='%')) ) return c @app.route("/cpu") def get_cpu_chart(): c = cpu_line() return c.dump_options_with_quotes()
内存
def memory(): memory = psutil.virtual_memory() swap = psutil.swap_memory() return memory.total, memory.used, \ memory.free, swap.total, swap.used, swap.free, memory.percent def memory_liquid() -> Gauge: mtotal, mused, mfree, stotal, sused, sfree, mpercent = memory() c = ( Gauge() .add("", [("", mpercent)]) .set_global_opts(title_opts=opts.TitleOpts(title="内存负载", pos_left = "center")) ) return mtotal, mused, mfree, stotal, sused, sfree, c @app.route("/memory") def get_memory_chart(): mtotal, mused, mfree, stotal, sused, sfree, c = memory_liquid() return jsonify({'mtotal': mtotal, 'mused': mused, 'mfree': mfree, 'stotal': stotal, 'sused': sused, 'sfree': sfree, 'liquid': c.dump_options_with_quotes()})
https://blog.csdn.net/ityouknow/article/details/105985451
磁盘
通过 psutil 获取磁盘大小、分区、使用率和磁盘IO
在监控平台上每 2 秒请求 url 获取磁盘信息,并动态显示图表
def disk(): disk_usage = psutil.disk_usage('/') disk_used = 0 # 磁盘已使用大小 = 每个分区的总和 partitions = psutil.disk_partitions() for partition in partitions: partition_disk_usage = psutil.disk_usage(partition[1]) disk_used = partition_disk_usage.used + disk_used now = time.strftime('%H:%M:%S', time.localtime(time.time())) count = psutil.disk_io_counters() read_bytes = count.read_bytes write_bytes = count.write_bytes # 第一次请求 if disk_dict['len'] == -1: disk_dict['pre_write_bytes'] = write_bytes disk_dict['pre_read_bytes'] = read_bytes disk_dict['len'] = 0 return disk_usage.total, disk_used, disk_usage.free # 当前速率=现在写入/读取的总字节-前一次请求写入/读取的总字节 disk_dict['write_bytes'].append((write_bytes - disk_dict['pre_write_bytes'])/1024) disk_dict['read_bytes'].append((read_bytes - disk_dict['pre_read_bytes'])/ 1024) disk_dict['disk_time'].append(now) disk_dict['len'] = disk_dict['len'] + 1 # 把现在写入/读取的总字节放入前一个请求的变量中 disk_dict['pre_write_bytes'] = write_bytes disk_dict['pre_read_bytes'] = read_bytes # 保持在图表中 50 个数据 if disk_dict['len'] == 51: disk_dict['write_bytes'].pop(0) disk_dict['read_bytes'].pop(0) disk_dict['disk_time'].pop(0) disk_dict['len'] = disk_dict['len'] - 1 return disk_usage.total, disk_used, disk_usage.free def disk_line() -> Line: total, used, free = disk() c = ( Line(init_opts=opts.InitOpts(width="1680px", height="800px")) .add_xaxis(xaxis_data=disk_dict['disk_time']) .add_yaxis( series_name="写入数据", y_axis=disk_dict['write_bytes'], areastyle_opts=opts.AreaStyleOpts(opacity=0.5), linestyle_opts=opts.LineStyleOpts(), label_opts=opts.LabelOpts(is_show=False), ) .add_yaxis( series_name="读取数据", y_axis=disk_dict['read_bytes'], yaxis_index=1, areastyle_opts=opts.AreaStyleOpts(opacity=0.5), linestyle_opts=opts.LineStyleOpts(), label_opts=opts.LabelOpts(is_show=False), ) .extend_axis( yaxis=opts.AxisOpts( name_location="start", type_="value", is_inverse=True, axistick_opts=opts.AxisTickOpts(is_show=True), splitline_opts=opts.SplitLineOpts(is_show=True), name='KB/2S' ) ) .set_global_opts( title_opts=opts.TitleOpts( title="磁盘IO", pos_left="center", pos_top="top", ), tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"), legend_opts=opts.LegendOpts(pos_left="left"), xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False), yaxis_opts=opts.AxisOpts(type_="value", name='KB/2S'), ) .set_series_opts( axisline_opts=opts.AxisLineOpts(), ) ) return total, used, free, c @app.route("/disk") def get_disk_chart(): total, used, free, c = disk_line() return jsonify({'total': total, 'used': used, 'free': free, 'line': c.dump_options_with_quotes()})
网卡
通过 psutil 获取网络接口和网络连接的信息
在监控平台上每 2 秒请求 url 获取网卡IO,并动态显示图表
def net_io(): now = time.strftime('%H:%M:%S', time.localtime(time.time())) # 获取网络信息 count = psutil.net_io_counters() g_sent = count.bytes_sent g_recv = count.bytes_recv # 第一次请求 if net_io_dict['len'] == -1: net_io_dict['pre_sent'] = g_sent net_io_dict['pre_recv'] = g_recv net_io_dict['len'] = 0 return # 当前网络发送/接收的字节速率 = 现在网络发送/接收的总字节 - 前一次请求网络发送/接收的总字节 net_io_dict['net_io_sent'].append(g_sent - net_io_dict['pre_sent']) net_io_dict['net_io_recv'].append(g_recv - net_io_dict['pre_recv']) net_io_dict['net_io_time'].append(now) net_io_dict['len'] = net_io_dict['len'] + 1 net_io_dict['pre_sent'] = g_sent net_io_dict['pre_recv'] = g_recv # 保持在图表中 10 个数据 if net_io_dict['len'] == 11: net_io_dict['net_io_sent'].pop(0) net_io_dict['net_io_recv'].pop(0) net_io_dict['net_io_time'].pop(0) net_io_dict['len'] = net_io_dict['len'] - 1 def net_io_line() -> Line: net_io() c = ( Line() .add_xaxis(net_io_dict['net_io_time']) .add_yaxis("发送字节数", net_io_dict['net_io_sent'], is_smooth=True) .add_yaxis("接收字节数", net_io_dict['net_io_recv'], is_smooth=True) .set_series_opts( areastyle_opts=opts.AreaStyleOpts(opacity=0.5), label_opts=opts.LabelOpts(is_show=False), ) .set_global_opts( title_opts=opts.TitleOpts(title="网卡IO", pos_left = "center"), xaxis_opts=opts.AxisOpts( axistick_opts=opts.AxisTickOpts(is_align_with_label=True), is_scale=False, boundary_gap=False, ), yaxis_opts=opts.AxisOpts(type_="value", name='B/2S'), legend_opts=opts.LegendOpts(pos_left="left"), )) return c
进程
通过 psutil 可以获取所有进程的信息
# 所有进程的 pid >>> psutil.pids() [0, 1, 134, 135, 138, 139, 140, 141, 144, 145, 147, 152, ..., 30400, 97792] # 单个进程 >>> p = psutil.Process(30400) # 名称 >>> p.name() 'pycharm' # 使用内存负载 >>> p.memory_percent() 12.838459014892578 # 启动时间 >>> p.create_time() 1587029962.493182 # 路径 >>> p.exe() '/Applications/PyCharm.app/Contents/MacOS/pycharm' # 状态 >>> p.status() 'running' # 用户名 >>> p.username() 'imeng' # 内存信息 >>> p.memory_info() pmem(rss=1093005312, vms=9914318848, pfaults=7813313, pageins=8448)
def process(): result = [] process_list = [] pid = psutil.pids() for k, i in enumerate(pid): try: proc = psutil.Process(i) ctime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(proc.create_time())) process_list.append((str(i), proc.name(), proc.cpu_percent(), proc.memory_percent(), ctime)) except psutil.AccessDenied: pass except psutil.NoSuchProcess: pass except SystemError: pass process_list.sort(key=process_sort, reverse=True) for i in process_list: result.append({'PID': i[0], 'name': i[1], 'cpu': i[2], 'mem': "%.2f%%"%i[3], 'ctime': i[4]}) return jsonify({'list': result}) def process_sort(elem): return elem[3] @app.route("/process") def get_process_tab(): c = process() return c @app.route("/delprocess") def del_process(): pid = request.args.get("pid") os.kill(int(pid), signal.SIGKILL) return jsonify({'status': 'OK'})
代码
app.py
import os, signal from random import randrange from flask import Flask, render_template, jsonify, request from pyecharts import options as opts from pyecharts.charts import Bar, Line, Liquid, Gauge, Grid import pyecharts.options as opts import time import psutil app = Flask(__name__, static_folder="templates") cpu_percent_dict = {} net_io_dict = {'net_io_time':[], 'net_io_sent': [], 'net_io_recv': [], 'pre_sent': 0, 'pre_recv': 0, 'len': -1} disk_dict = {'disk_time':[], 'write_bytes': [], 'read_bytes': [], 'pre_write_bytes': 0, 'pre_read_bytes': 0, 'len': -1} def cpu(): now = time.strftime('%H:%M:%S', time.localtime(time.time())) cpu_percent = psutil.cpu_percent() cpu_percent_dict[now] = cpu_percent # 保持在图表中 10 个数据 if len(cpu_percent_dict.keys()) == 11: cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0]) def cpu_line() -> Line: now = time.strftime('%Y年%m月%d日的', time.localtime(time.time())) cpu() c = ( Line() .add_xaxis(list(cpu_percent_dict.keys())) .add_yaxis('', list(cpu_percent_dict.values()), areastyle_opts=opts.AreaStyleOpts(opacity=0.5)) .set_global_opts(title_opts=opts.TitleOpts(title = now + "CPU负载",pos_left = "center"), yaxis_opts=opts.AxisOpts(min_=0,max_=100,split_number=10,type_="value", name='%')) ) return c def memory(): memory = psutil.virtual_memory() swap = psutil.swap_memory() return memory.total, memory.used, \ memory.free, swap.total, swap.used, swap.free, memory.percent def memory_liquid() -> Gauge: mtotal, mused, mfree, stotal, sused, sfree, mpercent = memory() c = ( Gauge() .add("", [("", mpercent)]) .set_global_opts(title_opts=opts.TitleOpts(title="内存负载", pos_left = "center")) ) return mtotal, mused, mfree, stotal, sused, sfree, c def net_io(): now = time.strftime('%H:%M:%S', time.localtime(time.time())) # 获取网络信息 count = psutil.net_io_counters() g_sent = count.bytes_sent g_recv = count.bytes_recv # 第一次请求 if net_io_dict['len'] == -1: net_io_dict['pre_sent'] = g_sent net_io_dict['pre_recv'] = g_recv net_io_dict['len'] = 0 return # 当前网络发送/接收的字节速率 = 现在网络发送/接收的总字节 - 前一次请求网络发送/接收的总字节 net_io_dict['net_io_sent'].append(g_sent - net_io_dict['pre_sent']) net_io_dict['net_io_recv'].append(g_recv - net_io_dict['pre_recv']) net_io_dict['net_io_time'].append(now) net_io_dict['len'] = net_io_dict['len'] + 1 net_io_dict['pre_sent'] = g_sent net_io_dict['pre_recv'] = g_recv # 保持在图表中 10 个数据 if net_io_dict['len'] == 11: net_io_dict['net_io_sent'].pop(0) net_io_dict['net_io_recv'].pop(0) net_io_dict['net_io_time'].pop(0) net_io_dict['len'] = net_io_dict['len'] - 1 def net_io_line() -> Line: net_io() c = ( Line() .add_xaxis(net_io_dict['net_io_time']) .add_yaxis("发送字节数", net_io_dict['net_io_sent'], is_smooth=True) .add_yaxis("接收字节数", net_io_dict['net_io_recv'], is_smooth=True) .set_series_opts( areastyle_opts=opts.AreaStyleOpts(opacity=0.5), label_opts=opts.LabelOpts(is_show=False), ) .set_global_opts( title_opts=opts.TitleOpts(title="网卡IO", pos_left = "center"), xaxis_opts=opts.AxisOpts( axistick_opts=opts.AxisTickOpts(is_align_with_label=True), is_scale=False, boundary_gap=False, ), yaxis_opts=opts.AxisOpts(type_="value", name='B/2S'), legend_opts=opts.LegendOpts(pos_left="left"), )) return c def process(): result = [] process_list = [] pid = psutil.pids() for k, i in enumerate(pid): try: proc = psutil.Process(i) ctime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(proc.create_time())) process_list.append((str(i), proc.name(), proc.cpu_percent(), proc.memory_percent(), ctime)) except psutil.AccessDenied: pass except psutil.NoSuchProcess: pass except SystemError: pass process_list.sort(key=process_sort, reverse=True) for i in process_list: result.append({'PID': i[0], 'name': i[1], 'cpu': i[2], 'mem': "%.2f%%"%i[3], 'ctime': i[4]}) return jsonify({'list': result}) def process_sort(elem): return elem[3] def disk(): disk_usage = psutil.disk_usage('/') disk_used = 0 # 磁盘已使用大小 = 每个分区的总和 partitions = psutil.disk_partitions() for partition in partitions: partition_disk_usage = psutil.disk_usage(partition[1]) disk_used = partition_disk_usage.used + disk_used now = time.strftime('%H:%M:%S', time.localtime(time.time())) count = psutil.disk_io_counters() read_bytes = count.read_bytes write_bytes = count.write_bytes # 第一次请求 if disk_dict['len'] == -1: disk_dict['pre_write_bytes'] = write_bytes disk_dict['pre_read_bytes'] = read_bytes disk_dict['len'] = 0 return disk_usage.total, disk_used, disk_usage.free # 当前速率=现在写入/读取的总字节-前一次请求写入/读取的总字节 disk_dict['write_bytes'].append((write_bytes - disk_dict['pre_write_bytes'])/1024) disk_dict['read_bytes'].append((read_bytes - disk_dict['pre_read_bytes'])/ 1024) disk_dict['disk_time'].append(now) disk_dict['len'] = disk_dict['len'] + 1 # 把现在写入/读取的总字节放入前一个请求的变量中 disk_dict['pre_write_bytes'] = write_bytes disk_dict['pre_read_bytes'] = read_bytes # 保持在图表中 50 个数据 if disk_dict['len'] == 51: disk_dict['write_bytes'].pop(0) disk_dict['read_bytes'].pop(0) disk_dict['disk_time'].pop(0) disk_dict['len'] = disk_dict['len'] - 1 return disk_usage.total, disk_used, disk_usage.free def disk_line() -> Line: total, used, free = disk() c = ( Line(init_opts=opts.InitOpts(width="1680px", height="800px")) .add_xaxis(xaxis_data=disk_dict['disk_time']) .add_yaxis( series_name="写入数据", y_axis=disk_dict['write_bytes'], areastyle_opts=opts.AreaStyleOpts(opacity=0.5), linestyle_opts=opts.LineStyleOpts(), label_opts=opts.LabelOpts(is_show=False), ) .add_yaxis( series_name="读取数据", y_axis=disk_dict['read_bytes'], yaxis_index=1, areastyle_opts=opts.AreaStyleOpts(opacity=0.5), linestyle_opts=opts.LineStyleOpts(), label_opts=opts.LabelOpts(is_show=False), ) .extend_axis( yaxis=opts.AxisOpts( name_location="start", type_="value", is_inverse=True, axistick_opts=opts.AxisTickOpts(is_show=True), splitline_opts=opts.SplitLineOpts(is_show=True), name='KB/2S' ) ) .set_global_opts( title_opts=opts.TitleOpts( title="磁盘IO", pos_left="center", pos_top="top", ), tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross"), legend_opts=opts.LegendOpts(pos_left="left"), xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False), yaxis_opts=opts.AxisOpts(type_="value", name='KB/2S'), ) .set_series_opts( axisline_opts=opts.AxisLineOpts(), ) ) return total, used, free, c @app.route("/") def index(): return render_template("index.html") @app.route("/cpu") def get_cpu_chart(): c = cpu_line() return c.dump_options_with_quotes() @app.route("/memory") def get_memory_chart(): mtotal, mused, mfree, stotal, sused, sfree, c = memory_liquid() return jsonify({'mtotal': mtotal, 'mused': mused, 'mfree': mfree, 'stotal': stotal, 'sused': sused, 'sfree': sfree, 'liquid': c.dump_options_with_quotes()}) @app.route("/netio") def get_net_io_chart(): c = net_io_line() return c.dump_options_with_quotes() @app.route("/process") def get_process_tab(): c = process() return c @app.route("/delprocess") def del_process(): pid = request.args.get("pid") os.kill(int(pid), signal.SIGKILL) return jsonify({'status': 'OK'}) @app.route("/disk") def get_disk_chart(): total, used, free, c = disk_line() return jsonify({'total': total, 'used': used, 'free': free, 'line': c.dump_options_with_quotes()}) if __name__ == "__main__": app.run()
templates/index.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>基于psutil的系统监控工具</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container" style="padding-top: 100px"> <div class="row user-list"> <div class="col-sm-12 user" style=""> <div id="alert" class="alert alert-success" role="alert" style="margin: auto;left: 0;right: 0;display: none;position: fixed;width: 50%;text-align: center;">删除成功</div> </div> </div> <div class="row user-list"> <div class="col-sm-12 user"> <div> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"><a href="#cpuTab" aria-controls="cpuTab" role="tab" data-toggle="tab">CPU</a></li> <li role="presentation"><a href="#memoryTab" aria-controls="memoryTab" role="tab" data-toggle="tab">内存</a></li> <li role="presentation"><a href="#diskTab" aria-controls="diskTab" role="tab" data-toggle="tab">磁盘</a></li> <li role="presentation"><a href="#netioTab" aria-controls="netioTab" role="tab" data-toggle="tab">网卡</a></li> <li role="presentation"><a href="#processTab" aria-controls="processTab" role="tab" data-toggle="tab">进程</a></li> </ul> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="cpuTab"> <div id="cpu" style="width:800px; height:300px;padding-top: 40px;margin-left: auto;margin-right: auto"></div> </div> <div role="tabpanel" class="tab-pane" id="memoryTab"> <div class="row user-list"> <div class="col-sm-5 user" style=""> <ul class="list-group" style="padding-left:200px;padding-top:50px"> <li class="list-group-item list-group-item-success">内存大小:<span class="badge" id="mtotal"></span></li> <li class="list-group-item list-group-item-info">内存已使用大小:<span class="badge" id="mused"></span></li> <li class="list-group-item list-group-item-warning">内存剩余大小:<span class="badge" id="mfree"></span></li> <li class="list-group-item list-group-item-success">交换区大小:<span class="badge" id="stotal"></span></li> <li class="list-group-item list-group-item-info">交换区已使用大小:<span class="badge" id="sused"></span></li> <li class="list-group-item list-group-item-warning">交换区剩余大小:<span class="badge" id="sfree"></span></li> </ul> </div> <div class="col-sm-7 user" style=""> <div id="memory" style="width:800px; height:300px;padding-top: 40px;margin-left: -100px;margin-right: auto"></div> </div> </div> </div> <div role="tabpanel" class="tab-pane" id="netioTab"> <div class="row user-list"> <div class="col-sm-12 user" style=""> <div id="netio" style="width:800px; height:300px;padding-top: 40px;margin-left: auto;margin-right: auto"></div> </div> </div> </div> <div role="tabpanel" class="tab-pane" id="processTab"> <table class="table table-hover" style="height:100px;padding-top: 40px;margin-left: auto;margin-right: auto"> <thead> <tr> <th>PID</th> <th>程序</th> <th>占用内存</th> <th>创建时间</th> <th>强行停止</th> </tr> </thead> <tbody id="tbody"> </tbody> </table> </div> <div role="tabpanel" class="tab-pane container" id="diskTab"> <div class="row user-list"> <div class="col-sm-3 user" style=""> <ul class="list-group" style="padding-top:100px"> <li class="list-group-item list-group-item-success">磁盘容量:<span class="badge" id="total"></span></li> <li class="list-group-item list-group-item-info">已使用容量:<span class="badge" id="used"></span></li> <li class="list-group-item list-group-item-warning">空闲容量:<span class="badge" id="free"></span></li> </ul> </div> <div class="col-sm-9 user" style=""> <div id="disk" style="width:800px; height:300px;padding-top: 40px;margin-left: auto;margin-right: auto"></div> </div> </div> </div> </div> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script> <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script> <script> var chart = echarts.init(document.getElementById('cpu'), 'white', {renderer: 'canvas'}); var memory = echarts.init(document.getElementById('memory'), 'white', {renderer: 'canvas'}); var netio = echarts.init(document.getElementById('netio'), 'white', {renderer: 'canvas'}); var disk = echarts.init(document.getElementById('disk'), 'white', {renderer: 'canvas'}); $( function () { fetchData(chart); setInterval(fetchData, 2000); fetchMemoryData(memory); setInterval(fetchMemoryData, 2000); fetchNetioData(netio); setInterval(fetchNetioData, 2000); setInterval(fetchProcessData, 2000); fetchDiskData(disk); setInterval(fetchDiskData, 2000); }, $('#myTabs a').click(function (e) { e.preventDefault() $(this).tab('show') }) ); function fetchData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/cpu", dataType: 'json', success: function (result) { chart.setOption(result); } }); } function fetchMemoryData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/memory", dataType: 'json', success: function (result) { memory.setOption(JSON.parse(result.liquid)); $('#mtotal').html((result.mtotal/1024/1024/1024).toFixed(2) + 'G') $('#mused').html((result.mused/1024/1024/1024).toFixed(2) + 'G') $('#mfree').html((result.mfree/1024/1024/1024).toFixed(2) + 'G') $('#stotal').html((result.stotal/1024/1024/1024).toFixed(2) + 'G') $('#sused').html((result.sused/1024/1024/1024).toFixed(2) + 'G') $('#sfree').html((result.sfree/1024/1024/1024).toFixed(2) + 'G') } }); } function fetchNetioData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/netio", dataType: 'json', success: function (result) { netio.setOption(result); } }); } function fetchProcessData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/process", dataType: 'json', success: function (result) { html = '' list = result.list for (var l in list) { html = html +'<tr><td>' + list[l].PID + '</td><td>' + list[l].name + '</td><td>' + list[l].mem + '</td><td>' + list[l].ctime + '</td><td><button type="button" class="btn btn-default btn-xs" onclick="delProcess('+list[l].PID+')"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button></td></tr>' } $('#tbody').html(html) } }) } function delProcess(pid) { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/delprocess?pid="+pid, dataType: 'json', success: function (result) { $("#alert").fadeIn(1000); $("#alert").fadeOut(3000); } }) } function fetchDiskData() { $.ajax({ type: "GET", url: "http://127.0.0.1:5000/disk", dataType: 'json', success: function (result) { disk.setOption(JSON.parse(result.line)); $('#total').html((result.total/1000000000).toFixed(2) + 'G') $('#used').html((result.used/1000000000).toFixed(2) + 'G') $('#free').html((result.free/1000000000).toFixed(2) + 'G') } }); } </script> </body> </html>
效果
参考文档 : https://blog.csdn.net/ityouknow/article/details/105985451