“Python系统信息监控”的版本间的差异

来自CloudWiki
跳转至: 导航搜索
 
(未显示4个用户的33个中间版本)
第1行: 第1行:
 
==概述==
 
==概述==
用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。
+
<p color="blue">用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。</p>
  
 
在Python中获取系统信息的另一个好办法是使用psutil这个第三方模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。
 
在Python中获取系统信息的另一个好办法是使用psutil这个第三方模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。
第6行: 第6行:
 
安装方法如下:
 
安装方法如下:
  
  pip install psutil
+
  pip3 install psutil
  
 
如果生产环境没有联网则可以先在外网使用pip下载,再移动至生产环境安装。为了方便显示语句运行结果,下面使用IPython解释器。在此啰嗦一下,IPython是学习Python的利器,是让Python显得友好十倍的外套,强烈建议读者使用IPython,
 
如果生产环境没有联网则可以先在外网使用pip下载,再移动至生产环境安装。为了方便显示语句运行结果,下面使用IPython解释器。在此啰嗦一下,IPython是学习Python的利器,是让Python显得友好十倍的外套,强烈建议读者使用IPython,
 
可通过以下命令安装IPython
 
可通过以下命令安装IPython
  
   pip install ipython。
+
   pip3 install ipython。
  
 
下面一一列举使用方法。
 
下面一一列举使用方法。
第24行: 第24行:
 
4</nowiki>
 
4</nowiki>
  
<nowiki>In [1]: import psutil
+
===统计CPU的用户/系统/空闲时间===
  
In [2]: psutil.cpu_times() #获取cpu占用时间的详细信息
+
<nowiki>>>> psutil.cpu_times()
Out[2]: scputimes(user=274971.40625, system=399154.53125, idle=1959806.1875, interrupt=13831.578125, dpc=5731.515625)
+
scputimes(user=192222.59374999997, system=147996.34375, idle=3147198.015625, interrupt=11456.46875, dpc=4403.546875)</nowiki>
  
In [3]: psutil.cpu_times(percpu=True) #获取每个cpu占用时间的详细信息
 
Out[3]:
 
[scputimes(user=69532.3125, system=121357.06250000006, idle=467653.01562499994, interrupt=6815.046875, dpc=3065.390625),
 
scputimes(user=55834.59375, system=84942.84375000006, idle=517764.23437499994, interrupt=3982.78125, dpc=1313.03125),
 
scputimes(user=81075.28125, system=110418.953125, idle=467047.375, interrupt=1964.03125, dpc=1013.953125),
 
scputimes(user=68573.21875, system=82476.46875, idle=507491.953125, interrupt=1070.84375, dpc=339.671875)]
 
  
In [4]: psutil.cpu_count()   #cpu逻辑数量
+
<nowiki>>>> psutil.cpu_times(percpu=True)
Out[4]: 4</nowiki>
+
[scputimes(user=30696.484375, system=27652.09375, idle=377724.46875, interrupt=7768.828125, dpc=3813.765625), scputimes(user=13698.046875, system=13368.046874999942, idle=409006.734375, interrupt=483.59375, dpc=96.59375), scputimes(user=31968.859374999996, system=20170.640625, idle=383933.328125, interrupt=517.78125, dpc=127.28125), scputimes(user=13582.359375, system=11269.468749999942, idle=411221.0, interrupt=380.75, dpc=35.828125), scputimes(user=32777.03125, system=22783.03124999994, idle=380512.75, interrupt=822.765625, dpc=154.84375), scputimes(user=17815.59375, system=13164.203125, idle=405093.03125, interrupt=448.78125, dpc=32.203125), scputimes(user=25047.562499999996, system=19983.265625, idle=391041.99999999994, interrupt=631.328125, dpc=105.15625), scputimes(user=26672.28125, system=19648.5625, idle=389751.984375, interrupt=405.265625, dpc=39.0625)]</nowiki>
  
<nowiki>In [5]: psutil.cpu_count(logical=False)
+
===获取CPU占用率===
Out[5]: 2
 
  
In [6]: psutil.cpu_percent()#CPU占用率
+
<nowiki>>>> psutil.cpu_percent()
Out[6]: 40.7
+
7.1
 +
