进程性能分析工具 pidstat 和用 python 的 matplotlib 库输出分析图表

news2024/9/30 17:36:34

文章目录

    • 前情提要
    • 效果展示
    • pidstat 简介
    • matplotlib 简介
    • 认识 figure 和 axes
    • 绘制曲线图
    • 绘制柱形图
    • 创建两个轴,将上面两种图形放到一个 figure 中
    • Backends of matplotlib
    • 如何使用 WebAgg
    • 注意事项

前情提要

这段时间在忙服务器压测的工作,虽然我们程序里面有统计 cpu 消耗的日志,但是有两点不足。一是该统计信息只统计了整个进程的总的 cpu 消耗,没有细致到每个线程的 cpu 消耗。二是该统计信息只包含了 cpu 的开销,没有其他诸如 io 消耗等数据。在 github 上以性能统计为关键字找到了 sysstat 库,这是一个 linux 系统性能分析的工具集。里面大多数工具是以整个系统为对象进行数据采样和统计的。而我主要是想统计指定进程的信息,我在这个工具集中找到一个符合的工具 pidstat,“pidstat reports statistics for Linux tasks (processes) : I/O, CPU, memory, etc.”。本文介绍 pidstat 的基础使用,以及将 pidstat 采样的数据以图表的方式输出出来,再依靠 matplotlib 的 backend 机制创建一个临时的 web 服务器,我们可以通过访问该临时站点查看和下载图表的 png 文件。

效果展示

这是执行脚本分析 pidstat 采样到的数据,将生成的图表展示到一个临时的 web 服务器上
在这里插入图片描述

访问上面提示的站点,有如下效果
在这里插入图片描述

在网页的左下角有下载按钮
在这里插入图片描述

pidstat 简介

pidstat 是 sysstat 工具集的一员。专门用于统计进程的各项指标。要在服务器上使用 pidstat,需要先安装 sysstat 工具集,用 yum 管理软件包可以使用以下命令安装:

yum install -y sysstat  # 安装
systemctl enable --now sysstat # 启用

下面介绍一下 pidstat 的常用命令:

  • -C name 表示采样进程的 Command 包含 name 字段(name 支持正则表达式),Command 为进程名字:
    在这里插入图片描述
  • -p pid 表示指定采样进程的 pid。使用该选项可以更精准的指定采样目标。
  • -u 采样 cpu 使用率,包含了 cpu 百分比,分为内核占用,用户占用,总占用。例如:
    在这里插入图片描述
  • -d 采样 IO 消耗,该选项只支持内核版本 2.6.20 以后的机器,可以用 uname -r 查看内核版本。主要关注每秒读写信息:
    在这里插入图片描述
  • -r 采样页中断次数和内存消耗,页中断次数可以反应程序申请和释放内存的频率,一些不好的代码逻辑也可能造成页中断次数增高。主要关注 rss(resident size),驻留物理内存。
    在这里插入图片描述
  • -t 同时展示归属该进程的线程信息,他们的关系会用树的形式展现,使用该选项的前提是用 -p 指定pid,我用 -C name 试了下没有捕获到具体的线程信息。如下:
    在这里插入图片描述
  • -h 该选项在你使用了上诉的多个采样选项之后可以加上,它可以让所有采样信息在水平一行一起输出,否则就是一个或者某几个天然可以搭配的采样内容一起输出,另外的单独输出,这样不方便将数据汇总起来二次处理。
  • 另外,在所有选项最后接上一个数字表示采样间隔时间(单位秒),如果你还想控制更精确点,后面还可以跟上一个数字表示在前一个数字指定的间隔时间内的采样次数。(采样间隔时间是可选项,默认值为 10 分钟,采样次数也是可选项,默认值为 1 次,我一般是设置为采样间隔 1 秒,采样次数就用默认值,即 1 秒 1 次)

这是我使用的采样命令:

