Python教程:使用psutil和rich库实现一个终端资源监控小工具(附完整代码)

在本文中,我们将介绍如何使用 Python 的 psutil 和 rich 库来实现一个终端资源监控小工具。psutil 是一个跨平台的 Python 库,用于获取关于系统进程和系统利用率的信息,而 rich 是一个 Python 库,用于在终端中创建美观的输出。

1.psutil 库介绍

psutil(Python System and Process Utilities)是一个强大的跨平台库,用于获取关于系统进程和系统利用率的信息,例如 CPU、内存、磁盘、网络等。它提供了简单易用的接口,可以方便地监控和管理系统资源。

在本项目中,我们主要使用 psutil 来获取关于指定进程的详细信息,例如进程的用户名、创建时间、线程数、CPU 占比、内存占比等。

2.rich 库介绍

rich 是一个 Python 库,用于在终端中创建美观的输出。它提供了丰富的样式和布局选项,使得在终端中输出信息更加清晰和易读。

在本项目中,我们将使用 rich 库来创建一个美观的表格,显示获取到的进程信息。

3.设计思路

  1. 导入所需的库:我们首先需要导入 psutil 和 rich 库,以及一些其他必要的模块。

  2. 编写函数获取目标进程:编写一个函数,通过进程名称获取指定进程的详细信息。

  3. 编写函数显示信息:编写一个函数,使用 rich 库创建一个表格,并显示获取到的进程信息。

  4. 主程序逻辑:在主程序中,设置要监控的进程名称和更新时间间隔,并调用上述函数实现监控功能。

4.实现原理

  1. 使用 psutil 库的 psutil.Process() 方法获取指定进程的详细信息,例如用户名、创建时间、线程数、CPU 占比、内存占比等。

  2. 使用 rich 库的 Table 类创建一个表格,使用 add_column() 方法添加列,使用 add_row() 方法添加行,并使用 console.log() 方法在终端中输出表格。

  3. 在主程序中,设置一个循环,每隔一定时间获取一次指定进程的信息,并使用 rich 库在终端中显示。

5.工具整体功能介绍

  1. 进程信息获取功能:

    • 使用 psutil.pids() 获取当前系统所有进程的 PID 列表。
    • 遍历每个 PID,通过 psutil.Process(pid) 获取进程对象 p
    • 判断进程对象 p 的名称是否包含指定的进程名 procName,以确定目标进程。
  2. 进程信息展示功能:

    • 使用 rich 库中的 Table 类创建一个表格,用于展示进程的详细信息。
    • 将进程的关键信息(如用户名、创建时间、线程数、CPU 占比、内存占比等)添加到表格中的不同行中。
    • 使用 console.log() 方法将表格和其他相关信息以美观的格式输出到终端。
  3. 循环监控功能:

    • 在 showMsg 函数中使用 while True 循环,持续监控目标进程的状态。
    • 每次循环中,重新获取目标进程的信息并更新展示在终端上的表格。
    • 使用 time.sleep(timeInterval) 控制每次更新的时间间隔,避免过度频繁地查询和展示信息。
  4. 异常处理:

    • 使用 try 和 except 块捕获 psutil.Process(pid) 可能抛出的异常,确保程序在获取进程信息时不会意外中断。
  5. 主程序逻辑:

    • 在主程序中,通过读取配置文件(例如 Config.py)获取要监控的进程名称和更新时间间隔。
    • 初始化 rich 库中的 Console 对象,用于在终端上输出信息。
    • 调用 showMsg 函数,传入要监控的进程名称和时间间隔,实现进程信息的持续监控和展示。

6.完整代码及配置如下

monitor.py

# -*- coding: gbk -*-
'''
Created on 2022年11月24日

@author: DanMo
@status: done
'''
import time
import psutil
from rich.console import Console
from rich.table import Column, Table
from rich.progress import track
from Config import config

def getTargetProc(procName):
    pidList = psutil.pids()
    for pid in track(pidList, description="获取本机所有进程..."):
        try:
            p = psutil.Process(pid)
        except:
            continue
        if procName in p.name():
            return p

def showMsg(procName, timeInterval):
    while True:
        table = Table(show_header=True, header_style="bold magenta")
        table.add_column("项目", style='dim')
        table.add_column("详情", style='dim')
        p = getTargetProc(procName)
        table.add_row('用户', f'{p.username()}')
        table.add_row('进程创建时间', f'{p.create_time()}')
        table.add_row('线程数', f'{p.num_threads()}')
        table.add_row('父进程', f'{p.parent()}')
        table.add_row('当前进程状态', f'{p.status()}')
        table.add_row('被调用的命令行', f'{p.cmdline()}')
        table.add_row('exe', f'{p.exe()}')
        table.add_row('io', f'{p.io_counters()}')
        table.add_row('CPU占比', f'{p.cpu_percent()}')
        table.add_row('内存占比', f'{p.memory_percent()}')
        table.add_row('当前进程打开的句柄数', f'{p.num_handles()}')
        console.log('进程信息总览:\n', p.__dict__, style='dim')
        console.log('当前进程创建的所有线程:\n', p.threads(), style='dim')
        console.log('打开的文件:\n', p.open_files(), style='dim')
        console.log('子进程:\n', p.children(True), style='dim')
        console.log(
            '进程所有连接信息[IPv4、IPv6、TCP、TCP over IPv4、TCP over IPv6、UDP、UDP over IPv4、UDP over IPv6、UNIX socket (both UDP and TCP protocols)]:\n',
            p.connections('all'), style='dim')
        if config.get_conf('envPath'):
            console.log('环境变量:\n', p.environ(), style='dim')
        console.log('内存信息:\n', p.memory_full_info(), style='dim')
        if config.get_conf('memorymap'):
            console.log('内存映射:\n', p.memory_maps(), style='dim')
        console.log('其他关于进程的信息:\n', style='dim')
        console.log(table)
        time.sleep(timeInterval)