>>> psutil.cpu_percent(percpu=True)
 +
[8.9, 3.0, 8.9, 4.3, 8.7, 4.8, 8.8, 9.0]</nowiki>
  
In [7]: psutil.cpu_percent(percpu=True) #每个CPU的占用率
+
实例:
Out[7]: [39.4, 32.8, 46.0, 43.3]</nowiki>
 
  
==监控内存信息==
+
<nowiki>import psutil
 +
for x in range(10):
 +
    s=psutil.cpu_percent(interval=1)
 +
    print("当前cput占比为:",s)</nowiki>
  
<nowiki>In [8]: psutil.virtual_memory()#查看物理内存
+
===应用:CPU监控函数===
Out[8]: svmem(total=17057337344, available=4142526464, percent=75.7, used=12914810880, free=4142526464)
+
<nowiki>
 
+
import psutil
In [9]: psutil.swap_memory()#查看虚拟内存
 
Out[9]: sswap(total=27257884672, used=12678332416, free=14579552256, percent=46.5, sin=0, sout=0)
 
  
 +
def cpu_info():    #----》函数名尽可能切合内容
 +
    cpu = psutil.cpu_percent(interval=1)
 +
    return cpu    #----》返回cpu,可以被调用,此return的结果就是调用的结果
  
 +
if __name__=="__main__": 
 +
    res=cpu_info()    #----》给调用结果赋值。可以省略,下同
 +
    print(res)
 
</nowiki>
 
</nowiki>
  
思考:内存的利用率应该怎样计算?
+
==监控内存信息==
 +
===查看物理内存===
  
==监控磁盘信息==
+
  <nowiki>>>> psutil.virtual_memory()
  <nowiki>In [9]: psutil.disk_partitions()
+
svmem(total=8278306816, available=954941440, percent=88.5, used=7323365376, free=954941440)</nowiki>
Out[9]:
 
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'),
 
sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'),
 
sdiskpart(device='F:\\', mountpoint='F:\\', fstype='', opts='cdrom')]</nowiki></nowiki>
 
  
 +
===查看交换内存===
 +
<nowiki>>>> psutil.swap_memory()
 +
sswap(total=20787396608, used=17976201216, free=2811195392, percent=86.5, sin=0, sout=0)</nowiki>
  
 +
实例:
  
==监控网络信息==
+
<nowiki>
 +
>>> mem = psutil.virtual_memory()
 +
>>> mem.total
 +
8278306816
 +
>>> mem.used
 +
7043653632
 +
>>> mem.free
 +
1234653184
 +
>>> type(mem.free)
 +
<class 'int'>
 +
>>> if mem.used/mem.total >0.8 :
 +
print("内存占用过高!")
 +
else:
 +
print("内存占比正常。")</nowiki>
  
<nowiki>In [10]:  psutil.net_io_counters()#获取网络读写字节的个数
 
Out[10]: snetio(bytes_sent=8445215479, bytes_recv=7761730094, packets_sent=5203357, packets_recv=10378093, errin=0, errout=0, dropin=0, dropout=0)
 
  
</nowiki>
+
思考:内存的利用率应该怎样计算?
 
 
思考:从中能获得什么信息 ?
 
  
 +
===应用:内存监控函数===
 
  <nowiki>
 
  <nowiki>
In [11]:  psutil.net_if_addrs() #获取网络接口信息
+
import psutil
Out[11]:
 
{'VPN - Driver': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-AC-AC-2C-4C-8C', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.252.233', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::68d0:7a05:cf58:fce9', netmask=None, broadcast=None, ptp=None)],
 
'以太网': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='50-7B-9D-99-AE-C6', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.247.20', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::2c1b:6dc0:feac:f714', netmask=None, broadcast=None, ptp=None)],
 
'本地连接* 3': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='08-D4-0C-40-C3-57', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.163.245', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::d16d:3604:8b75:a3f5', netmask=None, broadcast=None, ptp=None)],
 
'本地连接* 5': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='0A-D4-0C-40-C3-56', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.130.96', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::c9ad:1742:ec84:8260', netmask=None, broadcast=None, ptp=None)],
 
