python脚本通过进程或进程名监控内存使用情况

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

通过python来实现对跨平台的应用程序监控,真实内存和虚拟内存还有 CPU,网络等使用情况。

一、psutil是什么?

psutil是一个开源切跨平台的库,其提供了便利的函数用来获取才做系统的信息,比如CPU,内存,磁盘,网络等。此外,psutil还可以用来进行进程管理,包括判断进程是否存在、获取进程列表、获取进程详细信息等。而且psutil还提供了许多命令行工具提供的功能,包括:ps,top,lsof,netstat,ifconfig, who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap。

psutil是一个跨平台的库,在官方网站上查到其支持如下操作系统。
Linux
Windows
OSX
FreeBSD
OpenBSD
NetBSD
Sun Solaris
AIX

二、相关方法介绍

1.cpu

函数描述
psutil.cpu_count()cpu_count(,[logical]):默认返回逻辑CPU的个数,当设置logical的参数为False时,返回物理CPU的个数。
psutil.cpu_percent()cpu_percent(,[percpu],[interval]):返回CPU的利用率,percpu为True时显示所有物理核心的利用率,interval不为0时,则阻塞时显示interval执行的时间内的平均利用率
psutil.cpu_times()cpu_times(,[percpu]):以命名元组(namedtuple)的形式返回cpu的时间花费,percpu=True表示获取每个CPU的时间花费
psutil.cpu_times_percent()cpu_times_percent(,[percpu]):功能和cpu_times大致相同,看字面意思就能知道,该函数返回的是耗时比例。
psutil.cpu_stats()cpu_stats()以命名元组的形式返回CPU的统计信息,包括上下文切换,中断,软中断和系统调用次数。
psutil.cpu_freq()cpu_freq([percpu]):返回cpu频率

2.memory_内存

函数描述
virtual_memory()获取系统内存的使用情况,以命名元组的形式返回内存使用情况,包括总内存,可用内存,内存利用率,buffer和cache等。单位为字节。
swap_memory()获取系统交换内存的统计信息,以命名元组的形式返回swap/memory使用情况,包含swap中页的换入和换出。

3.disk_磁盘

函数描述
psutil.disk_io_counters()disk_io_counters([perdisk]):以命名元组的形式返回磁盘io统计信息(汇总的),包括读、写的次数,读、写的字节数等。当perdisk的值为True,则分别列出单个磁盘的统计信息(字典:key为磁盘名称,value为统计的namedtuple)。
psutil.disk_partitions()disk_partitions([all=False]):以命名元组的形式返回所有已挂载的磁盘,包含磁盘名称,挂载点,文件系统类型等信息。当all等于True时,返回包含/proc等特殊文件系统的挂载信息
psutil.disk_usage()disk_usage(path):以命名元组的形式返回path所在磁盘的使用情况,包括磁盘的容量、已经使用的磁盘容量、磁盘的空间利用率等。

4.net_网络

函数详情
psutil.net_io_counter([pernic])以命名元组的形式返回当前系统中每块网卡的网络io统计信息,包括收发字节数,收发包的数量、出错的情况和删包情况。当pernic为True时,则列出所有网卡的统计信息。
psutil.net_connections([kind])以列表的形式返回每个网络连接的详细信息(namedtuple)。命名元组包含fd, family, type, laddr, raddr, status, pid等信息。kind表示过滤的连接类型,支持的值如下:(默认为inet)
psutil.net_if_addrs()以字典的形式返回网卡的配置信息,包括IP地址和mac地址、子网掩码和广播地址。
psutil.net_if_stats()返回网卡的详细信息,包括是否启动、通信类型、传输速度与mtu。

5.pid_进程管理

psutil还提供了作为进程管理的功能函数,包括获取进程列表,判断是否存在。