nohup pidstat -p $pid -udrth 1 > $stat_cpu_log 2>/dev/null &
  • pidstat -p $pid -udrth 1 这部分是表示统计指定 pid 的进程的所有线程的 cpu 消耗,io 消耗,内存消耗,并且将每次的采样信息输出到一排,采样频率为 1 秒 1 次。
  • nohup 使得我关掉终端并不影响 pidstat 的运行。
  • > $stat_cpu_log 将 pidstat 输出的内容重定向到文件,方便我后续做二次处理。
  • 2>/dev/null 将 pidstat 产生的错误信息重定向到空文件,就是丢弃。
  • & 后台运行。

matplotlib 简介

Matplotlib是一个Python数据可视化库,提供了丰富的绘图工具,包括线图、散点图、条形图、等高线图、图像等。它的设计灵活,可以用于各种不同的绘图需求,从简单的图形到复杂的动态图形。Matplotlib的优点是它易于使用,具有广泛的文档和社区支持,可以与NumPy、SciPy等Python科学计算库无缝集成。同时,Matplotlib也是许多其他Python数据可视化库的基础,如Seaborn、ggplot等。

认识 figure 和 axes

figure 可以理解为一个图表的画布,这个画布上可以有多个 axes(轴,包含 x轴 和 y轴 组成的坐标轴),以下这张图是官网提供的 figure 介绍图,内容量很大。其中的蓝色圆圈表示圈中的内容可以由圈下面的函数调用绘制而成。
在这里插入图片描述

figure 和 axes 可以由 plt.subplots() 函数创建出来:

fig, ax = plt.subplots() # 创建包含了一个坐标轴的 figure
                         # figure 为一个 matplotlib.figure 对象
						 # ax 为一个 matplotlib.axes.Axes 对象
fig, axs = plt.subplots(rows, cols) # 创建包含了 rows * cols 个坐标轴的 figure
                                    # axs 为 matplotlib.axes.Axes 对象的二维数组
                                    # 形如 axs = matplotlib.axes.Axes[rows][cols]

我们的曲线或者其他图形都是基于 axes 来绘制的,figure 可以不要,例如用 plt.subplot 接口只创建坐标轴来绘制。但是基于 figure 来创建 axes ,可以用 figure 的一些属性来提供对图表的总体调控。

绘制曲线图

# -*- coding: utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# 0. 创建坐标轴,可以根据自己实际需要选择创建一个轴还是多个轴,只是要注意下多个轴是返回的数组
fig, ax = plt.subplots()
x_list = [1,2,3] # x 轴数据
y_list = [3,6,5]
# 1. 基本调用
ax.plot(x_list, y_list) # x 和 y 轴数据都由用户传入
# 2. 省略 x 数组
ax.plot(y_list)  # x 轴数据自动生成,系统会根据 y 轴数组长度自动填充 1~n 的 x 轴数据
# 3. 给曲线命名
ax.plot(y_list, label="name1") # label 属性可以指定该条曲线的名称
ax.legend() # 显示每条线的名字列表
# 4. 给坐标轴命名
ax.set_xlabel("我是x轴")
ax.set_ylabel("我是y轴")
# 5. 绘制
plt.show()

在这里插入图片描述

绘制柱形图

# -*- coding: utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# 0. 创建坐标轴,可以根据自己实际需要选择创建一个轴还是多个轴,只是要注意下多个轴是返回的数组
fig, ax = plt.subplots()
categories = ["name1", "name2", "name3"] # 柱形图 x 轴命名
values = [10, 35.5, 99] # 数据
# 1. 绘制到坐标轴上
rects = ax.bar(categories, values) # 返回值可以不关心,这里是用于设置柱形图顶上的数据显示需要用到下一个函数
# 2. 将数据标注到柱形图上方,方便观察
ax.bar_label(rects, padding=3, rotation=-55) # 
# 3. 将 x 轴的名字按 -55 度进行旋转,即是 顺时针旋转 55 度
ax.tick_params(axis='x', rotation=-55) # 这是为了避免名字过长,左右两个名字出现重叠
# 4. 绘制
plt.show()