'VMware Network Adapter VMnet1': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-50-56-C0-00-01', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.189.71', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::4d68:1bd9:83f3:bd47', netmask=None, broadcast=None, ptp=None)],
 
'VMware Network Adapter VMnet8': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-50-56-C0-00-08', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='10.0.0.1', netmask='255.255.255.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::31a9:a276:a6ab:c4d1', netmask=None, broadcast=None, ptp=None)],
 
'以太网 2': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-FF-D3-C0-D1-56', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.110.136', netmask='255.255.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.137.1', netmask='255.255.255.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::e540:e9f9:4a4b:6e88', netmask=None, broadcast=None, ptp=None)],
 
'WLAN': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='08-D4-0C-40-C3-56', netmask=None, broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.1.102', netmask='255.255.255.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::10d4:4318:dfb8:9360', netmask=None, broadcast=None, ptp=None)],
 
'Loopback Pseudo-Interface 1': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),
 
  snicaddr(family=<AddressFamily.AF_INET6: 23>, address='::1', netmask=None, broadcast=None, ptp=None)]}</nowiki>
 
  
获取网络接口状态:
+
def mem_info():
 +
    mem = psutil.virtual_memory()  #---》通过ps模块输出内存情况
 +
   
 +
    info1={'mem_total':ch(mem[0]),'mem_free':ch(mem[1]), \
 +
          'mem_percent':mem[2],'mem_used':ch(mem[3])} \
 +
          #--》将内存情况放入一个字典,方便调用
 +
    return info1
  
<nowiki>In [13]: psutil.net_if_stats()
+
def ch(m):
Out[13]:
+
    m =m/1024 #转化为KB
{'以太网': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500),
+
    m =m/1024 #转化为MB
'VMware Network Adapter VMnet8': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
+
    m =m/1024 #转化为GB
'以太网 2': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
+
    m = round(m,2)
'VPN - Driver': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
+
    return str(m)+"GB"
'Loopback Pseudo-Interface 1': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1073, mtu=1500),
 
'WLAN': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=135, mtu=1500),
 
'本地连接* 5': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500)}</nowiki>
 
  
获取当前网络连接信息:
+
if __name__ == '__main__':
 +
    res2=mem_info()
 +
    print(res2)
 +
</nowiki>
  
<nowiki>In [14]: psutil.net_connections()
+
==监控磁盘信息==
Out[14]:
+
===查看磁盘分区===
[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=10000), raddr=(), status='LISTEN', pid=9532),
+
  <nowiki>>>> psutil.disk_partitions()
  sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=58020), raddr=addr(ip='206.189.32.61', port=443), status='ESTABLISHED', pid=10916),
+
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='E:\\', mountpoint='E:\\', fstype='exFAT', opts='rw,fixed')]</nowiki>
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=50557), raddr=addr(ip='40.90.189.152', port=443), status='ESTABLISHED', pid=4676),
 
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=52856), raddr=addr(ip='127.0.0.1', port=52857), status='ESTABLISHED', pid=9228),
 
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='::', port=5353), raddr=(), status='NONE', pid=2324),
 
。。。</nowiki>
 
  
==获取进程信息==
+
===磁盘利用率===
 +
磁盘利用率 要在参数上指定路径:
  
  <nowiki>#获取所有进程的pid :
+
  <nowiki>
In [13]: for pid in psutil.pids():
+
>>> psutil.disk_usage('C:\\')
    ...:    print(pid,end=',')
+
sdiskusage(total=107374178304, used=62052282368, free=45321895936, percent=57.8)
    ...:
