Windows の CPU 使用率を収集して、Python (pandas+matplotlib) でグラフ化してみようという話です。
パフォーマンス データ収集(CPU)
logman
コマンドによりパフォーマンス データは簡単に収集できます。CPU 使用率を取得したい場合には、"\Processor Information(*)\% Processor Utility"
を指定すれば OK です。
# 1. CPU の使用率データを取得するデータ コレクター セットを作成
logman create counter "Perf_CPU" -c "\Processor Information(*)\% Processor Utility" -f csv -si 00:00:05 -o "C:\path\to\Logs\PerfLogging"
# 2. データ コレクター セットでログ取得を開始
logman start "Perf_CPU"
# 3. ログ取得を終了
logman stop "Perf_CPU"
# 4. 作成したデータコレクターセットを削除
logman delete "Perf_CPU"
Windows のパフォーマンス収集方法についての一般的な内容は、以下の Web サイトに書いたので、パフォーマンス ログ収集に興味があれば、一読いただければと思います。
パフォーマンス ログ収集 | Microsoft Japan Windows Technology Support Blog
https://jpwinsup.github.io/blog/2021/06/07/Performance/SystemResource/PerformanceLogging/
CSVファイルの形式
ヘッダー
"(PDH-CSV 4.0) ("
"\\ComputerName\Processor Information(0,0)\% Processor Utility"
"\\ComputerName\Processor Information(0,1)\% Processor Utility"
"\\ComputerName\Processor Information(0,2)\% Processor Utility"
"\\ComputerName\Processor Information(0,3)\% Processor Utility"
"\\ComputerName\Processor Information(0,4)\% Processor Utility"
"\\ComputerName\Processor Information(0,5)\% Processor Utility"
"\\ComputerName\Processor Information(0,6)\% Processor Utility"
"\\ComputerName\Processor Information(0,7)\% Processor Utility"
"\\ComputerName\Processor Information(0,_Total)\% Processor Utility"
"\\ComputerName\Processor Information(_Total)\% Processor Utility"
※ 見やすくするため、ヘッダーごとに改行しています。
1列目に謎の文字列"(PDH-CSV 4.0) (" が入っていますが、あとは CPUコアごとのデータと Total のヘッダーになります。中括弧の意味は、(0,4) = CPU0 の Core4 になります。なお、CPU を物理的に2個搭載しているサーバーなどでは、(1,0)、(1,1)、(1,2)... のデータも存在します。
(0,_Total)は、CPU0 の CPU 使用率、(_Total)は、端末に搭載しているすべての CPU の使用率という意味になります。
データ
"09/01/2024 17:59:38.102","47.122997226400272552","35.14188125643801186","41.022807332658764778","39.859085387270773992","35.931130229351772698","30.722207450208369295","38.218370531626831621","36.887222990085248853","38.113454862442544879","38.114960321492084461"
1列目に日時、それ以降の列に CPU 使用率のデータが入っています。
CPU パフォーマンスのグラフ化(Python)
おなじみの pandas, matplotlib で CSV をグラフ化していきます。
import re
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# CSVファイルを読み込む
df = pd.read_csv('PerfLogging_000001.csv', index_col=0, parse_dates=True)
# ヘッダーを変更
headers_list = df.columns.tolist()
new_headers = []
for header in headers_list:
# 正規表現で文字を抽出
match = re.search(r'\((\d+),(\w+)\)', header)
if match:
new_headers.append(f"CPU{match.group(1)},{match.group(2)}")
else:
new_headers.append('Overall')
df.columns = new_headers
# データフレームの整理
df.index.name = 'Date'
df.fillna(' ', inplace=True)
df.replace(' ', '0.0', inplace=True)
df = df.astype('float64', errors='ignore')
# データフレームの列数に応じてサブプロットの数を決定
num_columns = len(df.columns)
num_rows = (num_columns + 1) // 2
# プロットの設定(2列のレイアウト)
fig, axes = plt.subplots(num_rows, 2, figsize=(9, 21))
axes = axes.flatten() # 2D配列を1Dに変換
# 各列ごとにグラフを作成
for i, column in enumerate(df.columns):
df[column].plot(ax=axes[i], title=column)
axes[i].xaxis.set_major_formatter(mdates.DateFormatter('%m/%d %H:%M:%S'))
axes[i].set_xlabel('Date')
axes[i].set_ylabel('CPU Usage (%)')
axes[i].set_ylim(0, (df.max().max() // 50 + 1) * 50)
axes[i].grid(True)
# 不要なサブプロットを削除
for j in range(i + 1, len(axes)):
fig.delaxes(axes[j])
# PNGファイルとして保存
plt.tight_layout()
plt.savefig('plot.png', dpi=100)
CPU 使用率が 100% を超えていても異常ではありません。詳細は、Microsoft の Web サイトに書いてあります。
CPU usage over 100% if Intel Turbo Boost is active
https://learn.microsoft.com/en-us/troubleshoot/windows-client/performance/cpu-usage-exceeds-100
さいごに
昔は AI 関連で pandas と matplotlib を多用していましたが、最近、また必要になったので復習のつもりでやってみました。もっとこうしたほうがいいよというのがあれば教えてください。