if __name__ == '__main__':
    console = Console()
    procName = config.get_conf('processname')
    timeInterval = config.get_conf('timeinterval')
    showMsg(procName, timeInterval)

Config.py

# -*- coding: gbk -*-
'''
Created on 2022年11月24日

@author: DanMo
@status: done
'''
import os
import json
import threading
import configparser

workpath = os.path.dirname(os.path.abspath(__file__))
configFile = os.path.join(workpath, 'config.txt')
_lock = threading.Lock()

class CConfig(object):
    '''
    实现对配置的操作
    本类中,配置文件为config.txt
    对外部提供的结构为:
        set_conf
        get_conf
        clean_conf
        cleanall_conf
    '''

    def __init__(self, filename='config.txt'):
        self.filename = os.path.abspath(filename)
        self.config = configparser.ConfigParser(allow_no_value=True)
        # TODO:xiehs config逻辑,可以采取预先读取所有的方式,进行性能提高

    def set_conf(self, option, value=None, section='Monitor'):
        try:
            _lock.acquire()
            if not os.path.exists(self.filename):
                tmpf = open(self.filename, 'w')
                tmpf.close()
            if not self._is_exist(self.filename):
                raise Exception('CONFIG_File_Not_File')
            self.config.read(self.filename)
            if not self.config.has_section(section):
                self.config.add_section(section)
            self.config.set(section, option, json.dumps(value))
            with open(self.filename, 'w') as configfile:
                self.config.write(configfile)
        finally:
            _lock.release()

    def get_conf(self, option, section='Monitor'):
        if not os.path.exists(self.filename):
            return None
        if not self._is_exist(self.filename):
            raise Exception('CONFIG_File_Not_File')
        self.config.read(self.filename)
        if not self.config.has_section(section) or not self.config.has_option(section, option):
            return None
        val = self.config.get(section, option)
        val = json.loads(val)
        return val

    def _is_exist(self, path):
        return os.path.isfile(path)


config = CConfig(configFile)

config.txt

[Monitor]
processname = "YourAppName"
timeinterval = 4
memorymap = false
envPath = false

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/585142.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费的单片机物联网MQTT平台选择

目的是多设备接入中控,平台只做转发。 选择巴法云:巴法科技&巴法云-巴法设备云-巴法物联网云平台 clientId是私钥uid: 多设备 clientId 填同一个 uid 都是可以的。平台应该是加了后缀区分。 支持自定义topic,操作简单&#x…

Stable Diffusion使用ControlNet:IP-Adapter实现图片风格迁移

IP-Adapter 全称是 Text Compatible Image Prompt Adapter for Text-to-Image Diffusion Models(文本到图像扩散模型的文本兼容图像提示适配器),是腾讯研究院出品的一个新的ControlNet模型,旨在使预训练的文本到图像扩散模型能够生…

【Qt之·控件·样式表】

系列文章目录 文章目录 前言一、Qt样式表的基础知识1.1 Qt样式表的定义和语法规则1.2 Qt样式表中的选择器和属性1.2.1 盒子模型1.2.2 border 1.3 Qt样式表中的伪类和伪元素 二、编写基本的Qt样式表2.1 在Qt应用程序中引入样式表文件的方式2.2 设置基本的背景色、字体样式等 三、…

Anomalib:用于异常检测的深度学习库!

大家好,今天给大家介绍了一个用于无监督异常检测和定位的新型库:anomalib,Github链接:https://github.com/openvinotoolkit/anomalib 简介 考虑到可重复性和模块化,这个开源库提供了文献中的算法和一组工具,以通过即插即用的方法设计自定义异常检测算法。 Anomalib 包…

VUE+TS使用elementUI的el-checkbox双重v-for循环做勾选

html部分 <template><div class"hello"><el-form :model"elForm"> <!-- cities对象数组形式 --><el-form-item v-for"(item, topIndex) in cities" :key"topIndex"> <!--item.checked 是每一个item…

深度解析 Spring 源码:从BeanDefinition源码探索Bean的本质

