10min 手寫一個內存監控系統
本文的目的在於,盡可能用簡單的代碼,讓大家了解內存監控的原理,及思想。更容易去理解Nagios、Zabbix、Ganglia監控原理,文章最後還有視頻教程鏈接哦,從零敲出來的全過程
思路分為下面幾塊:
1.獲取內存監控信息
2.存儲監控信息
3.數據展現
4.後續擴展
1.加主機名,monitor部署在多臺機器,不直接插入數據庫
2. 增加CPU,Disk監控
3. 通過HTTP請求的方式,啟用一個單獨的Flask專門存儲monitor數據
第一步:獲取內存信息
我們通過讀取 /proc/meminfo獲取監控數據MemTotal、MemFree、Buffers、Cached,咱們常用free -m 其實也是讀取的/pro/meminfo的數據,順便說一下
對於操作系統來說,Buffers、Cached是已經被使用的
MemFree=total-used
對於應用程序來說
MemFree=buffers+cached+free
監控物理內存使用
內存使用=MemTotal-MemFree-Buffers-Cached
開擼:monitor.py獲取監控數據
def getMem(): with open(‘/proc/meminfo‘) as f: total = int(f.readline().split()[1]) free = int(f.readline().split()[1]) buffers = int(f.readline().split()[1]) cache= int(f.readline().split()[1]) mem_use = total-free-buffers-cache print mem_use/1024 while True: time.sleep(1) getMem()
測試:每秒打印一條數據
[www.51reboot.com@teach memory]$ python mointor.py 2920 2919 2919 2919 2919
希望內存多變好一些,寫了一個很挫的測試代碼
# test.py s = ‘www.51reboot.com‘*1000000 for i in s: for j in s: s.count(j)
執行python test.py,會發現內存占用多了幾M,說明咱們的代碼是OK的
第二步:存儲監控信息(我們用MySQL)
我們需要兩個字段,內存和時間 sql呼之欲出,簡單粗暴
create database memory;
create memory(memory int,time int)
接下來我們把monitor.py的數據存儲到數據庫中,這用到了Python MySQLdb模塊
import time import MySQLdb as mysql db = mysql.connect(user="reboot",passwd="reboot123",db="memory",host="localhost") db.autocommit(True) cur = db.cursor() def getMem(): with open(‘/proc/meminfo‘) as f: total = int(f.readline().split()[1]) free = int(f.readline().split()[1]) buffers = int(f.readline().split()[1]) cache = int(f.readline().split()[1]) mem_use = total-free-buffers-cache t = int(time.time()) sql = ‘insert into memory (memory,time) value (%s,%s)‘%(mem_use/1024,t) cur.execute(sql) print mem_use/1024 while True: time.sleep(1) getMem()
暫時告一段落
第三步:數據展現(Flask框架)
代碼結構
├── flask_web.py web後端代碼
├── mointor.py 監控數據獲取
├── static 靜態文件,第三方圖表庫
│ ├── exporting.js
│ ├── highstock.js
│ └── jquery.js
├── templates
│ └── index.html 展示前端頁面
└── test.py 占用內存的測試代碼
from flask import Flask,render_template,request import MySQLdb as mysql con = mysql.connect(user=‘reboot‘,passwd=‘reboot123‘,host=‘localhost‘,db=‘memory‘) con.autocommit(True) cur = con.cursor() app = Flask(__name__) import json @app.route(‘/‘) def index(): return render_template(‘index.html‘) @app.route(‘/data‘) def data(): sql = ‘select * from memory‘ cur.execute(sql) arr = [] for i in cur.fetchall(): arr.append([i[1]*1000,i[0]]) return json.dumps(arr) if __name__==‘__main__‘: app.run(host=‘0.0.0.0‘,port=9092,debug=True)
前端index.html
<div id="container" style="height: 400px; min-width: 310px"></div> <script> $(function () { // 使用當前時區,否則東八區會差八個小時 Highcharts.setOptions({ global: { useUTC: false } }); $.getJSON(‘/data‘, function (data) { // Create the chart $(‘#container‘).highcharts(‘StockChart‘, { rangeSelector : { selected : 1 }, title : { text : ‘內存數據‘ }, series : [{ name : ‘本機內存‘, data : data, tooltip: { valueDecimals: 2 } }] }); }); }); </script>
執行python flask_web.py,瀏覽器看數據www.51reboot.com:9092,出圖了
我們並不僅限於此,如果想實時的看到內存,應該怎麽搞
1.查詢數據時候增加一個時間戳當限制條件,只返回兩次查詢之間的增量數據
2.前端動態添加增量結點數據到圖表中
修改flask_web.py
tmp_time = 0 @app.route(‘/data‘) def data(): global tmp_time if tmp_time>0: sql = ‘select * from memory where time>%s‘ % (tmp_time/1000) else: sql = ‘select * from memory‘ cur.execute(sql) arr = [] for i in cur.fetchall(): arr.append([i[1]*1000,i[0]]) if len(arr)>0: tmp_time = arr[-1][0] return json.dumps(arr)
前端,3秒查一次增量數據,根據自己需求調整,修改index.html
$.getJSON(‘/data‘, function (data) { // Create the chart $(‘#container‘).highcharts(‘StockChart‘, { chart:{ events:{ load:function(){ var series = this.series[0] setInterval(function(){ $.getJSON(‘/data‘,function(res){ $.each(res,function(i,v){ series.addPoint(v) }) }) },3000) } } }, rangeSelector : { selected : 1 }, title : { text : ‘AAPL Stock Price‘ }, series : [{ name : ‘AAPL‘, data : data, tooltip: { valueDecimals: 2 } }] }); });
done!兩個文件都搞定,double kill! 效果
後邊改了這麽多,大家可能糊塗了,現在給出完整代碼:
完整代碼大家可以從Github下載
https://github.com/shengxinjing/my_blog/issues/1
視頻下載地址:http://pan.baidu.com/s/1i4acpP7
Python學習交流群:238757010
10min 手寫一個內存監控系統