Python3-22/456 psutil获取进程和系统信息

本文介绍了Python的psutil模块,它用于获取操作系统及硬件信息,包括CPU负载、内存使用、磁盘I/O、网络状态等。通过简单代码实现类似于Linux系统的监控命令,适用于跨平台的系统运维和脚本编写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

psutil=process and system utilites,是Python的一个第三方模块,通过一两行代码实现获取操作系统以及硬件相关的信息,如:CPU、磁盘、内存、内存、用户进程、电池、风扇等信息,支持Linux/Uinx/OSX/Windows跨平台使用,是系统运维管理员和运维人员不可不知的Python模块!常用于使用Python来编写脚本来简化日常的运维工作,如在Linux下,有许多的系统命令可以让我们时刻监控系统运行的状态,如ps、free、top、iostat、vmstat、sar等命令从而获取系统信息,以下是psutil模块实现前述命令相等的作用

import datetime
import psutil

'''
CPU(load)
MEM
SWAP(Linux)
DISK
DISK(IO)
NET
'''

def bootinfo():
    print("系统开机信息:")
    boot_time = psutil.boot_time()
    boot_time_2human = datetime.datetime.fromtimestamp(boot_time).strftime("%Y-%m-%d %H:%M:%S")
    print("系统开机时间是:%s" % boot_time_2human)

def loadavg():
    print("系统平均负载:")
    load_avg = psutil.getloadavg()
    print("系统平均负载大小: 1分钟:%s 5分钟:%s 15分钟:%s " % load_avg)

def memoryissue():
    print("内存使用信息:")
    mem = psutil.virtual_memory()
    memtotal = round(mem.total / 1024 / 1024, 2)  # round函数保留两位小数
    memused = round(mem.used / 1024 / 1024, 2)
    mempercent = str(round(mem.used / mem.total * 100, 2)) + '%'
    print("内存使用大小是:%s MB" % memused, end='\n')
    print("内存总大小是:%s MB" % memtotal, end='\n')
    print("内存使用率是:%s" % mempercent, end='\n')

def swapissue():
    print("SWAP使用信息:")
    swapinfo = psutil.swap_memory()
    swapinfo_total = round(swapinfo.total / 1024 / 1024, 2)
    swapinfo_used = round(swapinfo.used / 1024 / 1024, 2)
    swapinfo_percent = str(round(swapinfo_used / swapinfo_total * 100, 2)) + '%'
    print("SWAP总大小: %s" % swapinfo_total, end='\n')
    print("SWAP已使用大小:%s" % swapinfo_used)
    print("SWAP使用率: %s" % swapinfo_percent)

def diskissue(diskname):
    print("磁盘信息:")
    disk = psutil.disk_partitions()
    disuse = psutil.disk_usage(diskname)
    # disuse = psutil.disk_usage("D:\\")
    diskused = round(disuse.used / 1024 / 1024 / 1024, 2)
    disktotal = round(disuse.total / 1024 / 1024 / 1024, 2)
    diskpercent = str(round(diskused / disktotal * 100, 2)) + '%'
    print("硬盘使用大小是:%s GB" % diskused, end='\n')
    print("硬盘总大小是:%s GB" % disktotal, end='\n')
    print("硬盘使用率是:%s" % diskpercent, end='\n')

def ioissue():
    print("磁盘I/O信息:")
    # io_counter = psutil.disk_io_counters()
    io_counter = psutil.disk_io_counters(perdisk=True)  ##获取单个分区的IO和读写信息
    # print("磁盘读IO数: %s,磁盘写IO数据:%s,磁盘读IO字节大小:%s, 磁盘写IO字节大小:%s, 磁盘读时间:%s, 磁盘写时间: %s" %io_counter )
    print(io_counter)

def cpuissue():
    print("CPU信息:")
    cpu_logical_count = psutil.cpu_count()
    cpu_physical_count = psutil.cpu_count(logical=False)
    cpu_percent = psutil.cpu_percent(interval=None, percpu=True)
    cpu_user_times = round(psutil.cpu_times().user, 2)
    # cpu_iowait_times = round(psutil.cpu_times().iowait, 2)
    print("CPU的逻辑个数:%s" % cpu_logical_count)
    print("CPU的物理个数:%s" % cpu_physical_count)
    print("每个CPU使用率:%s" % cpu_percent)
    print("用户的CPU时间比:%s" % cpu_user_times)
    # print("iowait的CPU时间比:%s" % cpu_iowait_times)

def netissue():
    net = psutil.net_io_counters()
    bytes_sent = '{0:.2f} MB'.format(net.bytes_sent / 1024 / 1024)
    bytes_recv = '{0:.2f} MB'.format(net.bytes_recv / 1024 / 1024)
    print("网卡接受流量:%s, 网卡发送流量是:%s" % (bytes_recv, bytes_sent), end='\n')


print('#' * 50)
memoryissue()
print('#' * 50)
swapissue()
print('#' * 50)
diskissue(r'C:\\')
print('#' * 50)
cpuissue()
print('#' * 50)
netissue()
# print('#' * 50)
# loadavg()
print('#' * 50)
bootinfo()
print('#' * 50)
ioissue()

