PowerShellとPythonで性能情報を取得する

たまに性能情報を取得したいことがありますが、スクリプトでできると便利ですよね。

もくじ:

はじめに

Windowsでよくある実装はPDH (Performance Data Helper)や.NetでSystem.Diagnotics (PerformanceCounterクラス)を使う方法です。詳しくは調べていませんが、おそらく叩いているDLLは同じ。

PowerShellを使う場合には.Netでもいいのですが、WMI (Windows Management Instruments)か最近のバージョンでサポートされているGet-Counterコマンドレットが使いやすいと思います。

一方で、Pythonで性能取得と言えばpsutilモジュール。さすがにWindowsでもLinuxでもクロスプラットフォームで使えます。
厳密には色々違いはあるものの、よくある性能情報の取得がサポートされています。

下記はpsutilとWMIオブジェクトで取得できる主な性能値を列挙したものです。だいたい同じような性能値を並べたつもりですが、やはり厳密には同じものにはなりませんね。

カテゴリ 項目 Python (psutil) PowerShell (Win32_PerfFormattedData…)
CPU 使用率[%] .cpu_percent ..._PerfOS_Processor.PercentProcessorTime
メモリ 利用可能量[Byte] .virtual_memory.available ..._PerfOS_Memory.AvailableBytes
割り当て済み[Byte] .virtual_memory.used ..._PerfOS_Memory.CommittedBytes
割り当て率[%] .virtual_memory.percent ..._PerfOS_Memory.PercentCommittedBytesInUse
ディスク 使用容量率[%] .disk_usage
空き容量率[%] ..._PerfDisk_LogicalDisk.PercentFreeSpace
Write量[Bytes] .disk_io_counters.write_bytes
Read量[Bytes] .disk_io_counters.read_bytes
Write速度[Bytes/sec] ..._PerfDisk_LogicalDisk.DiskWriteBytesPersec
Read速度[Bytes/sec] ..._PerfDisk_LogicalDisk.DiskReadBytesPersec
Write数 .disk_io_counters.write_count
Read数 .disk_io_counters.read_count
Write時間[sec] .disk_io_counters.write_time
Read時間[sec] .disk_io_counters.read_time
Write応答時間[msec] ..._PerfDisk_LogicalDisk.AvgDisksecPerWrite
Read応答時間[sec] ..._PerfDisk_LogicalDisk.AvgDisksecPerRead
NIC 送信量[Bytes] .net_io_counters.bytes_sent (Get-NetAdapterStatistics.SentBytes)
受信量[Bytes] .net_io_counters.bytes_recv (Get-NetAdapterStatistics.ReceivedBytes)
送信速度[Bytes] ..._Tcpip_NetworkInterface.BytesSentPersec
受信速度[Bytes] ..._Tcpip_NetworkInterface.BytesReceivedPersec
システム 起動時刻[epoch] .boot_time
起動時間[sec] ..._PerfOS_System.SystemUpTime

ディスクの容量に関してはpsutilが使用率(使っているほう)、WMI経由では空き容量(残り使用可能なほう)です。足すと100%になる関係ですね。
また、psutilでは総じて述べ積算量が取得できる一方、WMI経由(またはパフォーマンスカウンタ)では単位時間あたりの量(速度)が取得できたりします。
なお、Get-NetAdapterStatisticsコマンドレットがサポートされているのはWindows 8世代以降(Server 2012以降)のようです。

PowerShellでの情報取得

性能情報を取得するためのWMIオブジェクトはおおよそWin32_PerfFormattedData_...で始まるものです。
上記の表では長くなるので分けて書いてありますが、例えばメモリの情報はWin32_PerfFormattedData_PerfOS_Memoryでアクセスできます。
取得結果の各パラメータを参照すれば性能値が取得できます。

メモリの場合は上の例のようにひとつのインスタンスのみですが、マルチコアのCPUなどさらに複数の下位インスタンスに分かれる場合があるので、合計値(_Total)など必要に応じて選ぶとよいと思います。

その他、Windowsで提供されているパフォーマンスカウンタの類はパフォーマンスモニター(管理ツール→システムツール→パフォーマンスで表示できるもの↓)で表示させることができるので、何が利用できるか調べたい場合に活用できます。

性能取得系のコマンドレットはWindows7(Server 2008R2)以降、いくつか追加されているので、最近のバージョンでは比較的快適にできたりします。

特にディスクの応答時間など、短い時間で急激に値が変わるものや、ミリ秒など単位が小さいものについてはWMIオブジェクトを参照するよりもGet-Counterコマンドレットを使って複数サンプリング&平均値を使う方法がより実用的です。

下記の例は複数回(-MaxSamples)、一定のインターバル(-SampleInterval)で測定値を取得したのち、集約して平均値や最大値を使う(Measure-ObjectSelect-Object)という記述になります。

Get-Counterコマンドレットで指定できるカウンター(-Counter)はパフォーマンスモニターなどでも使う文字列で、下記(論理ディスクの例)のようにして利用可能なものを調べることができます。

一連の処理を書いた例は下記のようなものです。

また、この結果はこんな感じになります。

psutilを使ったPythonでの情報取得

導入されていない場合はpip経由でインストールすることができます。

たまにインストールに失敗する場合があり、ビルドツール関連のパッケージを追加すると解決するかも知れません。下記はUbuntuでの例です。

以下はpsutilを使った例です。

おわり。

『PowerShellとPythonで性能情報を取得する』へのコメント

  1. 名前:えんでぃ 投稿日:2018/10/08(月) 09:53:49 ID:80605ef6d 返信

    Windows用ツールやAnsibleの記事など、いくつか拝見させていただきました。
    どれも内容が深く、とても勉強になりました。

    ブックマークさせていただきましたので、これからもお世話になります。