市面上有很多开源的监控系统:Cacti、nagios、zabbix。感觉都不符合我的需求,为什么不自己做一个呢
用Python两个小时徒手撸了一个简易的监控系统,给大家分享一下,希望能对大家有所启发
首先数据库建表
建立一个数据库“falcon”,建表语句如下:
1 CREATE TABLE `stat` ( 2 `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 3 `host` varchar(256) DEFAULT NULL, 4 `mem_free` int(11) DEFAULT NULL, 5 `mem_usage` int(11) DEFAULT NULL, 6 `mem_total` int(11) DEFAULT NULL, 7 `load_avg` varchar(128) DEFAULT NULL, 8 `time` bigint(11) DEFAULT NULL, 9 PRIMARY KEY (`id`),10 KEY `host` (`host`(255))11 ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
首先我们设计一个web服务,实现如下功能:
- 完成监控页面展示
- 接受POST提交上来的数据
- 提供json数据GET接口
目录结构如下:
web├── flask_web.py└── templates └── mon.html
flask_web.py
1 import MySQLdb as mysql 2 import json 3 from flask import Flask, request, render_template 4 app = Flask(__name__) 5 db = mysql.connect(user="reboot", passwd="reboot123", \ 6 db="falcon", charset="utf8") 7 db.autocommit(True) 8 c = db.cursor() 9 10 @app.route("/", methods=["GET", "POST"])11 def hello():12 sql = ""13 if request.method == "POST":14 data = request.json15 try:16 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']))17 ret = c.execute(sql)18 except mysql.IntegrityError:19 pass20 return "OK"21 else:22 return render_template("mon.html")23 24 @app.route("/data", methods=["GET"])25 def getdata():26 c.execute("SELECT `time`,`mem_usage` FROM `stat`")27 ones = [[i[0]*1000, i[1]] for i in c.fetchall()]28 return "%s(%s);" % (request.args.get('callback'), json.dumps(ones))29 30 31 if __name__ == "__main__":32 app.run(host="0.0.0.0", port=8888, debug=True)
这个template页面是我抄的highstock的示例,mon.html
简单起见我们只展示mem_usage信息到页面上
151reboot.com 2 3 4 5 6Highstock Example 7 8 9 12 40 41 42 43 44 45 46 47 48
web展示页面完成了,运行起来:
python flask_web.py 监听在8888端口上
我们需要做一个agent来采集数据,并上传数据库
moniItems.py
1 #!/usr/bin/env python 2 import inspect 3 import time 4 import urllib, urllib2 5 import json 6 import socket 7 8 class mon: 9 def __init__(self):10 self.data = {}11 12 def getTime(self):13 return str(int(time.time()) + 8 * 3600)14 15 def getHost(self):16 return socket.gethostname()17 18 def getLoadAvg(self):19 with open('/proc/loadavg') as load_open:20 a = load_open.read().split()[:3]21 return ','.join(a)22 23 def getMemTotal(self):24 with open('/proc/meminfo') as mem_open:25 a = int(mem_open.readline().split()[1])26 return a / 102427 28 def getMemUsage(self, noBufferCache=True):29 if noBufferCache:30 with open('/proc/meminfo') as mem_open:31 T = int(mem_open.readline().split()[1])32 F = int(mem_open.readline().split()[1])33 B = int(mem_open.readline().split()[1])34 C = int(mem_open.readline().split()[1])35 return (T-F-B-C)/102436 else:37 with open('/proc/meminfo') as mem_open:38 a = int(mem_open.readline().split()[1]) - int(mem_open.readline().split()[1])39 return a / 102440 41 def getMemFree(self, noBufferCache=True):42 if noBufferCache:43 with open('/proc/meminfo') as mem_open:44 T = int(mem_open.readline().split()[1])45 F = int(mem_open.readline().split()[1])46 B = int(mem_open.readline().split()[1])47 C = int(mem_open.readline().split()[1])48 return (F+B+C)/102449 else:50 with open('/proc/meminfo') as mem_open:51 mem_open.readline()52 a = int(mem_open.readline().split()[1])53 return a / 102454 55 def runAllGet(self):56 #自动获取mon类里的所有getXXX方法,用XXX作为key,getXXX()的返回值作为value,构造字典57 for fun in inspect.getmembers(self, predicate=inspect.ismethod):58 if fun[0][:3] == 'get':59 self.data[fun[0][3:]] = fun[1]()60 return self.data61 62 if __name__ == "__main__":63 while True:64 m = mon()65 data = m.runAllGet()66 print data67 req = urllib2.Request("http://51reboot.com:8888", json.dumps(data), { 'Content-Type': 'application/json'})68 f = urllib2.urlopen(req)69 response = f.read()70 print response71 f.close()72 time.sleep(60)
nohup python moniItems.py >/dev/null 2>&1 & 运行起来
访问 http://51reboot.com:8888 就可以看到我们的监控数据了:效果图如下
欢迎加入运维开发技术分享QQ群:365534424;数百位业内高手和同行在等你交流