import uiautomator2 as u2 import time import re import logging import threading from adbutils import adb # 配置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # 浏览器包名列表 BROWSER_PACKAGES = [ 'com.android.chrome','com.google.android.apps.messaging' ] class CPUMonitor: def __init__(self, device): self.device = device self.prev_total = None self.prev_idle = None self.prev_pid_stats = {} def get_system_cpu_usage(self): """获取系统级CPU使用率(基于/proc/stat)""" try: # 读取/proc/stat获取整机CPU数据 output = self.device.shell("cat /proc/stat | grep '^cpu '") parts = output.output.split() values = [int(x) for x in parts[1:8]] # 取前7个字段 # 计算总时间空闲时间 total_time = sum(values) idle_time = values[3] + values[4] # idle + iowait # 首次采样无比较基准 if self.prev_total is None or self.prev_idle is None: self.prev_total = total_time self.prev_idle = idle_time time.sleep(1) return self.get_system_cpu_usage() # 计算增量 total_delta = total_time - self.prev_total idle_delta = idle_time - self.prev_idle # 更新历史值 self.prev_total = total_time self.prev_idle = idle_time # 计算使用率 if total_delta == 0: return 0.0 return 100.0 * (total_delta - idle_delta) / total_delta except Exception as e: logging.error(f"获取系统CPU失败: {str(e)}") return 0.0 def get_process_cpu_usage(self, package_name): """获取指定包名的进程级CPU使用率""" try: # 获取所有相关PID pids = self._get_package_pids(package_name) if not pids: return 0.0 # 获取当前进程统计 current_stats = {} for pid in pids: stat = self._get_pid_stat(pid) if stat: current_stats[pid] = stat # 首次采样 if not self.prev_pid_stats.get(package_name): self.prev_pid_stats[package_name] = current_stats time.sleep(1) return self.get_process_cpu_usage(package_name) # 计算增量 prev_stats = self.prev_pid_stats[package_name] total_delta = 0 valid_pids = 0 for pid, curr in current_stats.items(): if pid in prev_stats: prev = prev_stats[pid] # 计算进程CPU时间增量 (utime + stime) process_delta = (curr['utime'] + curr['stime']) - \ (prev['utime'] + prev['stime']) total_delta += process_delta valid_pids += 1 # 更新历史数据 self.prev_pid_stats[package_name] = current_stats # 获取系统级CPU时间增量 system_output = self.device.shell("cat /proc/stat | grep '^cpu '").output system_parts = system_output.split() system_values = [int(x) for x in system_parts[1:8]] system_total = sum(system_values) if self.prev_total is None: self.prev_total = system_total return 0.0 system_delta = system_total - self.prev_total # 计算使用率百分比 if system_delta > 0 and valid_pids > 0: return 100.0 * total_delta / system_delta return 0.0 except Exception as e: logging.error(f"获取进程CPU失败[{package_name}]: {str(e)}") return 0.0 def _get_package_pids(self, package_name): """获取包名的所有进程ID""" try: output = self.device.shell(f"pgrep -f {package_name}").output return [pid.strip() for pid in output.splitlines() if pid.strip()] except: return [] def _get_pid_stat(self, pid): """获取指定PID的/proc/stat数据""" try: output = self.device.shell(f"cat /proc/{pid}/stat").output parts = output.split() # 解析关键字段 (utime=14, stime=15 从1开始计数) return { 'utime': int(parts[13]), 'stime': int(parts[14]) } except: return None def reduce_cpu_load(device): """降低设备CPU负载的优化方案""" try: # 更彻底的进程清理 device.shell("am kill-all") # 限制后台进程 device.shell("settings put global background_process_limit 3") # 清除缓存 device.shell("sync && echo 3 > /proc/sys/vm/drop_caches") logging.info("已执行深度CPU降载操作") except Exception as e: logging.error(f"降载操作出错: {str(e)}") def monitor_device(device_serial, max_cpu=80.0): """监控单个设备的CPU使用率(高精度版)""" try: device = u2.connect(device_serial) monitor = CPUMonitor(device) logging.info(f"开始高精度监控设备: {device_serial}") while True: try: # 获取系统级CPU使用率 total_cpu = monitor.get_system_cpu_usage() logging.info(f"整机CPU使用率: {total_cpu:.2f}%") # # 获取浏览器总CPU使用率 # browser_cpu = 0.0 # browser_details = {} apk_details = {} for package in BROWSER_PACKAGES: cpu_val = monitor.get_process_cpu_usage(package) # browser_details[package] = cpu_val # browser_cpu += cpu_val apk_details[package] = cpu_val logging.info(f"{package}详情: {cpu_val:.2f}%") logging.info("详情: " + ", ".join([f"{pkg}: {val:.2f}%" for pkg, val in apk_details.items()])) time.sleep(0.5) # logging.info("浏览器CPU详情: " + # ", ".join([f"{pkg}: {val:.2f}%" for pkg, val in browser_details.items()])) # logging.info(f"浏览器总CPU使用率: {browser_cpu:.2f}%") # # 监控逻辑 # if total_cpu > max_cpu and browser_cpu > total_cpu * 0.4: # logging.warning(f"设备 {device_serial} CPU超过阈值({max_cpu}%),浏览器占用过高,执行降负载操作") # reduce_cpu_load(device) time.sleep(5) except Exception as e: logging.error(f"监控循环出错: {str(e)}") time.sleep(10) except Exception as e: logging.error(f"设备连接失败: {device_serial}, 错误: {str(e)}") def main(): """主函数:监控所有连接的Android设备""" devices = [d.serial for d in adb.device_list()] if not devices: logging.warning("未找到连接的Android设备") return logging.info(f"找到 {len(devices)} 台设备: {', '.join(devices)}") for device_serial in devices: thread = threading.Thread(target=monitor_device, args=(device_serial,)) thread.daemon = True thread.start() # 保持主线程运行 while True: time.sleep(1) if __name__ == "__main__": try: main() except KeyboardInterrupt: logging.info("\n监控已停止") 把logging.info输出的每个包的cpu占有率值进行汇总,每个包输出10次后,结束测试。把输出的值平均值放到excel里记录。
最新发布
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值