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


Posted in Python onNovember 07, 2015

这里以监控内存使用率为例,写的一个简单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接口
具体框架结构图如下:

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

目录结构如下:

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 就可以看到我们的监控数据了:效果图如下

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

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

Python 相关文章推荐
Python fileinput模块使用介绍
Nov 30 Python
浅谈scrapy 的基本命令介绍
Jun 13 Python
Python 3.6 性能测试框架Locust安装及使用方法(详解)
Oct 11 Python
新手常见6种的python报错及解决方法
Mar 09 Python
Python访问MongoDB,并且转换成Dataframe的方法
Oct 15 Python
python3+selenium实现qq邮箱登陆并发送邮件功能
Jan 23 Python
基于wxPython的GUI实现输入对话框(2)
Feb 27 Python
Python3爬楼梯算法示例
Mar 04 Python
python下载库的步骤方法
Oct 12 Python
PyQt5+Pycharm安装和配置图文教程详解
Mar 24 Python
Python建造者模式案例运行原理解析
Jun 29 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
Sep 23 Python
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
Nov 07 #Python
举例讲解Linux系统下Python调用系统Shell的方法
Nov 07 #Python
使用Python导出Excel图表以及导出为图片的方法
Nov 07 #Python
Windows下为Python安装Matplotlib模块
Nov 06 #Python
python 的列表遍历删除实现代码
Apr 12 #Python
举例讲解Python中的死锁、可重入锁和互斥锁
Nov 05 #Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
Nov 05 #Python
You might like
laravel 5异常错误:FatalErrorException in Handler.php line 38的解决
2017/10/12 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
JS获得URL超链接的参数值实例代码
2013/06/21 Javascript
JavaScript判断密码强度(自写代码)
2013/09/06 Javascript
jQuery悬停文字提示框插件jquery.tooltipster.js用法示例【附demo源码下载】
2016/07/19 Javascript
Bootstrap树形菜单插件TreeView.js使用方法详解
2016/11/01 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
JS实现根据密码长度显示安全条功能
2017/03/08 Javascript
nodejs+express实现文件上传下载管理网站
2017/03/15 NodeJs
微信小程序实现根据字母选择城市功能
2017/08/16 Javascript
在vue项目中使用Nprogress.js进度条的方法
2018/01/31 Javascript
JS温故而知新之变量提升和时间死区
2019/01/27 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
2019/09/17 Javascript
javascript实现动态时钟的启动和停止
2020/07/29 Javascript
[06:49]2018DOTA2国际邀请赛寻真——VirtusPro傲视群雄
2018/08/12 DOTA
python3.3使用tkinter开发猜数字游戏示例
2014/03/14 Python
python Django模板的使用方法
2016/01/14 Python
python中的字符串内部换行方法
2018/07/19 Python
Python使用pandas对数据进行差分运算的方法
2018/12/22 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
Python异常继承关系和自定义异常实现代码实例
2020/02/20 Python
Python求区间正整数内所有素数之和的方法实例
2020/10/13 Python
世界上第一个水枕头:Mediflow
2018/12/06 全球购物
法国最大的在线眼镜店:EasyLunettes
2019/08/26 全球购物
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
上级检查欢迎词
2014/01/18 职场文书
应届护士求职信范文
2014/01/26 职场文书
自动化毕业生专业自荐书范文
2014/02/04 职场文书
房产代理公证处委托书
2014/04/04 职场文书
师德师风自查材料
2014/10/14 职场文书
个人专业技术总结
2015/03/05 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
追讨欠款律师函
2015/05/27 职场文书
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python