文章目录 一、BeanDefinition 的概述1.1 BeanDefinition 的定位1.2 BeanDefition 的作用 二、BeanDefinition 源码解读2.1 BeanDefinition 接口的主要方法2.2 BeanDefinition 的实现类2.2.1 实现类的区别2.2.2 setBeanClassName()2.2.3 getDependsOn()2.2.4 setScope() 2.3 Bea…

用Python Turtle画一个中国结

中国结&#xff0c;作为中华民族传统文化的象征之一&#xff0c;以其独特的编织技艺和深厚的文化内涵&#xff0c;深受人们喜爱。今天&#xff0c;我们就来用Python的turtle模块&#xff0c;尝试绘制一个充满韵味的中国结。 我们先来看看整个中国结生成的过程&#xff1a; 中国…

ros2 node 之间的通信方式之 —— Topic通信案例

文章目录 ros2 node 之间的通信方式之 Topic通信Topic 通信案例1、创建工作空间2、创建功能包3、编写发布者和订阅者代码3.1 topic_helloworld_pub.cpp3.2 topic_helloworld_sub.cpp 4、编写CMakeLists.txt5、编译工作空间下的功能包6、运行结果 ros2 node 之间的通信方式之 To…

2024年,如何实现高效的自动化渗透测试?

随着当前网络安全威胁的不断扩展与升级&#xff0c;开展渗透测试工作已经成为广大企业组织主动识别安全漏洞与潜在风险的关键过程。然而&#xff0c;传统的人工渗透测试模式对测试人员的专业能力和经验水平有很高的要求&#xff0c;企业需要投入较大的时间和资源才能完成。在此…

Seata分布式事务使用!!!!

1.版本说明 版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 2.建立Seata Server数据库&#xff08;TC-带头大哥的数据库&#xff09; incubator-seata/script/server/db at v1.6.1 apache/incubator-seata GitHub 3.业务库建表 incubator-seata/script/client/at/…

对于button按钮引发的bug

主要原因就是今天在给button按钮添加一个点击事件的时候&#xff0c;并没有声明button的type类型&#xff0c;就一直发生点击按钮但事件并不触发的问题。 触发这种问题的原因就是: 按钮默认的 type 类型是 "submit"&#xff0c;而不是 "button"。当你不显式…

探索潜力:中心化交易所平台币的对比分析

核心观点 平台币在过去一年里表现差异显著&#xff1a; 在过去的一年里&#xff0c;只有少数几个平台币如BMX、BGB和MX的涨幅超过了100%。相比之下&#xff0c;由于市值较高&#xff0c;BNB和OKB的涨幅相对较低。 回购和销毁机制在平台币价值中起决定性作用&#xff1a; 像M…

OpenHarmony实战开发-基础知识

Svg组件主要作为svg画布的根节点使用&#xff0c;也可以在svg中嵌套使用。 说明&#xff1a; svg父组件或者svg组件需要定义宽高值&#xff0c;否则不进行绘制。 创建Svg组件 在pages/index目录下的hml文件中创建一个Svg组件。 <!-- xxx.hml --> <div class"co…

[华为OD] C卷 5G网络 现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站 200

题目 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N,接 下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成 本各不相同&#xff0c;且有些节点之间已经存在光纤相连&#…

力扣刷题 63.不同路径 II

题干 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

(css)鼠标移出样式不变

(css)鼠标移出样式不变 需求&#xff1a;列表鼠标移入切换样式&#xff0c;移出保持不变 <divv-for"(item, index) of newsList":key"index"class"news-list":class"{active : change index}"tabindex"1"mouseenter&quo…

docker各目录含义

目录含义builder构建docker镜像的工具或过程buildkit用于构建和打包容器镜像&#xff0c;官方构建引擎&#xff0c;支持多阶段构建、缓存管理、并行化构建和多平台构建等功能containerd负责容器生命周期管理&#xff0c;能起、停、重启&#xff0c;确保容器运行。负责镜管理&am…

2024最新的,免费的 ChatGPT 网站AI(八个)

ChatGPT是美国人工智能研究实验室OpenAI在2022年11月推出的一款人工智能技术驱动的语言模型应用。它基于GPT-3.5架构&#xff08;后续还有GPT-4架构的升级版&#xff09;构建&#xff0c;拥有强大的自然语言处理能力和上下文理解能力&#xff0c;能够参与多轮对话&#xff0c;为…

恩智浦如何使用DITA

▲ 搜索“大龙谈智能内容”关注公众号▲ 作者 | John Walker - NXP销售和市场营销业务分析师 2013年4月18日 作为恩智浦半导体公司销售和市场部的业务分析师&#xff0c;我负责恩智浦半导公司产品信息的数据/内容模型、流程和工具。我来自英国&#xff0c;但自2000年以来一…

Python3 循环语句

Python 中的循环语句有 for 和 while。 Python 循环语句的控制结构图如下所示&#xff1a; while 循环 Python 中 while 语句的一般形式&#xff1a; while 判断条件(condition)&#xff1a;执行语句(statements)…… 执行流程图如下&#xff1a; 同样需要注意冒号和缩进。…
最新文章