[开发]Python实现运维监控服务器硬

发布时间:2019-08-28 09:12:54编辑:auto阅读(1560)

          今天通过使用Python开发针对服务器硬件运行状态的监控,简单了解下在虚拟环境中的运维监控的实现,算是给全面研究云计算开一个头。

    1.先准备环境,软件配置如下:
    虚拟环境:     Vmware 10
    操作系统:     Linux ubuntu-14.04-server-amd64
    数据库   :     Mysql
    开发语言:     Python 2.7
    可视化   :     Highcharts
    2.省略安装软件的步骤,开始创建数据库
         
    创建数据库“flacon” 
    CREATE DATABASE flacon;

    创建表“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;


    在开发之前注意创建文件工程目录
    web
    --templates
       --mon.html
    --flask_web.py
    --monItems.py

    3.用Python开发后台服务flask_web.py,用于将查询到的数据存入数据库,并相应前端页面的展示请求

    <span style="font-size:14px;">import MySQLdb as mysql
    import json
    from flask import Flask, request, render_template
    app = Flask(__name__)
    db = mysql.connect(user="root", passwd="root", \
            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)</span>



    注:服务通过ip:8888/和ip:8888/data两个请求url,用于相应不同的请求。根节点实现了两个方法,post方法用于将操作系统的监控数据接收并存储到mysql数据库中;get方法则返回mon.html页面。
         /data的url用于相应客户端页面提交的查询最新的数据的请求,这里根据查询条件的不同可以查询到不同的信息,这里没有实现查询全部属性而是默认了mem_usage。
         运行服务之后,效果如下:
    4.用Python开发查询系统资源的服务moniItems.py

    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://localhost:8888", json.dumps(data), {'Content-Type': 'application/json'})
            f = urllib2.urlopen(req)
            response = f.read()
            print response
            f.close()
            time.sleep(2)

    
    
    4.最后开发前端展示图表
    
    <title>运维原型</title>
    <!DOCTYPE HTML>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <title>运维原型</title>
    
            <script type="text/javascript" src="http://code.jquery.com/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: '运维原型'
                },
    
                series: [{
                    name: '运维原型',
                    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>
    

    注:顶一个div,命名为container,用于存放统计图表。页面通过向/data目录提交请求获得监控数据的查询结果,在回调函数中展示。通过访问url:http://ip:8888可以看到展现效果,如下:
    
    5.总结
    
         通过这个例子的开发,可以了解通过Python进行运维监控的基本方法,关键问题是要从操作系统的/proc/meminfo和/proc/loadavg文件查询操作系统内存使用数据和CPU的负载信息。以下blog可以帮助详细了解memnifo文件的内容和/proc目录其他文件的介绍。
    http://blog.csdn.net/cnctloveyu/article/details/4074892
    http://blog.csdn.net/kevinx_xu/article/details/8178746
         
    
    
    

         


    
    

关键字