python获取linux系统内存、cpu、网络使用情况

时间:2023-01-03 22:31:13
05 Jul

python获取linux系统内存、cpu、网络使用情况

做个程序需要用到系统的cpu、内存、网络的使用情况,百度之后发现目前使用python获取这些信息大多是调用系统命令(top、free等)。其实多linux命令也是读取/proc下的文件实现的,索性不如自己写一个。

一、计算cpu的利用率

要读取cpu的使用情况,首先要了解/proc/stat文件的内容,下图是/proc/stat文件的一个例子:

python获取linux系统内存、cpu、网络使用情况

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代码实现如下:

python获取linux系统内存、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
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的发送和收取的总字节数:

python获取linux系统内存、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
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):
        
             # for centos
        
             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' )