“Psutil + Flask开发Linux /Windows系统监控”的版本间的差异

来自CloudWiki
跳转至: 导航搜索
第25行: 第25行:
 
==获取系统信息==
 
==获取系统信息==
 
===初始化===
 
===初始化===
 +
app.py:
 +
 
  <nowiki>
 
  <nowiki>
  
第94行: 第96行:
 
         cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])
 
         cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])
  
     return render_template('list.html', title="CPU使用情况",my_dict=cpu_percent_dict)</nowiki>
+
     return render_template('list.html', title="CPU使用情况",my_dict=cpu_percent_dict)
 +
 
 +
if __name__ == '__main__':#程序入口
 +
    #app.run()#让应用运行在本地服务器上。
 +
    app.run(debug=True,host='0.0.0.0') #允许任意网址访问本站
 +
</nowiki>
  
 
[[文件:python2022052702.png|600px]]
 
[[文件:python2022052702.png|600px]]
第115行: 第122行:
 
     return render_template('list.html', title="内存使用情况",my_dict=sys)
 
     return render_template('list.html', title="内存使用情况",my_dict=sys)
  
if __name__ == '__main__':#程序入口
+
 
    #app.run()#让应用运行在本地服务器上。
 
    app.run(debug=True,host='0.0.0.0') #允许任意网址访问本站
 
  
 
</nowiki>
 
</nowiki>
第142行: 第147行:
 
===app.py===
 
===app.py===
 
  <nowiki>
 
  <nowiki>
 +
import psutil
 
import os, signal
 
import os, signal
 
from random import randrange
 
from random import randrange
  
 
from flask import Flask, render_template, jsonify, request
 
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 time
import psutil
 
  
 
app = Flask(__name__, static_folder="templates")
 
app = Flask(__name__, static_folder="templates")
第159行: 第160行:
 
disk_dict = {'disk_time':[], 'write_bytes': [], 'read_bytes': [], 'pre_write_bytes': 0, 'pre_read_bytes': 0, 'len': -1}
 
disk_dict = {'disk_time':[], 'write_bytes': [], 'read_bytes': [], 'pre_write_bytes': 0, 'pre_read_bytes': 0, 'len': -1}
  
 +
cpu_percent_dict = {}
 +
 +
@app.route("/cpu")
 
def cpu():
 
def cpu():
     now = time.strftime('%H:%M:%S', time.localtime(time.time()))
+
     for i in range(1,6):
    cpu_percent = psutil.cpu_percent()
+
        # 当前时间
    cpu_percent_dict[now] = cpu_percent
+
        now = time.strftime('%H:%M:%S', time.localtime(time.time()))
 +
        #  CPU 负载
 +
        cpu_percent = psutil.cpu_percent()
 +
        cpu_percent_dict[now] = cpu_percent
 +
        time.sleep(0.3)
 +
 
 
     # 保持在图表中 10 个数据
 
     # 保持在图表中 10 个数据
 
     if len(cpu_percent_dict.keys()) == 11:
 
     if len(cpu_percent_dict.keys()) == 11:
 
         cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])
 
         cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])
  
 +
    return render_template('list.html', title="CPU使用情况",my_dict=cpu_percent_dict)
  
def cpu_line() -> Line:
+
@app.route("/memory")
    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():
 
def memory():
 
     memory = psutil.virtual_memory()
 
     memory = psutil.virtual_memory()
 
     swap = psutil.swap_memory()
 
     swap = psutil.swap_memory()
     return memory.total, memory.used, \
+
     sys={}
          memory.free, swap.total, swap.used, swap.free, memory.percent
+
    sys['mem_total']= memory.total
 +
    sys['mem_used']= memory.used
 +
    sys['mem_free']= memory.free
 +
    sys['swap_total']=swap.total
 +
    sys['swap_used']=swap.used
 +
    sys['swap_free']=swap.free
 +
    sys['memory_percent']= memory.percent
  
 +
    return render_template('list.html', title="内存使用情况",my_dict=sys)
  
def memory_liquid() -> Gauge:
+
if __name__ == '__main__':#程序入口
    mtotal, mused, mfree, stotal, sused, sfree, mpercent = memory()