在这里插入图片描述

创建两个轴,将上面两种图形放到一个 figure 中

# -*- coding: utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

# 0. 创建两个坐标轴,用 figsize 设置图表的总大小
fig, axs = plt.subplots(1, 2, figsize=(12, 6))
ax = axs[0] # 曲线图用第一个
ax_bar = axs[1] # 柱形图用第二个

x_list = [1,2,3] # x 轴数据
y_list = [3,6,5]
# 1. 基本调用
ax.plot(x_list, y_list) # x 和 y 轴数据都由用户传入
# 2. 省略 x 数组
ax.plot(y_list)  # x 轴数据自动生成,系统会根据 y 轴数组长度自动填充 1~n 的 x 轴数据
# 3. 给曲线命名
ax.plot(y_list, label="name1") # label 属性可以指定该条曲线的名称
ax.set_xlabel("IamX")
ax.set_ylabel("IamY")
ax.legend() # 显示每条线的名字列表

categories = ["name1", "name2", "name3"] # 柱形图 x 轴命名
values = [10, 35.5, 99] # 数据
# 1. 绘制到坐标轴上
rects = ax_bar.bar(categories, values) # 返回值可以不关心,这里是用于设置柱形图顶上的数据显示需要用到下一个函数
# 2. 将数据标注到柱形图上方,方便观察
ax_bar.bar_label(rects, padding=3, rotation=-55)
# 3. 将 x 轴的名字按 -55 度进行旋转,即是 顺时针旋转 55 度
ax_bar.tick_params(axis='x', rotation=-55) # 这是为了避免名字过长,左右两个名字出现重叠

plt.show()

在这里插入图片描述

Backends of matplotlib

我在 matplotlib 的文档中发现一个 backends 机制,简单来说,matplotlib 可以让用户选择用什么后端技术来最终渲染输出绘制的内容,比如在 windows 平台,可以直接在控制台窗口执行脚本,弹出绘图窗口;或者将 matplotlib 嵌入到 PyQt 或 PyGObject 等图形用户界面中构建应用;还有一些人运行 web 应用程序服务器来动态展示图表。

由于我是在 linux 服务器上绘图,所以打开一个 web 服务器的 backend 特别合适,这样我每次有新的图表绘制后,只需要刷新一下网页即可,比生成图片,然后用 sz 发送到本地(sz 还和 tmux 冲突),再保存到文件夹,再打开来说方便太多了。

以下是 matplotlib 目前支持的 backend 模式,我要介绍的是 WebAgg 模式,其他模式大家可以按自己的需求来选择:
在这里插入图片描述

如何使用 WebAgg

  1. 由于 matplotlib 是根据环境变量 MPLBACKEND 的值来指定对应 backend 的, 所以要么预先设置服务器上的该环境变量为 MPLBACKEND=WebAgg,要么就是调用脚本时先指定环境变量,可以像这样调用:

    MPLBACKEND=WebAgg python3 test.py
    
  2. WebAgg 是通过调用 Tornado 这个库来生成 web 服务器的,所以需要用 pip 安装 Tornado 库。后面会说到版本的问题。

  3. 我自己测试发现,默认启动的 web 服务器的访问站点是 http://127.0.0.1:8898,如果你是在自己的电脑上执行脚本的话那么还好,你可以在网页中访问该站点。但是我是在内网的某个服务器上执行脚本,我从本地电脑是无法访问到服务器的这个站点的。官方有提供 WebAgg 的源码,通过源码发现可以像这样修改 web 服务器的 IP:

    import matplotlib as mpl
    mpl.rcParams['webagg.address'] = ip
    

    这里的 ip 你可以写死成你的服务器地址,但是这样肯定是不好的。这里提供一个获取 ip 的函数。

    # -*- coding: utf-8 -*-
    import socket
    import matplotlib as mpl
    # 获取本机IP地址
    def get_local_ip():
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(('8.8.8.8', 80))
            ip = s.getsockname()[0]
        except:
            ip = '127.0.0.1'
        finally:
            s.close()
        return ip
    mpl.rcParams['webagg.address'] = get_local_ip()
    