+
>>> psutil.disk_usage('D:\\')
0,4,76,96,472,544,580,584,604,620,636,748,756,848,892,900,940,1028,1096,1152,1220,1300,1388,1480,1488,1504,1516,1548,1552,1612,1616,1644,1712,1744,1800,1916,1928,1944,1984,2028,2060,2164,2280,2288,2296,2340,2348,2404,2408,2444,2456,2476,2484,2524,2652,2664,2672,2760,2928,2944,2960,3244,3348,3372,3388,3416,3520,3544,3560,3572,3596,3608,3644,3676,3688,3700,3704,3724,3732,3764,3784,3796,3808,3864,3876,3896,3904,3912,3920,3928,3936,3944,3976,3992,4012,4028,4040,4052,4064,4076,4136,4172,4204,4244,4260,4372,4388,4408,4416,4424,4468,4492,4536,4620,4640,4652,4800,5112,5228,5236,5244,5264,5328,5412,5592,5712,6096,6512,6564,6572,6920,6932,7176,7276,7376,7500,7520,7620,7696,7968,8080,8184,8200,8400,8812,8840,8864,8888,9228,9584,9608,9656,9688,9752,9792,9832,10020,10184,10260,10428,10500,10612,10780,10796,10812,11068,11108,11152,11324,11344,11444,11880,12056,12116,12260,12312,12380,13380,13556,13892,14004,14544,15552,15564,16204,16388,17296,17944,18276,18444,19092,19172,19204,20824,20964,22556,22968,25300,26272,26936,27816,27932,28688,28952,30060,30180,31080,31104,34032,34048,35136,35744,37200,38292,40108,40460,40968,41484,43596,44236,44308,45552,46420,47496,47932,48192,48892,49004,49740,50008,50224,50520,50564,50860,51448,51728,54740,54872,55464,56368,59672,59896,60344,61744,62640,64024,64376,64580,64616,64640,65068,65500,66092,66268,67896,68908,69388,69508,70016,70284,70828,71500,72948,73120,73332,75048,75356,75884,75952,76284,77516,77572,78160,79152,79232,79836,79908,80592,80652,80708,81884,84016,84408,84468,84612,85244,85260,85672,85780,86176,86488,86712,86732,87804,87856,89396,
+
sdiskusage(total=403391377408, used=8059502592, free=395331874816, percent=2.0)
 +
</nowiki>
  
#查找qq程序的有关信息:
+
===磁盘IO数===
 +
查看总IO数:
 +
<nowiki>
 +
>>> psutil.disk_io_counters()
 +
sdiskio(read_count=12433626, write_count=19244946, read_bytes=606192376832, write_bytes=564326417920, read_time=5281, write_time=4576)
 +
>>> psutil.disk_io_counters().read_count
 +
12441178
 +
</nowiki>
  
In [14]: for proc in psutil.process_iter(attrs=['pid','name','username']):
+
查看每个磁盘IO数:
    ...:    if proc.info['name'].startswith('QQ'):
 
    ...:        print(proc.info)
 
    ...:
 
{'pid': 3976, 'name': 'QQProtect.exe', 'username': None}
 
{'pid': 11444, 'name': 'QQLiveService.exe', 'username': 'DESKTOP-LN2H42N\\thinkpad'}
 
{'pid': 47496, 'name': 'QQ.exe', 'username': 'DESKTOP-LN2H42N\\thinkpad'}
 
{'pid': 69388, 'name': 'QQExternal.exe', 'username': 'DESKTOP-LN2H42N\\thinkpad'}</nowiki>
 
  
前面使用psutil.process_iter获取了进程相关的信息,返回结果是一个可迭代对象,每个元素的info是一个字典,通过字典可以获取我们关心的信息。
+
<nowiki>
 +
>>> psutil.disk_io_counters(perdisk=True)
 +
{'PhysicalDrive0': sdiskio(read_count=12432860, write_count=19245033, read_bytes=606186330112, write_bytes=564327729664, read_time=5216, write_time=4576), 'PhysicalDrive1': sdiskio(read_count=797, write_count=28, read_bytes=6743040, write_bytes=638976, read_time=65, write_time=0)}
  
思考:如何获得每个元素 info的 详细信息 ?
+
>>> s=psutil.disk_io_counters(perdisk=True)
 +
>>> s['PhysicalDrive0']
 +
sdiskio(read_count=12440387, write_count=19248016, read_bytes=606235895808, write_bytes=564359970816, read_time=5216, write_time=4578)
 +
>>> s['PhysicalDrive0'].read_count
 +
12440387</nowiki>
  
获取进程的其他信息 还可以通过以下方式:
+
===应用:监控磁盘函数===
 +
<nowiki>
 +
