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



思路主要是用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[ 0 in  [ 'Ubuntu' , 'debian' , 'ubuntu' , 'Debian' ]):
             sysinstaller  =  'apt-get'
             installer  =  'dpkg'
         elif (ostype[ 0 in  [ 'SuSE' ]):
             sysinstaller  =  'zypper'
             installer  =  'rpm'
         elif (ostype[ 0 in  [ '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) <  2 continue
             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()


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式web服务器boa框架的基础上, 使用C语言cgi, 或者Python脚本, 结合HTML + javascript + ajax 的嵌入式web系统的开发实例 html 中使用javascritp + ajax 从C语言生成的cgi文件的get, set 一些值. boa服务器的相关配置参数说明: http://www.cnblogs.com/liuweiqiang/p/3859130.html boa安装包文件名: boa-for-hi3516a.tar.gz boa.conf 文件的保存路径: cat /etc/boa/boa.conf boa可 执行文件的路径: /usr/local/bin/boa, 可以设置为: 系统启动的时候, 这个进程自动启动 boa.conf 文件的重要参数 保存html文件的目录 DocumentRoot /www 可以将这个目录, 设置为samb共享文件夹的目录, 方便修改调试 修改完成以后, 肯定要重启boa进程的 保存python脚本, 或者C语言cgi文件的目录 ScriptAlias /cgi-bin/ /var/www/cgi-bin/ 说明: cgi-bin/ 后面的斜杠, 一定要加上 可以将这个目录, 设置为samb共享文件夹的目录, 方便修改调试 修改完成以后, 肯定要重启boa进程的 html文件文件中, 调用python脚本的时候, 指定的路径, 需要有: /cgi-bin, 比如: var url = "/cgi-bin/getuser.py"; 这个是python 或者 var url = "/cgi-bin/output.cgi"; 这个是C语言 说明: 如果发现, html文件, 修改了, 可是在浏览器中, 查看html源代码的时候, 这个代码, 还是旧的, 那么可以通过清空"IE浏览器", "360浏览器"的浏览记录 以上, javascript 可以调用python 同样, 也可以调用C语言生成的cgi文件(其实, 就是可执行文件) C语言 + Html 例子 C语言 CGI实例 http://blog.csdn.net/ajrm0925/article/details/8810342 http://blog.csdn.net/liang890319/article/details/6277900 http://blog.csdn.net/gnefniu/article/details/42432657 上传文件: http://blog.csdn.net/yu_xiang/article/details/7996670 查找文件 find . -type f -name "boa.conf" -print -mount find . -type f -name "boa" -print -mount 四、嵌入式web服务器boa的配置和使用 嵌入式web服务器boa的配置文件为boa.conf, 在boa-0.94.13目录下面,复制该文件到文件 系统的/etc/boa目录下面,打开boa.conf,修改为如下内容: Port 80 User root Group root ErrorLog /dev/console AccessLog /dev/null ServerName SoftEmbed.com DocumentRoot /www DirectoryIndex index.html KeepAliveMax 1000 KeepAliveTimeout 10 MimeTypes /etc/mime.types DefaultType text/plain CGIPath /bin:/usr/bin:/usr/local/bin ScriptAlias /cgi-bin/ /www/cgi-bin/ 几个重要配置参数如下: DocumentRoot: 存放html文档的主目录; DirectoryIndex: 默认返回的html文档; ScriptAlias:cgi脚本虚拟路径对应的实际路径,/www/cgi-bin/为cgi脚本存放的实际路径; 其他配置选项的意义请参考相关资料。 复制boa可执行文件到/usr/sbin目录中, 启动boa进程 重新制作文件系统,系统启动后,在客户端浏览器上输入开发板的ip 地址,例如: http://192.168.0.218, 就可以看到显示的测试网页了,如下图所示 CGI getenv函数的参数详解: http://www.cnblogs.com/ser0632/p/5498228.html s = getenv("环境变量名"); 取得环境变量内容 putenv改变或增加环境变量 int putenv(const char * string); setenv(改变或增加环境变量) http://www.jb51.net/article/71940.htm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值