注意事项

  • matplotlib 版本差异,python 版本差异,依赖库的差异都可能引发各种问题,下面列一下我使用的版本情况
    在这里插入图片描述
  • 如果有 python 安装模块不全的问题可以参考 python3.8 安装 和 python3.10.3 安装。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五种高效的原型设计工具推荐

软件产品的诞生注定要经历一个过程:需求分析、设计、开发、测试和在线。在设计阶段,原型设计是软件设计和开发的重要保证。与其他工作一样,高效的原型设计需要相应工具的帮助来完成原型设计。在许多原型设计工具中,这里推荐了五种…

洛谷P1420-最长连号

洛谷P1420-最长连号 这个题目很入门,但是我第一次做怎么做都做不出来,看了几个代码,方法各式各样,这个我是我觉得最通俗易懂的一个, 循环外面的两个输入第一个cin是个数第二个是输入的第一个数,所以下面for循环的条件…

毕业论文之转化为三线表格(wps)

目录 一、前言 1.修改之前的表格 2. 修改完成后(三线表格式) 二、操作步骤 一、前言 在论文里面的表格要求是三线表格式的时候,就需要我们去把这个表格修改成三线表格式。 1.修改之前的表格 2. 修改完成后(三线表格式&…

Vulnhub靶机渗透:Raven1(超级详细)

Raven1 https://www.vulnhub.com/entry/raven-1,256/ kali:192.168.54.128 raven1:192.168.54.15 nmap扫描 端口扫描 # Nmap 7.93 scan initiated Thu May 18 16:41:33 2023 as: nmap --min-rate 20000 -p- -oN nmap/ports 192.168.54.15 Nmap scan report for 192.168.54.…

PPT / Powerpoint中利用LaTeX输入公式

新版的Word(Office 2016后?)是支持LaTeX公式输入的,但是Powerpoint并不支持。下面介绍如何利用latex-ppt插件实现PPT中输入LaTeX公式: 1 安装latex-ppt插件 1.1 下载插件 插件开源仓库:latex-ppt&#x…

Linux【Ubuntu】安装Docker配置docker-compose 编排工具

一:Docker具体安装传送门: 亲测有效 https://www.runoob.com/docker/ubuntu-docker-install.html 二:配置Docker编排工具docker-compose 1,下载Docker-compose 下载Docker-Compose(下载完毕就是一个文件docker-compose-Linux-x…

实验10 超市订单管理系统综合实验

实验10 超市订单管理系统综合实验 应粉丝要求,本博主帮助实现基本效果! 未避免产生版权问题,本项目博主不公开源码,如果您遇到相关问题可私聊博主! 一、实验目的及任务 通过该实验,掌握利用SSM框架进行系…

生成式AI热潮:一场“添饭碗”的科技革命

今年以来,人工智能(AI)热潮席卷全球,被认为将掀起新的科技革命。 5月18日的2023天津世界智能大会,以“智行天下 能动未来”为主题,重点关注人工智能发展的新趋势、新技术、新业态。大会开幕式结束之后&…

lidar camera calibration

1 Automatic Extrinsic Calibration Method for LiDAR and Camera Sensor Setups 2022 vel2cam git 2 A Novel Method for LiDARCamera Calibration by PlaneFitting 本文介绍了一种使用带ArUco标记的立方体的3D-3D对应特征来校准LiDAR和相机的新方法。在LiDAR坐标系中&…

安全响应中心 — 垃圾邮件事件报告(5.16)

2023年5月 第二周 一. 样本概况 ✅ 类型1:二维码钓鱼(QRPhish) 利用二维码进行的钓鱼、投毒,成为目前常见的邮件攻击手段之一,该类二维码主要存在于网络链接图片、邮件内容图片、附件图片中。 近日,安全团队捕获到一类基于员工…

什么是DevOps?如何理解DevOps思想?

博文参考总结自:https://www.kuangstudy.com/course/play/1573900157572333569 仅供学习使用,若侵权,请联系我删除! 1、什么是DevOps? DevOps是一种思想或方法论,它涵盖开发、测试、运维的整个过程。DevOps强调软件开…

三阶段项目相关内容

当虚拟网关和真实物理网关相同的时候,默认优先级是255 vrrp角色: 主路由器 备份路由器 虚拟路由器 计时器:发送hello报文的时间, 主网关:每隔1s会向备份发一次vrrp报文 备份网关:监听vrrp报文,主网…

【UE4】从零开始制作战斗机(上:准备模型、定义函数和变量)

资源连接:(链接) 步骤: 1. 下载完资源并解压,资源内容如下: 2. 将上图中所有的.fbx文件导入ue 使用默认的导入设置就行,直接点击导入所有 导入后内容如下: 将资源中的textures也导…

程序员必备的免费自然语言转SQL (摸鱼)工具,人手必备

程序员必备的免费自然语言转SQL (摸鱼)工具,人手必备 1、SQL查询中添加过滤 请对附加的SQL查询添加筛选条件,仅显示在加州居住且消费总额排名前10位的客户。 “SELECT customer_name, SUM(order_total) AS total_spent FROM orders GROUP BY customer…

web缓存—Squid代理服务

1.squid的相关知识 1.1 squid的概念 Squid服务器缓存频繁要求网页、媒体文件和其它加速回答时间并减少带宽堵塞的内容。 Squid代理服务器(Squid proxy server)一般和原始文件一起安装在单独服务器而不是网络服务器上。Squid通过追踪网络中的对象运用起…

一文搞懂Golang中的接口

目录 接口 接口介绍 接口定义 实现接口 空接口 实现空接口 类型断言 使用类型断言 结构体实现多接口 接口嵌套 结构体值接收者和指针接收者实现接口的区别 代码案例 接口 接口介绍 Go语言中的接口(interface)是一组方法签名的集合&#xf…

单片机--STM中断系统

目录 【1】中断系统 1.基本概念 2.中断的意义 中断提高了CPU效率? 3.中断处理过程 中断处理过程 4. 中断体系结构 5.NVIC NVIC主要功能 6.EXTI 【2】IIC IIC主要特点 【3】485 【1】中断系统 1.基本概念 在处理器中,中断相当于对于突发事件…

【Scala---02】Scala 类与对象 『 类 | 属性 | 访问权限 | 方法 | 继承 | 伴生对象伴生类』

文章目录 1. 定义类2. 属性3. 访问权限4. 方法4.1 方法 vs 函数4.2 方法重写4.3 方法重载4.4 构造方法(1) 构造器定义(2) 构造器的参数列表(3) 构造器私有化 5. 继承6. 伴生对象 & 伴生类6.1 伴生对象的由来6.2 伴生对象 & 伴生类 7. 后续 1. 定义类 Java文件&#xf…

JavaScript全解析——ES6函数中参数的默认值和解构赋值

本文为千锋资深前端教学老师带来的【JavaScript全解析】系列,文章内含丰富的代码案例及配图,从0到1讲解JavaScript相关知识点,致力于教会每一个人学会JS! 文末有本文重点总结,可以收藏慢慢看~ 更多技术类内容&#xf…

AI向百万薪资 高级原画师开刀?!爆Midjourney入局3D模型生成

来源 SoulofArt | ID Soul_Art 现在AI向高级原画师和3D开刀了? 网传爆料AI已入局3D模型生成... 这进化速度放在整个行业都十分炸裂 4月,Midjourney进一步宣布推出Niji-journey V5 这是MJ针对二次元动漫风格预训练好的模型 可在其中添加提示词直接调…