def disk_info(disk_name):
 +
    disk = psutil.disk_usage(disk_name)  #---》(r'c:')为查看盘的固定写法
 +
    info2 = {'total': ch(disk[0]),\
 +
              'used': ch(disk[1]),\
 +
              'free': ch(disk[2]), \
 +
              'percent': disk[3]}  # ---》同样写入一个字典
 +
    return info2
 +
   
 +
res3=disk_info(r'c:')
 +
print(res3)</nowiki>
  
  <nowiki>In [18]: psutil.Process(10848).cpu_times()#获取cpu占用
+
==监控网络信息==
Out[18]: pcputimes(user=1103.40625, system=462.203125, children_user=0.0, children_system=0.0)
+
===获得本机IP===
 +
  <nowiki>>>> import socket
 +
>>> hostname = socket.gethostname()
 +
>>> hostname
 +
'LAPTOP-28C3GCM7'
 +
>>> socket.gethostbyname(hostname)
 +
'192.168.1.104'</nowiki>
  
In [19]: psutil.Process(10848).memory_info()#获取内存占用,rss就是实际占用的内存
+
===获取网络读写字节个数===
Out[19]: pmem(rss=403660800, vms=533426176, num_page_faults=22055661, peak_wset=541741056, wset=403660800, peak_paged_pool=1336168, paged_pool=1140336, peak_nonpaged_pool=363148, nonpaged_pool=234576, pagefile=533426176, peak_pagefile=563355648, private=533426176)
 
  
In [20]: psutil.Process(10848).num_threads()#获取线程数
+
<nowiki>psutil.net_io_counters()#获取网络读写字节的个数
Out[20]: 96
+
snetio(bytes_sent=8445215479, bytes_recv=7761730094, packets_sent=5203357, packets_recv=10378093, errin=0, errout=0, dropin=0, dropout=0)
 +
</nowiki>
  
In [21]: psutil.Process(10848).memory_percent()#获取内存占比
+
思考:从中能获得什么信息 ?
Out[21]: 2.233989187849646</nowiki>
 
  
==其他有用信息==
+
===获取网络接口信息===
按名称查找有关信息:
+
<nowiki>>>> psutil.net_if_addrs()
 +
{'本地连接* 1': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='E8-6F-38-26-0F-C9', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.77.128', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::f05e:828a:d017:4d80', netmask=None, broadcast=None, ptp=None)],</nowiki>
  
  <nowiki>import psutil
+
===获取网络接口状态===
 +
  <nowiki>>>> psutil.net_if_stats()
 +
{'蓝牙网络连接': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=3, mtu=1500), '以太网': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500), 'Loopback Pseudo-Interface 1': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1073, mtu=1500), 'WLAN': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=300, mtu=1500), '本地连接* 1': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500), '本地连接* 2': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500)}
 +
>>> s=psutil.net_if_stats()
 +
>>> s['以太网'].isup
 +
True</nowiki>
  
def find_procs_by_name(name):
+
思考:编写程序,查看本机哪个网络接口是开启的 ?
    "Return a list of processes matching 'name'."
 
    ls = []
 
    for p in psutil.process_iter(attrs=['name']):
 
        if p.info['name'] == name:
 
            ls.append(p)
 
    return ls
 
  
</nowiki>
 
  
<nowiki>def find_procs_by_name(name):
+
===获取当前网络连接信息===
    "Return a list of processes matching 'name'."
 
    ls = []
 
    for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
 
        if name == p.info['name'] or \
 
                p.info['exe'] and os.path.basename(p.info['exe']) == name or \
 
                p.info['cmdline'] and p.info['cmdline'][0] == name:
 
            ls.append(p)
 
    return ls</nowiki>
 
  
 +
<nowiki>psutil.net_connections()
 +
Out[14]:
 +
[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=10000), raddr=(), status='LISTEN', pid=9532),
 +
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=58020), raddr=addr(ip='206.189.32.61', port=443), status='ESTABLISHED', pid=10916),
 +
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=50557), raddr=addr(ip='40.90.189.152', port=443), status='ESTABLISHED', pid=4676),
 +
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=52856), raddr=addr(ip='127.0.0.1', port=52857), status='ESTABLISHED', pid=9228),
 +
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='::', port=5353), raddr=(), status='NONE', pid=2324),
 +
