監控系統我們都知道用來監控服務器系統的一個穩定性了,下面整理了一篇flask + mysql寫的簡單監控系統的配置例子,希望對各位有幫助.
這里以監控內存使用率為例,寫的一個簡單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接口,具體框架結構圖如下:
flask-monitor
目錄結構如下:
- 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)) //Vevb.com
- 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 就可以看到我們的監控數據了.
flask-highcharts
highcharts支持將按時間拖動,也支持按指定時間段查看,并且查看到的圖片可以直接保存為png、jpg或pdf、csv等格式查看.
這只是一個簡單的監控系統了其實是非常的簡單了,當然要做和高準確還是需要其它的專業工具來實現了.
新聞熱點
疑難解答