+
     #app.run()#让应用运行在本地服务器上。
    c = (
+
     app.run(debug=True,host='0.0.0.0') #允许任意网址访问本站
        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()
 
  
 
</nowiki>
 
</nowiki>
  
===templates/index.html===
+
===templates/list.html===
 +
templates/list.html:
  
 
  <nowiki>
 
  <nowiki>
第432行: 第219行:
 
     <table id="customers" class="table table-striped">
 
     <table id="customers" class="table table-striped">
 
     <tr>
 
     <tr>
       <th>ID</th>
+
       <th>监测项</th>
       <th>name</th>
+
       <th>数值</th>
 
     </tr>
 
     </tr>
  
第443行: 第230行:
 
     {% endfor %}
 
     {% endfor %}
 
     </table>
 
     </table>
</body>
+
</body></nowiki>
</html></nowiki>
 
  
 
==效果==
 
==效果==
[[文件:python22031901.png|600px]]
+
[[文件:python2022052702.png|600px]]
 +
 
 +
[[文件:python2022052701.png|600px]]
  
 
参考文档 : https://blog.csdn.net/ityouknow/article/details/105985451
 
参考文档 : https://blog.csdn.net/ityouknow/article/details/105985451

2022年5月28日 (六) 04:14的版本

简介

psutil 是一个跨平台库(http://pythonhosted.org/psutil)能够获取到系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。主要用来做系统监控,性能分析,进程管理。支持 Linux、Mac OS、Windows 系统。

本文以 psutil 模块获取系统信息开发一个监控 Windows 系统的平台。

技术选择

  • 监控的系统是 Windows 系统
  • 监控系统模块选择 psutil 模块
  • Web 框架选择的是 Flask 框架


技术准备

安装 psutil

pip3 install psutil

安装 Flask、pyecharts、Bootstrap

Flask 的教程是在公众号文章:Web 开发 Flask 介绍

获取系统信息

初始化

app.py:


import psutil
import os, signal
from random import randrange

from flask import Flask, render_template, jsonify, request
import time

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}

cpu_percent_dict = {}

网页模板

templates/list.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>
    <h1>{{title}}</h1>
     <table id="customers" class="table table-striped">
    <tr>
      <th>监测项</th>
      <th>数值</th>
    </tr>

    {% for key, value in my_dict.items() %}
    <tr>
      <td>{{ key }}</td>
      <td>{{ value}}</td>
    </tr>
    {% endfor %}
     </table>
</body>
</html>

CPU信息

通过 psutil 获取 CPU 信息

@app.route("/cpu")
def cpu():
    for i in range(1,6):
        # 当前时间
        now = time.strftime('%H:%M:%S', time.localtime(time.time()))
        #  CPU 负载
        cpu_percent = psutil.cpu_percent()
        cpu_percent_dict[now] = cpu_percent
        time.sleep(0.3)

    # 保持在图表中 10 个数据
    if len(cpu_percent_dict.keys()) == 11:
        cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])

    return render_template('list.html', title="CPU使用情况",my_dict=cpu_percent_dict)

if __name__ == '__main__':#程序入口
    #app.run()#让应用运行在本地服务器上。
    app.run(debug=True,host='0.0.0.0') #允许任意网址访问本站

Python2022052702.png

内存

@app.route("/memory")
def memory():
    memory = psutil.virtual_memory()
    swap = psutil.swap_memory()
    sys={}
    sys['mem_total']= memory.total
    sys['mem_used']= memory.used
    sys['mem_free']= memory.free
    sys['swap_total']=swap.total
    sys['swap_used']=swap.used
    sys['swap_free']=swap.free
    sys['memory_percent']= memory.percent

    return render_template('list.html', title="内存使用情况",my_dict=sys)




效果:

Python2022052701.png


https://blog.csdn.net/ityouknow/article/details/105985451

磁盘

通过 psutil 获取磁盘大小、分区、使用率和磁盘IO


网卡

通过 psutil 获取网络接口和网络连接的信息


代码

app.py

import psutil
import os, signal
from random import randrange

from flask import Flask, render_template, jsonify, request
import time

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}

cpu_percent_dict = {}

@app.route("/cpu")
def cpu():
    for i in range(1,6):
        # 当前时间
        now = time.strftime('%H:%M:%S', time.localtime(time.time()))
        #  CPU 负载
        cpu_percent = psutil.cpu_percent()
        cpu_percent_dict[now] = cpu_percent
        time.sleep(0.3)

    # 保持在图表中 10 个数据
    if len(cpu_percent_dict.keys()) == 11:
        cpu_percent_dict.pop(list(cpu_percent_dict.keys())[0])

    return render_template('list.html', title="CPU使用情况",my_dict=cpu_percent_dict)

@app.route("/memory")
def memory():
    memory = psutil.virtual_memory()
    swap = psutil.swap_memory()
    sys={}
    sys['mem_total']= memory.total
    sys['mem_used']= memory.used
    sys['mem_free']= memory.free
    sys['swap_total']=swap.total
    sys['swap_used']=swap.used
    sys['swap_free']=swap.free
    sys['memory_percent']= memory.percent

    return render_template('list.html', title="内存使用情况",my_dict=sys)

if __name__ == '__main__':#程序入口
    #app.run()#让应用运行在本地服务器上。
    app.run(debug=True,host='0.0.0.0') #允许任意网址访问本站


templates/list.html

templates/list.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>
    <h1>{{title}}</h1>
     <table id="customers" class="table table-striped">
    <tr>
      <th>监测项</th>
      <th>数值</th>
    </tr>

    {% for key, value in my_dict.items() %}
    <tr>
      <td>{{ key }}</td>
      <td>{{ value}}</td>
    </tr>
    {% endfor %}
     </table>
</body>

效果

Python2022052702.png

Python2022052701.png

参考文档 : https://blog.csdn.net/ityouknow/article/details/105985451