市面上有很多开源的监控系统:Cacti、nagios、zabbix。感觉都不符合我的需求,为什么不自己做一个呢
用Python两个小时徒手撸了一个简易的监控系统,给大家分享一下,希望能对大家有所启发
首先数据库建表
建立一个数据库“falcon”,建表语句如下:
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;
首先我们设计一个web服务,实现如下功能:
1.完成监控页面展示
2.接受POST提交上来的数据
3.提供json数据GET接口
目录结构如下:
web
├── flask_web.py
└── templates
└── mon.html
[/code]
flask_web.py
[code]
import MySQLdb as mysql
import json
from flask import Flask, request, render_template
app = Flask(__name__)
db = mysql.connect(user=\"reboot\", passwd=\"reboot123\", \\
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)
这个template页面是我抄的highstock的示例,mon.html
简单起见我们只展示mem_usage信息到页面上
jb51.net Highstock Example
web展示页面完成了,运行起来:
Python flask_web.py 监听在8888端口上
我们需要做一个agent来采集数据,并上传数据库
moniItems.py
#!/usr/bin/env python
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://jb51.net: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 & 运行起来
访问 http://jb51.net:8888 就可以看到我们的监控数据了:效果图如下
