用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 list 合并连接字符串的方法
Mar 09 Python
python实现的登陆Discuz!论坛通用代码分享
Jul 11 Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 Python
python 统计列表中不同元素的数量方法
Jun 29 Python
python 将对象设置为可迭代的两种实现方法
Jan 21 Python
Python数据库小程序源代码
Sep 15 Python
window7下的python2.7版本和python3.5版本的opencv-python安装过程
Oct 24 Python
python实现大量图片重命名
Mar 23 Python
Python拼接字符串的7种方式详解
Mar 19 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
Jan 07 Python
用Python制作音乐海报
Jan 26 Python
pytorch 把图片数据转化成tensor的操作
Mar 04 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
虫族 ZERG 概述
2020/03/14 星际争霸
php生成图片验证码-附五种验证码
2015/08/19 PHP
浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)
2015/09/22 PHP
PHP 记录访客的浏览信息方法
2018/01/29 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
JavaScript 事件对象的实现
2009/07/13 Javascript
JavaScript String.replace函数参数实例说明
2013/06/06 Javascript
IE、FF、Chrome浏览器中的JS差异介绍
2013/08/13 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
jquery删除指定子元素代码实例
2015/01/13 Javascript
浅谈JavaScript中Date(日期对象),Math对象
2015/02/05 Javascript
浅析Javascript匿名函数与自执行函数
2016/02/06 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
AngularJS出现$http异步后台无法获取请求参数问题的解决方法
2016/11/03 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
Vue.js简易安装和快速入门(第二课)
2017/10/17 Javascript
JS中数据结构之栈
2019/01/01 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
2019/09/27 Javascript
python通过邮件服务器端口发送邮件的方法
2015/04/30 Python
在Linux中通过Python脚本访问mdb数据库的方法
2015/05/06 Python
详解Python函数作用域的LEGB顺序
2016/05/14 Python
python书籍信息爬虫实例
2018/03/19 Python
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
利用Python的sympy包求解一元三次方程示例
2019/11/22 Python
解决os.path.isdir() 判断文件夹却返回false的问题
2019/11/29 Python
Pycharm打开已有项目配置python环境的方法
2020/07/03 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
编写一子程序,将一链表倒序,即使链表表尾变表头,表头变表尾
2016/02/10 面试题
周鸿祎:教你写创业计划书
2013/12/30 职场文书
党员思想汇报范文
2013/12/30 职场文书
老人院义工活动感想
2015/08/07 职场文书
2016年先进教师个人事迹材料
2016/02/26 职场文书
Python内置的数据类型及使用方法
2022/04/13 Python