用Python的Flask框架结合MySQL写一个内存监控程序

1056次阅读  |  发布于5年以前

这里以监控内存使用率为例,写的一个简单demo性程序,具体操作根据51reboot提供的教程写如下。

一、建库建表

创建falcon数据库:


    mysql> create database falcon character set utf8;
    Query OK, 1 row affected (0.00 sec)

创建内存监控使用的表stat,表结构如下:


    CREATE TABLE `stat` (
     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `host` varchar(256) DEFAULT NULL,
     `mem_free` int(11) DEFAULT NULL,
     `mem_usage` int(11) DEFAULT NULL,
     `mem_total` int(11) DEFAULT NULL,
     `load_avg` varchar(128) DEFAULT NULL,
     `time` bigint(11) DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `host` (`host`(255))
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

二、flask web端设置

首先我们设计一个web服务,实现如下功能:

完成监控页面展示
接受POST提交上来的数据
提供json数据GET接口
具体框架结构图如下:

2015117174700956.png \(907×380\)

目录结构如下:


    web
    ├── flask_web.py
    └── templates
     └── mon.html

flask_web代码如下:


    import MySQLdb as mysql
    import json
    from flask import Flask, request, render_template
    app = Flask(__name__)
    db = mysql.connect(user="361way", passwd="123456", \
      db="falcon", charset="utf8")
    db.autocommit(True)
    c = db.cursor()
    @app.route("/", methods=["GET", "POST"])
    def hello():
     sql = ""
     if request.method == "POST":
      data = request.json
      try:
       sql = "INSERT INTO `stat` (`host`,`mem_free`,`mem_usage`,`mem_total`,`load_avg`,`time`) VALUES('%s', '%d', '%d', '%d', '%s', '%d')" % (data['Host'], data['MemFree'], data['MemUsage'], data['MemTotal'], data['LoadAvg'], int(data['Time']))
       ret = c.execute(sql)
      except mysql.IntegrityError:
       pass
      return "OK"
     else:
      return render_template("mon.html")
    @app.route("/data", methods=["GET"])
    def getdata():
     c.execute("SELECT `time`,`mem_usage` FROM `stat`")
     ones = [[i[0]*1000, i[1]] for i in c.fetchall()]
     return "%s(%s);" % (request.args.get('callback'), json.dumps(ones))
    if __name__ == "__main__":
     app.run(host="0.0.0.0", port=8888, debug=True)

这里使用的汇图JS为highcharts、highstock ,具体模板页面内容如下:


    [root@91it templates]# cat mon.html

    <title>memory monitor</title>
    <!DOCTYPE HTML>
    <html>
     <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Highstock Example</title>
      <!-- <script type="text/javascript" src="{{ url_for('static', filename='jquery.min.js') }}"></script> -->
      <script type="text/javascript" src="http://ajax.useso.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
      <style type="text/css">
    ${demo.css}
      </style>
      <script type="text/javascript">
    $(function () {
     $.getJSON('/data?callback=?', function (data) {
      // Create the chart
      $('#container').highcharts('StockChart', {
       rangeSelector: {
        inputEnabled: $('#container').width() > 480,
        selected: 1
       },
       title: {
        text: 'memory monitor'
       },
       series: [{
        name: 'memory monitor',
        data: data,
        type: 'spline',
        tooltip: {
         valueDecimals: 2
        }
       }]
      });
     });
    });
      </script>
     </head>
     <body>
    <!-- <script src="{{ url_for('static', filename='highstock.js') }}"></script> -->
    <script src="http://cdnjs.cloudflare.com/ajax/libs/highstock/2.0.4/highstock.js"></script>
    <!-- <script src="{{ url_for('static', filename='exporting.js') }}"></script> -->
    <script src="http://code.highcharts.com/modules/exporting.js"></script>
    <div id="container" style="height: 400px"></div>
     </body>
    </html>

注:这里的JS代码都直接使用互联网上的代码,如果主机无法连接互联网的,可以将上面的三段代取取下来,在templates 的同级目录创建static 目录,将下载下来的三个文件放到该目录,删除模板中三处引用javascript处的代码,使用当前注释的三段。

三、agent被监控端设置

web展示页面完成了,运行起来:python flask_web.py 监听在8888端口上。我们需要做一个agent来采集数据,并通过post方法请求flask_web页面,将数据上传写入数据库。这里以监控内存为例,具体监控代码如下:


    #!/usr/bin/env python
    #coding=utf-8
    import inspect
    import time
    import urllib, urllib2
    import json
    import socket
    class mon:
     def __init__(self):
      self.data = {}
     def getTime(self):
      return str(int(time.time()) + 8 * 3600)
     def getHost(self):
      return socket.gethostname()
     def getLoadAvg(self):
      with open('/proc/loadavg') as load_open:
       a = load_open.read().split()[:3]
       return ','.join(a)
     def getMemTotal(self):
      with open('/proc/meminfo') as mem_open:
       a = int(mem_open.readline().split()[1])
       return a / 1024
     def getMemUsage(self, noBufferCache=True):
      if noBufferCache:
       with open('/proc/meminfo') as mem_open:
        T = int(mem_open.readline().split()[1])
        F = int(mem_open.readline().split()[1])
        B = int(mem_open.readline().split()[1])
        C = int(mem_open.readline().split()[1])
        return (T-F-B-C)/1024
      else:
       with open('/proc/meminfo') as mem_open:
        a = int(mem_open.readline().split()[1]) - int(mem_open.readline().split()[1])
        return a / 1024
     def getMemFree(self, noBufferCache=True):
      if noBufferCache:
       with open('/proc/meminfo') as mem_open:
        T = int(mem_open.readline().split()[1])
        F = int(mem_open.readline().split()[1])
        B = int(mem_open.readline().split()[1])
        C = int(mem_open.readline().split()[1])
        return (F+B+C)/1024
      else:
       with open('/proc/meminfo') as mem_open:
        mem_open.readline()
        a = int(mem_open.readline().split()[1])
        return a / 1024
     def runAllGet(self):
      #自动获取mon类里的所有getXXX方法,用XXX作为key,getXXX()的返回值作为value,构造字典
      for fun in inspect.getmembers(self, predicate=inspect.ismethod):
       if fun[0][:3] == 'get':
        self.data[fun[0][3:]] = fun[1]()
      return self.data
    if __name__ == "__main__":
     while True:
      m = mon()
      data = m.runAllGet()
      print data
      req = urllib2.Request("http://test.361way.com:8888", json.dumps(data), {'Content-Type': 'application/json'})
      f = urllib2.urlopen(req)
      response = f.read()
      print response
      f.close()
      time.sleep(60)

nohup python moniItems.py >/dev/null 2>&1 & 在被监控主机上运行,如果出于实验目的,想尽快的看到展示效果,可以将time.sleep(60) 改为time.sleep(2) ,这样每2秒就会取一次数据写入数据库。

访问 http://test.361way.com:8888 就可以看到我们的监控数据了:效果图如下

2015117175842218.png \(793×435\)

highcharts支持将按时间拖动,也支持按指定时间段查看。并且查看到的图片可以直接保存为png、jpg或pdf、csv等格式查看。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8