。。。</nowiki>
  
杀掉子进程:
+
===应用:编写网络监控函数===
 +
  <nowiki>
 +
def net_info():
 +
    net = psutil.net_io_counters()
 +
    netinfo={'bytes_sent':ch(net[0]),\
 +
            'bytes_recv':ch(net[1]),\
 +
            'packets_sent':ch(net[2]),\
 +
            'packets_recv':ch(net[3])
 +
        }
 +
    return netinfo</nowiki>
  
  <nowiki>import psutil
+
==应用:用python编写系统运行报告==
 +
  <nowiki>
 +
import psutil
 +
print("CPU的个数:",psutil.cpu_count())
 +
print("CPU的物理总数是:",psutil.cpu_count(logical=False))
 +
print("CPU的空闲时间是:",psutil.cpu_times())
 +
print("CPU的全系统空闲时间是:",psutil.cpu_times(percpu=True))
 +
print("CPU的占用率是:",psutil.cpu_percent())
 +
print("CPU的所有占用率是:",psutil.cpu_percent(percpu=True))
 +
for x in range(10):
 +
    s=psutil.cpu_percent(interval=1)
 +
    print("当前cput占比为:",s)
 +
print("物理内存是:",psutil.virtual_memory())
 +
print("交换内存是:",psutil.swap_memory())
 +
print("查看磁盘分区:",psutil.disk_partitions())
 +
print("查看磁盘利用率:",psutil.disk_usage('c:\\'))
 +
print("查看磁盘io总数:",psutil.disk_io_counters())
 +
print(psutil.disk_io_counters().read_count)
 +
print("查看每个磁盘的io数",psutil.disk_io_counters(perdisk=True))
  
def reap_children(timeout=3):
 
    "Tries hard to terminate and ultimately kill all the children of this process."
 
    def on_terminate(proc):
 
        print("process {} terminated with exit code {}".format(proc, proc.returncode))
 
  
    procs = psutil.Process().children()
+
#获取本机ip
    # send SIGTERM
+
import socket
    for p in procs:
+
hostname = socket.gethostname()
        p.terminate()
+
print("你的主机名是",hostname)
    gone, alive = psutil.wait_procs(procs, timeout=timeout, callback=on_terminate)
+
print("你的主机ip是",socket.gethostbyname(hostname))
    if alive:
+
print("网络独写字节个数",psutil.net_io_counters())
        # send SIGKILL
+
print("网络接口信息",psutil.net_if_addrs())
        for p in alive:
+
print("网络接口状态",psutil.net_if_stats())</nowiki>
            print("process {} survived SIGTERM; trying SIGKILL" % p)
 
            p.kill()
 
        gone, alive = psutil.wait_procs(alive, timeout=timeout, callback=on_terminate)
 
        if alive:
 
            # give up
 
            for p in alive:
 
                print("process {} survived SIGKILL; giving up" % p)</nowiki>
 

2023年4月10日 (一) 03:04的最新版本

概述

用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。

在Python中获取系统信息的另一个好办法是使用psutil这个第三方模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。

安装方法如下:

pip3 install psutil

如果生产环境没有联网则可以先在外网使用pip下载,再移动至生产环境安装。为了方便显示语句运行结果,下面使用IPython解释器。在此啰嗦一下,IPython是学习Python的利器,是让Python显得友好十倍的外套,强烈建议读者使用IPython, 可通过以下命令安装IPython

 pip3 install ipython。

下面一一列举使用方法。

获取CPU信息

获取CPU个数

>>> import psutil
>>> psutil.cpu_count()
8
>>> psutil.cpu_count(logical=False)
4

统计CPU的用户/系统/空闲时间

>>> psutil.cpu_times()
scputimes(user=192222.59374999997, system=147996.34375, idle=3147198.015625, interrupt=11456.46875, dpc=4403.546875)


