用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 相关文章推荐
python3使用tkinter实现ui界面简单实例
Jan 10 Python
Python内置的字符串处理函数详细整理(覆盖日常所用)
Aug 19 Python
JSONLINT:python的json数据验证库实例解析
Nov 28 Python
Python lambda函数基本用法实例分析
Mar 16 Python
详谈Numpy中数组重塑、合并与拆分方法
Apr 17 Python
pycharm: 恢复(reset) 误删文件的方法
Oct 22 Python
pandas去重复行并分类汇总的实现方法
Jan 29 Python
Python模块、包(Package)概念与用法分析
May 31 Python
将python包发布到PyPI和制作whl文件方式
Dec 25 Python
关于tf.reverse_sequence()简述
Jan 20 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
Apr 20 Python
Python3自定义json逐层解析器代码
May 11 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
php 将bmp图片转为jpg等其他任意格式的图片
2009/06/21 PHP
php页面跳转代码 输入网址跳转到你定义的页面
2013/03/28 PHP
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
2014/08/18 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
如何解决PHP无法实现多线程的问题
2015/09/25 PHP
PHP安装threads多线程扩展基础教程
2015/11/17 PHP
浅谈PHP链表数据结构(单链表)
2016/06/08 PHP
thinkphp分页实现效果
2016/10/13 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
StringTemplate遇见jQuery冲突的解决方法
2011/09/22 Javascript
JavaScript的漂亮的代码片段
2013/06/05 Javascript
jQuery中animate的几种用法与注意事项
2016/12/12 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
vue中eventbus被多次触发以及踩过的坑
2017/12/02 Javascript
zTree树形菜单交互选项卡效果的实现方法
2017/12/25 Javascript
vue的keep-alive用法技巧
2019/08/15 Javascript
VUE+node(express)实现前后端分离
2019/10/13 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
JS闭包原理及其使用场景解析
2020/12/03 Javascript
[00:27]DOTA2荣耀之路2:Patience from zhou!
2018/05/24 DOTA
nohup后台启动Python脚本,log不刷新的解决方法
2019/01/14 Python
pytorch 获取层权重,对特定层注入hook, 提取中间层输出的方法
2019/08/17 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
2020/03/28 Python
Pandas对DataFrame单列/多列进行运算(map, apply, transform, agg)
2020/06/14 Python
Django用户认证系统如何实现自定义
2020/11/12 Python
前端canvas动画如何转成mp4视频的方法
2019/06/17 HTML / CSS
Lookfantastic德国官网:英国知名美妆购物网站
2017/06/11 全球购物
学校安全工作制度
2014/01/19 职场文书
工作表现自我评价
2014/02/08 职场文书
《画风》教学反思
2014/04/16 职场文书
年终考核实施方案
2014/05/26 职场文书
危货运输企业安全生产责任书
2014/07/28 职场文书
导游词之太湖
2019/10/08 职场文书
python中Pyqt5使用Qlabel标签播放视频
2022/04/22 Python
css中:last-child不生效的解决方法
2022/08/05 HTML / CSS