免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 20671 | 回复: 8
打印 上一主题 下一主题

[DevOps] 不到200行代码搞定自己的监控系统(附视频讲解)-Python运维三十六式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-01 20:45 |只看该作者 |倒序浏览
本帖最后由 xjtuhit 于 2014-10-05 14:01 编辑

原文地址:http://51reboot.com/python36-falcon-mon/
视频地址:http://51reboot.com/python36-falcon-mon-video/

觉得还有点用,转过来分享一下
市面上有很多开源的监控系统: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接口

目录结构如下:
  1. web
  2. ├── flask_web.py
  3. └── templates
  4.     └── 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. @app.route("/", methods=["GET", "POST"])
  10. def hello():
  11.     sql = ""
  12.     if request.method == "POST":
  13.         data = request.json
  14.         try:
  15.             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']))
  16.             ret = c.execute(sql)
  17.         except mysql.IntegrityError:
  18.             pass
  19.         return "OK"
  20.     else:
  21.         return render_template("mon.html")

  22. @app.route("/data", methods=["GET"])
  23. def getdata():
  24.     c.execute("SELECT `time`,`mem_usage` FROM `stat`")
  25.     ones = [[i[0]*1000, i[1]] for i in c.fetchall()]
  26.     return "%s(%s);" % (request.args.get('callback'), json.dumps(ones))
  27.    

  28. if __name__ == "__main__":
  29.     app.run(host="0.0.0.0", port=8888, debug=True)
复制代码
这个template页面是我抄的highstock的示例,mon.html

简单起见我们只展示mem_usage信息到页面上
  1. <title>51reboot.com</title>
  2. <!DOCTYPE HTML>
  3. <html>
  4.     <head>
  5.         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  6.         <title>Highstock Example</title>

  7.         <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
  8.         <style type="text/css">
  9. ${demo.css}
  10.         </style>
  11.         <script type="text/javascript">
  12. $(function () {
  13.     $.getJSON('/data?callback=?', function (data) {

  14.         // Create the chart
  15.         $('#container').highcharts('StockChart', {

  16.             rangeSelector: {
  17.                 inputEnabled: $('#container').width() > 480,
  18.                 selected: 1
  19.             },

  20.             title: {
  21.                 text: '51Reboot.com'
  22.             },

  23.             series: [{
  24.                 name: '51Reboot.com',
  25.                 data: data,
  26.                 type: 'spline',
  27.                 tooltip: {
  28.                     valueDecimals: 2
  29.                 }
  30.             }]
  31.         });
  32.     });
  33. });
  34.         </script>
  35.     </head>
  36.     <body>
  37. <script src="http://cdnjs.cloudflare.com/ajax/libs/highstock/2.0.4/highstock.js"></script>
  38. <script src="http://code.highcharts.com/modules/exporting.js"></script>


  39. <div id="container" style="height: 400px"></div>
  40.     </body>
  41. </html>
复制代码
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. class mon:
  8.     def __init__(self):
  9.         self.data = {}

  10.     def getTime(self):
  11.         return str(int(time.time()) + 8 * 3600)

  12.     def getHost(self):
  13.         return socket.gethostname()

  14.     def getLoadAvg(self):
  15.         with open('/proc/loadavg') as load_open:
  16.             a = load_open.read().split()[:3]
  17.             return ','.join(a)
  18.    
  19.     def getMemTotal(self):
  20.         with open('/proc/meminfo') as mem_open:
  21.             a = int(mem_open.readline().split()[1])
  22.             return a / 1024
  23.    
  24.     def getMemUsage(self, noBufferCache=True):
  25.         if noBufferCache:
  26.             with open('/proc/meminfo') as mem_open:
  27.                 T = int(mem_open.readline().split()[1])
  28.                 F = int(mem_open.readline().split()[1])
  29.                 B = int(mem_open.readline().split()[1])
  30.                 C = int(mem_open.readline().split()[1])
  31.                 return (T-F-B-C)/1024
  32.         else:
  33.             with open('/proc/meminfo') as mem_open:
  34.                 a = int(mem_open.readline().split()[1]) - int(mem_open.readline().split()[1])
  35.                 return a / 1024
  36.    
  37.     def getMemFree(self, noBufferCache=True):
  38.         if noBufferCache:
  39.             with open('/proc/meminfo') as mem_open:
  40.                 T = int(mem_open.readline().split()[1])
  41.                 F = int(mem_open.readline().split()[1])
  42.                 B = int(mem_open.readline().split()[1])
  43.                 C = int(mem_open.readline().split()[1])
  44.                 return (F+B+C)/1024
  45.         else:
  46.             with open('/proc/meminfo') as mem_open:
  47.                 mem_open.readline()
  48.                 a = int(mem_open.readline().split()[1])
  49.                 return a / 1024
  50.    
  51.     def runAllGet(self):
  52.         #自动获取mon类里的所有getXXX方法,用XXX作为key,getXXX()的返回值作为value,构造字典
  53.         for fun in inspect.getmembers(self, predicate=inspect.ismethod):
  54.             if fun[0][:3] == 'get':
  55.                 self.data[fun[0][3:]] = fun[1]()
  56.         return self.data

  57. if __name__ == "__main__":
  58.     while True:
  59.         m = mon()
  60.         data = m.runAllGet()
  61.         print data
  62.         req = urllib2.Request("http://51reboot.com:8888", json.dumps(data), {'Content-Type': 'application/json'})
  63.         f = urllib2.urlopen(req)
  64.         response = f.read()
  65.         print response
  66.         f.close()
  67.         time.sleep(60)
复制代码
nohup python moniItems.py >/dev/null 2>&1 & 运行起来

访问 http://51reboot.com:8888 就可以看到我们的监控数据了:效果图如下

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
2 [报告]
发表于 2014-10-02 22:01 |只看该作者
不错。

论坛徽章:
0
3 [报告]
发表于 2014-10-10 17:19 |只看该作者
相当不错                 

论坛徽章:
0
4 [报告]
发表于 2014-10-11 11:20 |只看该作者
好强大

论坛徽章:
0
5 [报告]
发表于 2014-10-12 14:19 |只看该作者
太牛鼻了~~

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
6 [报告]
发表于 2014-10-19 07:34 |只看该作者
回复 1# xjtuhit

又看了一遍,是本人的作品吗? 楼主有兴趣open source 一下吗?放到github里,我有兴趣提供改进。


   

论坛徽章:
0
7 [报告]
发表于 2014-10-25 16:04 |只看该作者
是긞爅写的。可以开源。 有兴趣可以站内。
回复 6# rdcwayx


   

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
8 [报告]
发表于 2014-10-26 14:16 |只看该作者
开源的话,自己放到github,你可以把 repository的URL放在这里即可。

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-08-25 06:20:00
9 [报告]
发表于 2015-09-08 18:17 |只看该作者
楼主太强大了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP