用Python的Flask框架結(jié)合MySQL寫一個內(nèi)存監(jiān)控程序
這里以監(jiān)控內(nèi)存使用率為例,寫的一個簡單demo性程序,具體操作根據(jù)51reboot提供的教程寫如下。
一、建庫建表
創(chuàng)建falcon數(shù)據(jù)庫:
mysql> create database falcon character set utf8; Query OK, 1 row affected (0.00 sec)
創(chuàng)建內(nèi)存監(jiān)控使用的表stat,表結(jié)構(gòu)如下:
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端設(shè)置
首先我們設(shè)計(jì)一個web服務(wù),實(shí)現(xiàn)如下功能:
完成監(jiān)控頁面展示
接受POST提交上來的數(shù)據(jù)
提供json數(shù)據(jù)GET接口
具體框架結(jié)構(gòu)圖如下:

目錄結(jié)構(gòu)如下:
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 ,具體模板頁面內(nèi)容如下:
[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代碼都直接使用互聯(lián)網(wǎng)上的代碼,如果主機(jī)無法連接互聯(lián)網(wǎng)的,可以將上面的三段代取取下來,在templates 的同級目錄創(chuàng)建static 目錄,將下載下來的三個文件放到該目錄,刪除模板中三處引用javascript處的代碼,使用當(dāng)前注釋的三段。
三、agent被監(jiān)控端設(shè)置
web展示頁面完成了,運(yùn)行起來:python flask_web.py 監(jiān)聽在8888端口上。我們需要做一個agent來采集數(shù)據(jù),并通過post方法請求flask_web頁面,將數(shù)據(jù)上傳寫入數(shù)據(jù)庫。這里以監(jiān)控內(nèi)存為例,具體監(jiān)控代碼如下:
#!/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類里的所有g(shù)etXXX方法,用XXX作為key,getXXX()的返回值作為value,構(gòu)造字典
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 & 在被監(jiān)控主機(jī)上運(yùn)行,如果出于實(shí)驗(yàn)?zāi)康模氡M快的看到展示效果,可以將time.sleep(60) 改為time.sleep(2) ,這樣每2秒就會取一次數(shù)據(jù)寫入數(shù)據(jù)庫。
訪問 http://test.361way.com:8888 就可以看到我們的監(jiān)控?cái)?shù)據(jù)了:效果圖如下

highcharts支持將按時間拖動,也支持按指定時間段查看。并且查看到的圖片可以直接保存為png、jpg或pdf、csv等格式查看。
相關(guān)文章
Python數(shù)據(jù)獲取實(shí)現(xiàn)圖片數(shù)據(jù)提取
本文主要介紹了Python數(shù)據(jù)獲取實(shí)現(xiàn)圖片數(shù)據(jù)提取,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
python基于tkinter點(diǎn)擊按鈕實(shí)現(xiàn)圖片的切換
這篇文章主要介紹了python基于tkinter點(diǎn)擊按鈕實(shí)現(xiàn)圖片的切換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
將python字符串轉(zhuǎn)化成長表達(dá)式的函數(shù)eval實(shí)例
這篇文章主要介紹了將python字符串轉(zhuǎn)化成長表達(dá)式的函數(shù)eval實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
60行Python PyGame代碼實(shí)現(xiàn)簡單的迷宮游戲
這篇文章主要為大家詳細(xì)介紹如何通過了60行Python PyGame代碼實(shí)現(xiàn)一個簡單的迷宮游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2023-12-12
Python如何獲取免費(fèi)高匿代理IP及驗(yàn)證
這篇文章主要介紹了Python如何獲取免費(fèi)高匿代理IP及驗(yàn)證問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
python數(shù)據(jù)分析之單因素分析線性擬合及地理編碼
這篇文章主要介紹了python數(shù)據(jù)分析之單因素分析線性擬合及地理編碼,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06
Python多維/嵌套字典數(shù)據(jù)無限遍歷的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄狿ython多維/嵌套字典數(shù)據(jù)無限遍歷的實(shí)現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11