函数描述
psutil.pids()以列表的形式返回当前正在运行的进程
psutil.pid_exists(1)判断给点定的pid是否存在
psutil.process_iter()迭代当前正在运行的进程,返回的是每个进程的Process对象
psutil.Process( pid )对进程进行封装,可以使用该类的方法获取进行的详细信息,或者给进程发送信号。传入参数为pid

函数 描述
psutil.pids() 以列表的形式返回当前正在运行的进程
psutil.pid_exists(1) 判断给点定的pid是否存在
psutil.process_iter() 迭代当前正在运行的进程,返回的是每个进程的Process对象
psutil.Process( pid ) 对进程进行封装,可以使用该类的方法获取进行的详细信息,或者给进程发送信号。传入参数为pid

psutil.Process( pid )获取进程相关信息的方法:

name():获取进程的名称
cmdline():获取启动进程的命令行参数
create_time():获取进程的创建时间(时间戳格式)
num_fds():进程打开的文件个数
num_threads():进程的子进程个数
is_running():判断进程是否正在运行
send_signal():给进程发送信号,类似与os.kill等
kill():发送SIGKILL信号结束进程
terminate():发送SIGTEAM信号结束进程

更多信息参考https://pypi.org/project/psutil/

6.sensors_传感器

函数描述
psutil.sensors_temperatures(fahrenheit=False)返回硬件的温度
psutil.sensors_fans()返回硬件风扇速度
psutil.sensors_battery()返回电池状态

总结

该三方库有些字段获取和linux并不一致,如lsof会展开所有的fd数,但是windows中又没有该命令,故psutil中的num_fds统计的是windows和 linux共同有的,要统计不同平台下的fd,需要具体根据设备支持的命令修改。
如果您查看psutil的源代码,您会发现num_fds()只是在计算/proc//fd中的“文件”:

#_pslinux.py
@wrap_exceptions
def num_fds(self):
    return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))

lsof可能做更多的工作(例如,它在process_proc_map()中分析内存映射):https://github.com/lsof-org/lsof/blob/56d79ed56d14825f234783a867d6bd5676729b32/dialects/linux/dproc.c

文末附代码

import sys
import time
import os
import csv
import psutil

if len(sys.argv)!=2:
	print(len(sys.argv))
	sys.exit(-1)

processID = int(sys.argv[1]) #pid
p = psutil.Process(processID)
elaspeTime = 5 #采样间隔
loops = 1; #循环次数

outPutFile = 'performance_%s.csv'%(processID)
fp = open(outPutFile,'w')
fp.write('%s,%s,%s,%s,%s,%s,%s,%s\n'%('Time','PID','Name','CPU(%)','RSS(B)','VMS(B)','Threads','Handles','Fds:'))

while(True):
    try:
        timestr =time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
        tpname = p.name()
        tpid = processID
        tHans = len(p.open_files())
        tThrds = len(p.threads())
        tcpuPer = p.cpu_percent(interval=1)
        tRss = p.memory_info()[0]
        #fds = p.num_fds() #只是打开的文件数,并非真正全部fd
        #of = p.open_files()
        #print(of)
        fds = os.popen('lsof -p %s |wc -l'%(processID)).read().replace('\n', '').replace('\r', '')
        #print(val)
        tVms = p.memory_info()[1]
        fp.write('%s,%s,%s,%s,%s,%s,%s,%s,%s\n'%(timestr,tpid,tpname,tcpuPer,tRss,tVms,tThrds,tHans,fds))
        printStr = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s'%(timestr[-8:-3],tpid,tpname,tcpuPer,tRss,tVms,tThrds,tHans,fds)
		
        print (printStr)
        loops =  loops + 1
        time.sleep(elaspeTime)
    except Exception as e:
        for prr in psutil.process_iter():
            try:
                print ("%s%s%s" %(prr.name().strip(),' '*(30-len(prr.name().strip())),prr.pid))
            except:
                pass
        break

print ("The result file: %s"%(os.path.join(os.getcwd(),outPutFile)))
fp.close()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值