python 嵌入式webserver 服务器 状态监控

来源:互联网 发布:重生之古董商淘宝之旅 编辑:程序博客网 时间:2024/05/29 08:00


思路主要是用python脚本获取linux服务器的各种状态信息,然后用webserver的方式,以json数据发给http,主控节点去读取webserver返回的json,生成系统监控报表。代码简单,开发和部署都很方便。


用到的主要东西是python的第三方嵌入式web模块叫cherrypy,之所以选择cherrypy,主要原因就是开发快速,学习也很快,基本我用了一天多就基本学会了怎么来写了。当然,也可以用python自带的simpleHTTPserver。不过那个确实太simple了。cherrypy的优点在于,多线程,多并发。又不像Tornado和Django那样重量级。因为我们返回的是json,也用不到什么html模板,数据库的功能。当然也可以选择web.py,不过相比还是cherrypy更好一点我认为,web.py也借鉴了cherrypy不少的思想。



主要流程是这样:


想办法读取Linux系统的各种数据  --->  解析数据转成json发给http服务器  --->  监控服务器扫描数据生成图表


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/python
# -*- coding: utf8 -*-
import sys
import cherrypy
import platform
import os
import time
#python 2.4为simplejson,python 2.6以上为json
try:
    import json
except ImportError:
    import simplejson as json
                                                                                
#假装做一个index出来
class Index(object):
    #下面这句表示修饰index方法,这个index方法是暴露给http server的
    @cherrypy.expose
    def index(self):
        return "hello cherrypy"
                                                                                    
