基于top命令监控进程cpu占用与mem占用

1 minute read

Published:

本文着重于对cpu 和mem 资源的统计分析。

通常,在软件开发过程中需要关注系统资源使用情况,在经过一段时间的压力测试下,采集cpu 和mem 利用率,分析得到软件对资源占用的峰谷值。

采集

利用top 命令获取感兴趣进程(POI)的资源信息。 perf.sh 内容如下:

#!/bin/bash
 
# file name format 

filename="top_$(date "+%Y%m%d%H%M%S").log"
 
while true; do
    timestamp=$(date "+%Y%m%d%H%M%S")
    echo "Current time: $timestamp"
    echo $timestamp >> "$filename"
    top -b -n 1 >> "$filename"

    # 1 s
    sleep 1
done

#   
#
#  grep havp_nni_node ~/top_20250409135102.log
#  
#  # 0 means full line 
#  # 9 CPU; 10 mem
#
# bash  ./perf.sh 
#
# grep process_name  ~/top_20220101000550.log | awk '{print $9 "," $10}' > top_20220101000550.csv
#
# python3 draw.py -i top_20250409135646.csv  
#
#

可视化

可视化脚本draw.py 如下:

import pandas as pd
import matplotlib.pyplot as plt 
import argparse

parser = argparse.ArgumentParser(description="draw")
parser.add_argument("-i", "--input", help="file name", required=True)
args = parser.parse_args()

df = pd.read_csv(args.input)

fig = plt.figure()     

assert 2 == len(df.columns), "bad collect by grep"
key_str = ["CPU", "MEM"]
i = 1

for column in df.columns:
    fig.add_subplot(int(f"12{i}"))    
    df[column].plot(kind='line', color='deepskyblue')   

    max_v = df[column].max()
    min_v = df[column].min()
    avg_v = df[column].mean()
    p90_v = df[column].quantile(0.9)

    # draw max value as a horizon line
    plt.axhline(y=max_v, color='r', linestyle='--')    
    plt.text(0, max_v, 'max:%.1f' % max_v, fontsize=12, color='r', ha='right')   

    # draw min  
    plt.axhline(y=min_v, color='y', linestyle='--')  
    plt.text(0, min_v, 'min:%.1f' % min_v, fontsize=12, color='y', ha='right')   

    # draw mean  
    print(f"{avg_v} {max_v}")
    if abs(avg_v - max_v) > 0.2:
        # plt.axhline(y=avg_v, color='lawngreen', linestyle='--')   
        plt.text(0, avg_v, 'mean:%.1f' % avg_v, fontsize=12, color='lawngreen', ha='right')     

    # draw p90  
    if abs(p90_v - max_v) > 0.2:
        # plt.axhline(y=p90_v, color='m', linestyle='--')   
        plt.text(0, p90_v, 'p90:%.1f' % p90_v, fontsize=12, color='gray', ha='right')   

    plt.ylabel('usage %')
    plt.xlabel('samping idx')

    plt.title(f'{key_str[i-1]} usage')
    i += 1
plt.show()   

# grep 42745  ./top_20220101001338.log | awk '{print $9 "," $10}' > mainborad.csv
# grep 3497 ./top_20220101001338.log | awk '{print $9 "," $10}' > mainborad.csv
# https://zhuanlan.zhihu.com/p/65220518

合一

#!/bin/bash

if [ -z "$#" ];then
  echo -e "bad params"
  exit 1
fi 

profile_out=$1

grep havp_nni_node  $profile_out | awk '{print $9 "," $10}' > $profile_out.csv
if [ -s $profile_out.csv ]; then
    python3 draw.py -i $profile_out.csv
else
    echo "$profile_out.csv is empty"
fi

运行

#!/bin/bash

bash ./run.sh top_20220101005855.log    

输出

output