python将Linux下使用top命令获取的进程信息进行分析做可视化展示

Python个人学习笔记 专栏收录该内容
15 篇文章 0 订阅

python将Linux下使用top命令获取的进程信息进行分析做可视化展示

版本

版本作者日期备注
v1.0ZY2020.11.10初版完成

一、目标

Linux下我们通常使用top命令过滤某个进程获取该进程的内存以及CPU占用等信息,而进行长时间拷机时更可以将该信息重定向到文件中,拷机完成后我们直接分析该文件查看内存是否稳定,cpu占用是否存在飙升等,目前大数据分析火热的情况,我们想到将该文件数据做下简单的大数据分析,将常用数据利用python做下分析后以图表的形式展现出来并写入excel形成一次拷机的分析文档,这样将中间分析过程以及结果的归档过程代码化、自动化了,后续回溯也变得很方便了。

二、源码

(1)、top命令简单说明:

top ? 或者top -h之后:
Usage: top [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ]
    -m num  Maximum number of processes to display.
    -n num  Updates to show before exiting.
    -d num  Seconds to wait between updates.
    -s col  Column to sort by (cpu,vss,rss,thr).
    -t      Show threads instead of processes.
    -h      Display this help screen.

(2)、常用的top获取信息并存储文件

将process进程的信息获取并存储到top文件:
top | grep process > ./top

(3)、python处理思路

  • 读取top文件获取原始数据
  • 简单清洗原始数据,获取需要进行分析的cpu等字段信息并转换成int/float等便于进行数据计算的数据类习惯
  • 关键字段进行数学运算,比如计算最大值、最小值、平均值等
  • 将内存等信息变化过程利用图表展示出来
  • 将分析结果写入excel
  • 将python脚本打包,比如Windows下的exe,使得不用安装python环境即可运行

(4)、小技巧

  • 传入top文件时使用外部传参的方式获取任意名称的top文件,这样打包成exe后拖入任意名称的top文件即可
  • pandas的excel处理会覆盖sheet,因此需要结合openpyxl进一步处理excel

(5)、源码

思路清晰之后,结合python丰富的包,代码只有100+行,很方便,这里没有做过多的函数封装,后续可以优化一下(试用了pandas、openpyxl、matplotlib等):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/11/6 0006 9:24
# @Author  : ZY

import time
import sys
import openpyxl
import pandas as pd
from openpyxl import load_workbook
import matplotlib.pyplot as plt
from openpyxl.drawing.image import Image


def add_sheet(data, excel_writer, sheet_name):
    """
    不改变原有Excel的数据,新增sheet。
    注:
        使用openpyxl操作Excel时Excel必需存在,因此要新建空sheet
        无论如何sheet页都会被新建,只是当sheet_name已经存在时会新建一个以1结尾的sheet,如:test已经存在时,新建sheet为test1,以此类推
    :param data: DataFrame数据
    :param excel_writer: 文件路径
    :param sheet_name: 新增的sheet名称
    :return:
    """
    book = load_workbook(excel_writer.path)
    excel_writer.book = book
    data.to_excel(excel_writer=excel_writer, sheet_name=sheet_name, index=None, header=True)

    excel_writer.close()


# pandas读取top文件
if len(sys.argv) == 2:
    original_data = pd.read_csv(sys.argv[1], sep='\\s+', encoding='utf-8')
else:
    print("参数个数错误,请指定解析文件")
    sys.exit(-1)

# 以当前时间创建文件名
path = './' + 'top数据分析结果_' + time.strftime("%Y%m%d%H%M%S") + '.xlsx'
print(path)

# 创建空excel,添加sheet的接口必须文件存在
excel_write = pd.ExcelWriter(path, engine='openpyxl')
pd.DataFrame().to_excel(path, sheet_name='Sheet1')

# 可能存储的top文件没有线程调度策略这一项
if original_data.shape[1] == 10:
    original_data.columns = ['进程id(PID)', '进程优先级(PR)', 'CPU占用率(CPU%)', '进程状态(S)', '线程数(#THR)',
                             '虚拟内存(VSS)', '实际使用的物理内存(RSS)', '线程调度策略(PCY)', '进程所有者的ID(UID)', '进程名字(Name)']
