运维高手十分钟写了一个内存监控系统

  1. 云栖社区>
  2. 博客>
  3. 正文

运维高手十分钟写了一个内存监控系统

玄学酱 2017-08-15 10:56:00 浏览2563
展开阅读全文

本文的目的在于,尽可能用简单的代码,让大家了解内存监控的原理及思想,更容易去理解Nagios、Zabbix、Ganglia监控原理。文章最后还有视频教程哦!从零敲出来的全过程。

思路分为下面几块:

1.获取内存监控信息

2.存储监控信息

3.数据展现

4.后续扩展

    a.加主机名,monitor部署在多台机器,不直接插入数据库

    b.增加CPU,Disk监控

    c.通过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获取监控数据。


  1. def getMem(): 
  2. with open('/proc/meminfo'as f: 
  3. total = int(f.readline().split()[1]) 
  4. free = int(f.readline().split()[1]) 
  5. buffers = int(f.readline().split()[1]) 
  6. cache = int(f.readline().split()[1]) 
  7. mem_use = total-free-buffers-cache 
  8. print mem_use/1024 
  9. while True
  10. time.sleep(1) 
  11. getMem() 

测试:每秒打印一条数据。


  1. [www.51reboot.com@teach memory]$ python mointor.py 2920 
  2.  2919 
  3.  2919 
  4.  2919 
  5.  2919 

希望内存多变好一些,写了一个很挫的测试代码。


  1. # test.py 
  2. s = 'www.51reboot.com'*1000000 
  3. for i in s: 
  4. for j in s: 
  5. s.count(j) 

执行python test.py,会发现内存占用多了几M,说明咱们的代码是OK的。

第二步:存储监控信息(我们用MySQL)

我们需要两个字段,内存和时间 sql呼之欲出,简单粗暴!


  1. create database memory; 
  2. create memory(memory int,time int

接下来,我们把monitor.py的数据存储到数据库中,这用到了Python MySQLdb模块。


  1. import time 
  2. import MySQLdb as mysql 
  3. db = mysql.connect(user="reboot",passwd="reboot123",db="memory",host="localhost"
  4. db.autocommit(True
  5. cur = db.cursor() 
  6. def getMem(): 
  7. with open('/proc/meminfo'as f: 
  8. total = int(f.readline().split()[1]) 
  9. free = int(f.readline().split()[1]) 
  10. buffers = int(f.readline().split()[1]) 
  11. cache = int(f.readline().split()[1]) 
  12. mem_use = total-free-buffers-cache 
  13. t = int(time.time()) 
  14. sql = 'insert into memory (memory,time) value (%s,%s)'%(mem_use/1024,t) 
  15. cur.execute(sql) 
  16. print mem_use/1024 
  17. while True
  18. time.sleep(1) 
  19. getMem() 

暂时告一段落。

第三步:数据展现(Flask框架)

代码结构:

├── flask_web.py web后端代码

├── mointor.py 监控数据获取

├── static 静态文件,第三方图表库

    │ ├── exporting.js

    │ ├── highstock.js

│ └── jquery.js

├── templates

    │ └── index.html 展示前端页面

└── test.py 占用内存的测试代码

flask_web.py的代码如下:

提供两个路由。

◆根目录渲染文件index.html。

◆/data路由去数据库查数据,返回json,供画图使用。


  1. from flask import Flask,render_template,request 
  2. import MySQLdb as mysql 
  3. con = mysql.connect(user='reboot',passwd='reboot123',host='localhost',db='memory'
  4. con.autocommit(True
  5. cur = con.cursor() 
  6. app = Flask(__name__) 
  7. import json 
  8. @app.route('/'
  9. def index(): 
  10. return render_template('index.html'
  11. @app.route('/data'
  12. def data(): 
  13. sql = 'select * from memory' 
  14. cur.execute(sql) 
  15. arr = [] 
  16. for i in cur.fetchall(): 
  17. arr.append([i[1]*1000,i[0]]) 
  18. return json.dumps(arr) 
  19. if __name__=='__main__'
  20. app.run(host='0.0.0.0',port=9092,debug=True

前端index.html


  1. <div id="container" style="height: 400px; min-width: 310px"></div> 
  2. <script> 
  3. $(function () { 
  4. // 使用当前时区,否则东八区会差八个小时 
  5. Highcharts.setOptions({ 
  6. global: { 
  7. useUTC: false 
  8. }); 
  9. $.getJSON('/data'function (data) { 
  10. // Create the chart 
  11. $('#container').highcharts('StockChart', { 
  12. rangeSelector : { 
  13. selected : 1 
  14. }, 
  15. title : { 
  16. text : '内存数据' 
  17. }, 
  18. series : [{ 
  19. name : '本机内存'
  20. data : data, 
  21. tooltip: { 
  22. valueDecimals: 2 
  23. }] 
  24. }); 
  25. }); 
  26. }); 
  27. </script> 

执行python flask_web.py,浏览器看数据www.51reboot.com:9092,出图了。

我们并不仅限于此,如果想实时的看到内存,应该怎么搞?

1.查询数据时候增加一个时间戳当限制条件,只返回两次查询之间的增量数据。

2.前端动态添加增量结点数据到图表中。

修改flask_web.py。


  1. tmp_time = 0 
  2. @app.route('/data'
  3. def data(): 
  4. global tmp_time 
  5. if tmp_time>0: 
  6. sql = 'select * from memory where time>%s' % (tmp_time/1000) 
  7. else
  8. sql = 'select * from memory' 
  9. cur.execute(sql) 
  10. arr = [] 
  11. for i in cur.fetchall(): 
  12. arr.append([i[1]*1000,i[0]]) 
  13. if len(arr)>0: 
  14. tmp_time = arr[-1][0] 
  15. return json.dumps(arr) 

前端,3秒查一次增量数据,根据自己需求调整,修改index.html。


  1. $.getJSON('/data'function (data) { 
  2. // Create the chart 
  3. $('#container').highcharts('StockChart', { 
  4. chart:{ 
  5. events:{ 
  6. load:function(){ 
  7. var series = this.series[0] 
  8. setInterval(function(){ 
  9. $.getJSON('/data',function(res){ 
  10. $.each(res,function(i,v){ 
  11. series.addPoint(v) 
  12. }) 
  13. }) 
  14. },3000) 
  15. }, 
  16. rangeSelector : { 
  17. selected : 1 
  18. }, 
  19. title : { 
  20. text : 'AAPL Stock Price' 
  21. }, 
  22. series : [{ 
  23. name : 'AAPL'
  24. data : data, 
  25. tooltip: { 
  26. valueDecimals: 2 
  27. }] 
  28. }); 
  29. }); 

done!两个文件都搞定,double kill!效果。



作者:Reboot
来源:51CTO

网友评论

登录后评论
0/500
评论
玄学酱
+ 关注