- 论坛徽章:
- 0
|
本帖最后由 xjtuhit 于 2014-10-05 14:01 编辑
原文地址:http://51reboot.com/python36-falcon-mon/
视频地址:http://51reboot.com/python36-falcon-mon-video/
觉得还有点用,转过来分享一下
市面上有很多开源的监控系统: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服务,实现如下功能:
完成监控页面展示
接受POST提交上来的数据
提供json数据GET接口
目录结构如下:- web
- ├── flask_web.py
- └── templates
- └── mon.html
复制代码 flask_web.py- 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信息到页面上- <title>51reboot.com</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="http://ajax.googleapis.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: '51Reboot.com'
- },
- series: [{
- name: '51Reboot.com',
- data: data,
- type: 'spline',
- tooltip: {
- valueDecimals: 2
- }
- }]
- });
- });
- });
- </script>
- </head>
- <body>
- <script src="http://cdnjs.cloudflare.com/ajax/libs/highstock/2.0.4/highstock.js"></script>
- <script src="http://code.highcharts.com/modules/exporting.js"></script>
- <div id="container" style="height: 400px"></div>
- </body>
- </html>
复制代码 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://51reboot.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 & 运行起来
访问 http://51reboot.com:8888 就可以看到我们的监控数据了:效果图如下
|
|