elif original_data.shape[1] == 9:
    original_data.columns = ['进程id(PID)', '进程优先级(PR)', 'CPU占用率(CPU%)', '进程状态(S)', '线程数(#THR)',
                             '虚拟内存(VSS)', '实际使用的物理内存(RSS)', '进程所有者的ID(UID)', '进程名字(Name)']
print(original_data)

# 删除有空值的一行,即取出最后一列进程名字不为空的数据
topdata = original_data[original_data['进程名字(Name)'].notna()].copy()
print(topdata)

# 去除CPU占用中的%和内存中的K
topdata['CPU占用率(CPU%)'].replace(regex=True, inplace=True, to_replace='%', value='')
topdata['实际使用的物理内存(RSS)'].replace(regex=True, inplace=True, to_replace='K', value='')
# 转换类型为int/float
topdata['CPU占用率(CPU%)'] = topdata['CPU占用率(CPU%)'].astype('float64')
topdata['实际使用的物理内存(RSS)'] = topdata['实际使用的物理内存(RSS)'].astype('float64')

# 计算统计结果
min_mem = topdata['实际使用的物理内存(RSS)'].min()
max_mem = topdata['实际使用的物理内存(RSS)'].max()
avg_mem = round(topdata['实际使用的物理内存(RSS)'].mean(), 2)
statistical_res = {'统计结果': ['总行数:' + str(len(topdata)),
                            'ky_stb PID:' + str(topdata.iat[0, 0]),
                            '运行时长:' + str(round(len(topdata) * 3 / 60 / 60, 2)) + 'h',
                            'ky_stb重启次数:' + str(topdata['进程id(PID)'].value_counts().count() - 1),
                            '最小CPU:' + str(topdata['CPU占用率(CPU%)'].min()) + '%',
                            '最大CPU:' + str(topdata['CPU占用率(CPU%)'].max()) + '%',
                            '平均CPU:' + str(round(topdata['CPU占用率(CPU%)'].mean(), 2)) + '%',
                            '最小内存:' + str(min_mem) + 'KB' + '(' + str(round(min_mem / 1024, 2)) + 'M)',
                            '最大内存:' + str(max_mem) + 'KB' + '(' + str(round(max_mem / 1024, 2)) + 'M)',
                            '平均内存:' + str(avg_mem) + 'KB' + '(' + str(round(avg_mem / 1024, 2)) + 'M)']}

# 将内存数据转换为折线图并存储为图片
mem_show = pd.DataFrame(topdata['实际使用的物理内存(RSS)'], index=topdata.index)
fig = plt.figure()
# 设置字体,防止默认字体不存在告警以及显示方块
plt.rcParams['font.sans-serif'] = ['SimHei']
ax = fig.add_subplot(1, 1, 1)
mem_show.plot(ax=ax)
fig.savefig('mem.png')

# 将统计结果放入新sheet中
add_sheet(pd.DataFrame(statistical_res), excel_write, sheet_name='统计结果')
# 添加清洗后的未分析数据到excel的新sheet中
add_sheet(pd.DataFrame(topdata), excel_write, sheet_name='原始top数据清洗结果')
# 添加最原始的数据
add_sheet(pd.DataFrame(original_data), excel_write, sheet_name='原始top数据')
# 保存之前的修改
excel_write.save()

# 删除创建时的空sheet
excel_file = path
wb = openpyxl.load_workbook(excel_file)
ws = wb['Sheet1']
wb.remove(ws)
# 设置统计结果列的列宽
ws = wb[wb.sheetnames[0]]
ws.column_dimensions['A'].width = 50
# 插入内存处理后的图片到D3位置
img = Image('mem.png')
ws.add_image(img, 'D3')

wb.save(excel_file)

(6)、打包

使用pyinstaller打包:
(这个是其官网,可以总体了解一下:http://www.pyinstaller.org)

pip install pyinstaller
pyinstaller -F xxx.py

打包后的exe在生成的dist目录下。

期间打包后运行报错:could not find the matplotlib data files,最后发现是matplotlib版本和pyinsteller版本不匹配导致的,我这里重新安装3.1.1即可:

pip uninstall matplotlib
pip install matplotlib==3.1.1

三、最后

python流行自有其原因,丰富的包确实让开发应用快捷很多,但是其执行效率和打包后的大小确实也比较大。总体来说,python及数据处理是值得下功夫琢磨的。

  • 0
    点赞
  • 2
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值