>>> psutil.cpu_times(percpu=True)
[scputimes(user=30696.484375, system=27652.09375, idle=377724.46875, interrupt=7768.828125, dpc=3813.765625), scputimes(user=13698.046875, system=13368.046874999942, idle=409006.734375, interrupt=483.59375, dpc=96.59375), scputimes(user=31968.859374999996, system=20170.640625, idle=383933.328125, interrupt=517.78125, dpc=127.28125), scputimes(user=13582.359375, system=11269.468749999942, idle=411221.0, interrupt=380.75, dpc=35.828125), scputimes(user=32777.03125, system=22783.03124999994, idle=380512.75, interrupt=822.765625, dpc=154.84375), scputimes(user=17815.59375, system=13164.203125, idle=405093.03125, interrupt=448.78125, dpc=32.203125), scputimes(user=25047.562499999996, system=19983.265625, idle=391041.99999999994, interrupt=631.328125, dpc=105.15625), scputimes(user=26672.28125, system=19648.5625, idle=389751.984375, interrupt=405.265625, dpc=39.0625)]

获取CPU占用率

>>> psutil.cpu_percent()
7.1
>>> psutil.cpu_percent(percpu=True)
[8.9, 3.0, 8.9, 4.3, 8.7, 4.8, 8.8, 9.0]

实例:

import psutil
for x in range(10):
    s=psutil.cpu_percent(interval=1)
    print("当前cput占比为:",s)

应用:CPU监控函数

import psutil

def cpu_info():    #----》函数名尽可能切合内容
     cpu = psutil.cpu_percent(interval=1)
     return cpu     #----》返回cpu,可以被调用,此return的结果就是调用的结果

if __name__=="__main__":   
    res=cpu_info()     #----》给调用结果赋值。可以省略,下同
    print(res)

监控内存信息

查看物理内存

>>> psutil.virtual_memory()
svmem(total=8278306816, available=954941440, percent=88.5, used=7323365376, free=954941440)

查看交换内存

>>> psutil.swap_memory()
sswap(total=20787396608, used=17976201216, free=2811195392, percent=86.5, sin=0, sout=0)

实例:

>>> mem = psutil.virtual_memory()
>>> mem.total
8278306816
>>> mem.used
7043653632
>>> mem.free
1234653184
>>> type(mem.free)
<class 'int'>
>>> if mem.used/mem.total >0.8 :
	print("内存占用过高!")
else:
	print("内存占比正常。")


思考:内存的利用率应该怎样计算?

应用:内存监控函数

import psutil

def mem_info():
    mem = psutil.virtual_memory()   #---》通过ps模块输出内存情况
    
    info1={'mem_total':ch(mem[0]),'mem_free':ch(mem[1]), \
           'mem_percent':mem[2],'mem_used':ch(mem[3])} \
           #--》将内存情况放入一个字典,方便调用
    return info1

def ch(m):
    m =m/1024 #转化为KB
    m =m/1024 #转化为MB
    m =m/1024 #转化为GB
    m = round(m,2)
    return str(m)+"GB"

if __name__ == '__main__':
    res2=mem_info()
    print(res2)

监控磁盘信息

查看磁盘分区

>>> psutil.disk_partitions()
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='E:\\', mountpoint='E:\\', fstype='exFAT', opts='rw,fixed')]

磁盘利用率

磁盘利用率 要在参数上指定路径:

>>> psutil.disk_usage('C:\\')
sdiskusage(total=107374178304, used=62052282368, free=45321895936, percent=57.8)
>>> psutil.disk_usage('D:\\')
sdiskusage(total=403391377408, used=8059502592, free=395331874816, percent=2.0)

磁盘IO数

查看总IO数:

>>> psutil.disk_io_counters()
sdiskio(read_count=12433626, write_count=19244946, read_bytes=606192376832, write_bytes=564326417920, read_time=5281, write_time=4576)
>>> psutil.disk_io_counters().read_count
12441178

查看每个磁盘IO数:

>>> psutil.disk_io_counters(perdisk=True)
{'PhysicalDrive0': sdiskio(read_count=12432860, write_count=19245033, read_bytes=606186330112, write_bytes=564327729664, read_time=5216, write_time=4576), 'PhysicalDrive1': sdiskio(read_count=797, write_count=28, read_bytes=6743040, write_bytes=638976, read_time=65, write_time=0)}