class Node(object):
    '''
    url /node/dist/
    '''
    #获取目标机器的发行分支,版本号,架构类型,主机名称等等,返回json
    @cherrypy.expose
    def dist(self):
        dist_json = ''
        sysinstaller = ''
        installer = ''
        ostype = platform.dist()
        if(ostype[0in ['Ubuntu','debian','ubuntu','Debian']):
            sysinstaller = 'apt-get'
            installer = 'dpkg'
        elif(ostype[0in ['SuSE']):
            sysinstaller = 'zypper'
            installer = 'rpm'
        elif(ostype[0in ['CentOS''centos''redhat','RedHat']):
            sysinstaller = 'yum'
            installer = 'rpm'
            machine = platform.machine()
        hostname = platform.node()
                                                                                    
        dist_json = {'os.system':ostype[0], 'os.version':ostype[1], 'os.release':ostype[2], 'os.sysinstall':sysinstaller, 'os.installer':installer, 'os.arch':machine, 'os.hostname':hostname}
        return json.dumps(dist_json, sort_keys=False, indent=4, separators=(','': '))
    '''
    url /node/GetCpuInfo/
    '''
    #获取CPU型号等,返回json
    @cherrypy.expose
    def GetCpuInfo(self):
        cpu = []
        cpuinfo = {}
        = open("/proc/cpuinfo")
        lines = f.readlines()
        f.close()
        for line in lines:
            if line == 'n':
                cpu.append(cpuinfo)
                cpuinfo = {}
            if len(line) < 2continue
            name = line.split(':')[0].strip().replace(' ','_')
            var = line.split(':')[1].strip()
            cpuinfo[name] = var
        return json.dumps(cpuinfo, sort_keys=False, indent=4, separators=(','': '))
    '''
    url /node/GetMemInfo/
    '''
    #获取内存使用的详细信息
    @cherrypy.expose
    def GetMemInfo(self):
        mem = {}
        = open("/proc/meminfo")
        lines = f.readlines()
        f.close()
        for line in lines:
            if len(line) < 2:
                   continue
            name = line.split(':')[0]
            var = line.split(':')[1].split()[0]
            mem[name] = long(var) * 1024.0
        mem['MemUsed'= mem['MemTotal'- mem['MemFree'- mem['Buffers'- mem['Cached']
        return json.dumps(mem, sort_keys=False, indent=4, separators=(','': '))
    '''
    url /node/GetLoadAvg//
    '''
    #获取系统负载的详细信息
    @cherrypy.expose
    def GetLoadAvg(self):
        loadavg = {}
        = open("/proc/loadavg")
        con = f.read().split()
        f.close()
        loadavg['lavg_1']=con[0]
        loadavg['lavg_5']=con[1]
        loadavg['lavg_15']=con[2]
        loadavg['nr']=con[3]
        loadavg['last_pid']=con[4]
        return json.dumps(loadavg, sort_keys=False, indent=4, separators=(','': '))
    '''
    url /node/GetIfInfo/eth(x)
    '''
    获取指定网卡的流量信息,这里面有点复杂
    @cherrypy.expose
    def GetIfInfo(self, interface):
        dist_json = self.dist()
        = open("/proc/net/dev")
        lines = f.readlines()
        f.close()
        intf = {}
        for line in lines[2:]:
            con = line.split()
            #if部分是给centos使用的,centos在流量大的情况下,网卡信息里面字符串会连上,所以需要单独拆分处理,else部分则是ubuntu或者其他系统格式化很好的使用
            if con[0][-1].isdigit() == True:
                offset = con[0].split(':')
                intf['interface'= str(offset[0])
                intf['ReceiveBytes'= str(offset[1])
                intf['ReceivePackets'= str(con[1])
                intf['ReceiveErrs'= str(con[2])
                intf['ReceiveDrop'= str(con[3])
                intf['ReceiveFifo'= str(con[4])
                intf['ReceiveFrames'= str(con[5])
                intf['ReceiveCompressed'= str(con[6])
                intf['ReceiveMulticast'= str(con[7])
                intf['TransmitBytes'= str(con[8])
                intf['TransmitPackets'= str(con[9])
                intf['TransmitErrs'= str(con[10])
                intf['TransmitDrop'= str(con[11])
                intf['TransmitFifo'= str(con[12])
                intf['TransmitFrames'= str(con[13])
                intf['TransmitCompressed'= str(con[14])
                intf['TransmitMulticast'= str(con[15])
            else:
                intf['interface'= str(con[0])
                intf['ReceiveBytes'= str(con[1])
                intf['ReceivePackets'= str(con[2])
                intf['ReceiveErrs'= str(con[3])
                intf['ReceiveDrop'= str(con[4])
                intf['ReceiveFifo'= str(con[5])
                intf['ReceiveFrames'= str(con[6])
                intf['ReceiveCompressed'= str(con[7])
                intf['ReceiveMulticast'= str(con[8])
                intf['TransmitBytes'= str(con[9])
                intf['TransmitPackets'= str(con[10])
                intf['TransmitErrs'= str(con[11])
                intf['TransmitDrop'= str(con[12])
                intf['TransmitFifo'= str(con[13])
                intf['TransmitFrames'= str(con[14])
                intf['TransmitCompressed'= str(con[15])
                intf['TransmitMulticast'= str(con[16])
        return json.dumps(intf, sort_keys=False)
    #获取全部网卡的接口和流量信息
    @cherrypy.expose
    def GetIfTraffic(self):
        ifs = []
        nettraffic = {}
        = open("/proc/net/dev")
        lines = f.readlines()
        f.close()
        for line in lines[2:]:
            con = line.split()
            ifname = con[0].split(':')
            if(ifname[0].strip() != 'lo'):
                ifs.append(ifname[0].strip())
            else:
                continue
        for interface in ifs:
            nettraffic[interface] = self.GetIfInfo( interface)
                                                                                    
        return json.dumps(nettraffic)
    #获取硬盘的分区信息和使用量
    @cherrypy.expose
    def GetHddInfo(self):
        hdds = []
        mount = {}
        file_system = []
        type = []
        size = []
        used = []
        avail = []
        used_percent = []
        mounted_on = []
        hdds = os.popen('df -lhT  | grep -v tmpfs | grep -v boot | grep -v usr | grep -v tmp | sed \'1d;/ /!N;s/\\n//;s/[ ]*[ ]/\\t/g;\'').readlines()
        for line in hdds:
            file_system.append(line.replace('\\n','').replace('\\t',' ').split()[0])
            type.append(line.replace('\\n','').replace('\\t',' ').split()[1])
            size.append(line.replace('\\n','').replace('\\t',' ').split()[2])
            used.append(line.replace('\\n','').replace('\\t',' ').split()[3])
            avail.append(line.replace('\\n','').replace('\\t',' ').split()[4])
            used_percent.append(line.replace('\\n','').replace('\\t',' ').split()[5])
            mounted_on.append(line.replace('\\n','').replace('\\t',' ').split()[6])
        mount['file_system'= file_system
        mount['type'= type
        mount['size'= size
        mount['used'= used
        mount['avail'= avail
        mount['used_percent'= used_percent
        mount['mounted_on'= mounted_on
        dist_json = json.dumps(mount)
        return dist_json
                                                                                
    #获取CPU的使用量信息,需要系统安装sysstat支持
    @cherrypy.expose
    def GetCpuDetail(self):
        dist_json = self.dist()
        dist = json.loads(dist_json)
        if(dist['os.system'in ['CentOS''centos''redhat''RedHat']):
            if(int(dist['os.version'].split('.')[0])  < 6):  #For CentOS only
                cmd = 'mpstat 1 1 | sed \'1d;2d;3d;4d\' | awk \'{print "{\\\"user\\\":\\\"\"$3\"\\\",\\\"nice\\\":\\\"\"$4\"\\\",\\\"sys\\\":\\\"\"$5\"\\\",\\\"iowait\\\":\\\"\"$6\"\\\",\\\"irq\\\":\\\"\"$7\"\\\",\\\"soft\\\":\\\"\"$8\"\\\",\\\"steal\\\":\\\"\"$9\"\\\",\\\"idle\\\":\\\"\"$10\"\\\"}"}\''
            else:
                cmd = 'mpstat 1 1 | sed \'1d;2d;3d;4d\' | awk \'{print "{\\\"user\\\":\\\"\"$3\"\\\",\\\"nice\\\":\\\"\"$4\"\\\",\\\"sys\\\":\\\"\"$5\"\\\",\\\"iowait\\\":\\\"\"$6\"\\\",\\\"irq\\\":\\\"\"$7\"\\\",\\\"soft\\\":\\\"\"$8\"\\\",\\\"steal\\\":\\\"\"$9\"\\\",\\\"idle\\\":\\\"\"$11\"\\\"}"}\''
        else:
            cmd = 'mpstat 1 1 | sed \'1d;2d;3d;4d\' | awk \'{print "{\\\"user\\\":\\\"\"$3\"\\\",\\\"nice\\\":\\\"\"$4\"\\\",\\\"sys\\\":\\\"\"$5\"\\\",\\\"iowait\\\":\\\"\"$6\"\\\",\\\"irq\\\":\\\"\"$7\"\\\",\\\"soft\\\":\\\"\"$8\"\\\",\\\"steal\\\":\\\"\"$9\"\\\",\\\"idle\\\":\\\"\"$11\"\\\"}"}\''
        cpu = os.popen(cmd).readline().strip()
        return cpu
if "__main__" == __name__:
    #服务器配置
    settings = {
                'global': {
                    #绑定端口
                    'server.socket_port' 60090,
                    #ip地址设置,觉得够安全就用0.0.0.0,否则就单独写那台服务器的ip
                    'server.socket_host''0.0.0.0',
                    'server.socket_file': '',
                    'server.socket_queue_size'100,
                    'server.protocol_version''HTTP/1.1',
                    'server.log_to_screen'True,
                    'server.log_file': '',
                    'server.reverse_dns'False,
                    'server.thread_pool'200,
                    'server.environment''production',
                    'engine.timeout_monitor.on'False
                }
        }
        #使用配置和映射路由并启动webserver
        cherrypy.config.update(settings)
        cherrypy.tree.mount(Index(), '/')
        cherrypy.tree.mount(Node(), '/node')
        cherrypy.engine.start()


原创粉丝点击