|
05 Jul
python获取linux系统内存、cpu、网络使用情况
做个程序需要用到系统的cpu、内存、网络的使用情况,百度之后发现目前使用python获取这些信息大多是调用系统命令(top、free等)。其实多linux命令也是读取/proc下的文件实现的,索性不如自己写一个。
一、计算cpu的利用率
要读取cpu的使用情况,首先要了解/proc/stat文件的内容,下图是/proc/stat文件的一个例子:

cpu、cpu0、cpu1……每行数字的意思相同,从左到右分别表示user、nice、system、idle、iowait、irq、softirq。根据系统的不同,输出的列数也会不同,比如ubuntu 12.04会输出10列数据,centos 6.4会输出9列数据,后边几列的含义不太清楚,每个系统都是输出至少7列。没一列的具体含义如下:
user:用户态的cpu时间(不包含nice值为负的进程所占用的cpu时间)
nice:nice值为负的进程所占用的cpu时间
system:内核态所占用的cpu时间
idle:cpu空闲时间
iowait:等待IO的时间
irq:系统中的硬中断时间
softirq:系统中的软中断时间
以上各值的单位都是jiffies,jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在这里我们把它当做单位时间就行。
intr行中包含的是自系统启动以来的终端信息,第一列表示中断的总此数,其后每个数对应某一类型的中断所发生的次数
ctxt行中包含了cpu切换上下文的次数
btime行中包含了系统运行的时间,以秒为单位
processes/total_forks行中包含了从系统启动开始所建立的任务个数
procs_running行中包含了目前正在运行的任务的个数
procs_blocked行中包含了目前被阻塞的任务的个数
由于计算cpu的利用率用不到太多的值,所以截图中并未包含/proc/stat文件的所有内容。
知道了/proc文件的内容之后就可以计算cpu的利用率了,具体方法是:先在t1时刻读取文件内容,获得此时cpu的运行情况,然后等待一段时间在t2时刻再次读取文件内容,获取cpu的运行情况,然后根据两个时刻的数据通过以下方式计算cpu的利用率:100 - (idle2 - idle1)*100/(total2 - total1),其中total = user + system + nice + idle + iowait + irq + softirq。python代码实现如下:
|
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
|
import
time
def
readCpuInfo():
f
= open('/proc/stat')
lines
= f.readlines();
f.close()
for
line in
lines:
line
= line.lstrip()
counters
= line.split()
if
len(counters) <
5:
continue
if
counters[0].startswith('cpu'):
break
total
= 0
for
i in
xrange(1,
len(counters)):
total
= total
+ long(counters[i])
idle
= long(counters[4])
return
{'total':total,
'idle':idle}
def
calcCpuUsage(counters1, counters2):
idle
= counters2['idle']
- counters1['idle']
total
= counters2['total']
- counters1['total']
return
100 -
(idle*100/total)
if
__name__ ==
'__main__':
counters1
= readCpuInfo()
time.sleep(0.1)
counters2
= readCpuInfo()
print
calcCpuUsage(counters1, counters2):
|
二、计算内存的利用率
计算内存的利用率需要读取的是/proc/meminfo文件,该文件的结构比较清晰,不需要额外的介绍,需要知道的是内存的使用总量为used = total - free - buffers - cached,python代码实现如下:

|
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
|
def
readMemInfo():
res
= {'total':0,
'free':0,
'buffers':0,
'cached':0}
f
= open('/proc/meminfo')
lines
= f.readlines()
f.close()
i
= 0
for
line in
lines:
if
i ==
4:
break
line
= line.lstrip()
memItem
= line.lower().split()
if
memItem[0]
==
'memtotal:':
res['total']
= long(memItem[1])
i
= i
+1
continue
elif
memItem[0]
==
'memfree:':
res['free']
= long(memItem[1])
i
= i
+1
continue
elif
memItem[0]
==
'buffers:':
res['buffers']
= long(memItem[1])
i
= i
+1
continue
elif
memItem[0]
==
'cached:':
res['cached']
= long(memItem[1])
i
= i
+1
continue
return
res
def
calcMemUsage(counters):
used
= counters['total']
- counters['free']
- counters['buffers']
- counters['cached']
total
= counters['total']
return
used*100/total
if
__name__ ==
'__main__':
counters
= readMemInfo()
print
calcMemUsage(counters)
|
三、获取网络的使用情况
获取网络使用情况需要读取的是/proc/net/dev文件,如下图所示,里边的内容也很清晰,不做过的的介绍,直接上python代码,取的是eth0的发送和收取的总字节数:

|
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
|
def
readNetInfo(dev):
f
= open('/proc/net/dev')
lines
= f.readlines()
f.close()
res
= {'in':0,
'out':0}
for
line in
lines:
if
line.lstrip().startswith(dev):
line
= line.replace(':',
' ')
items
= line.split()
res['in']
= long(items[1])
res['out']
= long(items[len(items)/2
+ 1])
return
res
if
__name__ ==
'__main__':
print
readNetInfo('eth0')
|
四、获取网卡的ip地址和主机的cpu个数
这两个函数是程序的其它地方需要用到,就顺便写下来:
|
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
|
import
time
import
socket
import
fcntl
import
struct
def
getIpAddress(dev):
s
= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
a
= s.fileno()
b
= 0x8915
c
= struct.pack('256s', dev[:15])
res
= fcntl.ioctl(a, b, c)[20:24]
return
socket.inet_ntoa(res)
def
getCpuCount():
f
= open('/proc/cpuinfo')
lines
= f.readlines()
f.close()
res
= 0
for
line in
lines:
line
= line.lower().lstrip()
if
line.startswith('processor'):
res
= res
+ 1
return
res
if
__name__ ==
'__main__':
print
getCpuCount()
print
getIpAddress('eth0')
|
|