用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中的私有属性
Aug 21 Python
Python函数中定义参数的四种方式
Nov 30 Python
python基础教程之五种数据类型详解
Jan 12 Python
Python使用numpy实现BP神经网络
Mar 10 Python
通过Python 接口使用OpenCV的方法
Apr 02 Python
PyQt5 pyqt多线程操作入门
May 05 Python
利用Python实现原创工具的Logo与Help
Dec 03 Python
Python中Numpy ndarray的使用详解
May 24 Python
python中的反斜杠问题深入讲解
Aug 12 Python
OpenCV+face++实现实时人脸识别解锁功能
Aug 28 Python
从numpy数组中取出满足条件的元素示例
Nov 26 Python
浅谈Python3实现两个矩形的交并比(IoU)
Jan 18 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
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
php出现内存位置访问无效错误问题解决方法
2014/08/16 PHP
smarty内置函数foreach用法实例
2015/01/22 PHP
PHP Reflection API详解
2015/05/12 PHP
WordPress中对访客评论功能的一些优化方法
2015/11/24 PHP
PHP压缩图片功能的介绍
2019/03/21 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
2019/10/11 PHP
JavaScript实现快速排序(自已编写)
2012/12/19 Javascript
JavaScript电子时钟倒计时第二款
2016/01/10 Javascript
高性能JavaScript循环语句和条件语句
2016/01/20 Javascript
利用JS实现数字增长
2016/07/28 Javascript
过期软件破解办法实例详解
2017/01/04 Javascript
详解wow.js中各种特效对应的类名
2017/09/13 Javascript
vue和react等项目中更简单的实现展开收起更多等效果示例
2018/02/22 Javascript
vue配置接口域名方法总结
2019/05/12 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
Python中atexit模块的基本使用示例
2015/07/08 Python
Python+微信接口实现运维报警
2016/08/27 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
2018/02/21 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
Python 异常处理Ⅳ过程图解
2019/10/18 Python
Python高级编程之继承问题详解(super与mro)
2019/11/19 Python
python logging通过json文件配置的步骤
2020/04/27 Python
基于Python+QT的gui程序开发实现
2020/07/03 Python
广州品高软件.net笔面试题目
2012/04/18 面试题
秋季运动会表扬稿
2014/01/16 职场文书
高中运动会广播稿
2014/01/21 职场文书
文明青少年标兵事迹材料
2014/01/28 职场文书
大学班级学风建设方案
2014/05/01 职场文书
小学感恩节活动总结
2015/03/24 职场文书
2015年市场部工作总结
2015/04/30 职场文书
2015国庆66周年宣传语
2015/07/14 职场文书
《给予树》教学反思
2016/03/03 职场文书
vue使用v-model进行跨组件绑定的基本实现方法
2021/04/28 Vue.js
MySQL数据库优化之通过索引解决SQL性能问题
2022/04/10 MySQL
Spring Cloud OAuth2实现自定义token返回格式
2022/06/25 Java/Android