>>> s=psutil.disk_io_counters(perdisk=True)
>>> s['PhysicalDrive0']
sdiskio(read_count=12440387, write_count=19248016, read_bytes=606235895808, write_bytes=564359970816, read_time=5216, write_time=4578)
>>> s['PhysicalDrive0'].read_count
12440387

应用:监控磁盘函数

def disk_info(disk_name):
     disk = psutil.disk_usage(disk_name)  #---》(r'c:')为查看盘的固定写法
     info2 = {'total': ch(disk[0]),\
              'used': ch(disk[1]),\
              'free': ch(disk[2]), \
              'percent': disk[3]}  # ---》同样写入一个字典
     return info2
    
res3=disk_info(r'c:')
print(res3)

监控网络信息

获得本机IP

>>> import socket
>>> hostname = socket.gethostname()
>>> hostname
'LAPTOP-28C3GCM7'
>>> socket.gethostbyname(hostname)
'192.168.1.104'

获取网络读写字节个数

psutil.net_io_counters()#获取网络读写字节的个数
snetio(bytes_sent=8445215479, bytes_recv=7761730094, packets_sent=5203357, packets_recv=10378093, errin=0, errout=0, dropin=0, dropout=0)
 

思考:从中能获得什么信息 ?

获取网络接口信息

>>> psutil.net_if_addrs()
{'本地连接* 1': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='E8-6F-38-26-0F-C9', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.77.128', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::f05e:828a:d017:4d80', netmask=None, broadcast=None, ptp=None)],

获取网络接口状态

>>> psutil.net_if_stats()
{'蓝牙网络连接': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=3, mtu=1500), '以太网': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500), 'Loopback Pseudo-Interface 1': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1073, mtu=1500), 'WLAN': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=300, mtu=1500), '本地连接* 1': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500), '本地连接* 2': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500)}
>>> s=psutil.net_if_stats()
>>> s['以太网'].isup
True

思考:编写程序,查看本机哪个网络接口是开启的 ?


获取当前网络连接信息

psutil.net_connections()
Out[14]:
[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=10000), raddr=(), status='LISTEN', pid=9532),
 sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=58020), raddr=addr(ip='206.189.32.61', port=443), status='ESTABLISHED', pid=10916),
 sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.1.104', port=50557), raddr=addr(ip='40.90.189.152', port=443), status='ESTABLISHED', pid=4676),
 sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=52856), raddr=addr(ip='127.0.0.1', port=52857), status='ESTABLISHED', pid=9228),
 sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='::', port=5353), raddr=(), status='NONE', pid=2324),
。。。

应用:编写网络监控函数

 
def net_info():
    net = psutil.net_io_counters()
    netinfo={'bytes_sent':ch(net[0]),\
             'bytes_recv':ch(net[1]),\
             'packets_sent':ch(net[2]),\
             'packets_recv':ch(net[3])
        }
    return netinfo

应用:用python编写系统运行报告

import psutil
print("CPU的个数:",psutil.cpu_count())
print("CPU的物理总数是:",psutil.cpu_count(logical=False))
print("CPU的空闲时间是:",psutil.cpu_times())
print("CPU的全系统空闲时间是:",psutil.cpu_times(percpu=True))
print("CPU的占用率是:",psutil.cpu_percent())
print("CPU的所有占用率是:",psutil.cpu_percent(percpu=True))
for x in range(10):
    s=psutil.cpu_percent(interval=1)
    print("当前cput占比为:",s)
print("物理内存是:",psutil.virtual_memory())
print("交换内存是:",psutil.swap_memory())
print("查看磁盘分区:",psutil.disk_partitions())
print("查看磁盘利用率:",psutil.disk_usage('c:\\'))
print("查看磁盘io总数:",psutil.disk_io_counters())
print(psutil.disk_io_counters().read_count)
print("查看每个磁盘的io数",psutil.disk_io_counters(perdisk=True))


#获取本机ip
import socket
hostname = socket.gethostname()
print("你的主机名是",hostname)
print("你的主机ip是",socket.gethostbyname(hostname))
print("网络独写字节个数",psutil.net_io_counters())
print("网络接口信息",psutil.net_if_addrs())
print("网络接口状态",psutil.net_if_stats())