[C#] パフォーマンスモニタ(perfmon)で見るような情報をプログラムで取得する

# もくじ

https://tera1707.com/entry/2022/02/06/144447

# やりたいこと

パフォーマンスモニタで見るような情報を、自前のプログラムの中で見ていろいろやりたい。
※自前のプログラムの中ではグラフ書いたりはしなくていいが、パフォーマンスに関する値だけほしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/345aa8d4-323c-4a28-cbf8-f084b04b971d.png)
[Win+R]に「perfmon」と入れて出てきたウインドウで「パフォーマンスモニター」を選ぶと上記が開く。

# やり方

`System.Diagnostics`の`PerformanceCounter`クラスを使う。

# サンプル

1秒おきに、CPUの使用率などの情報を取り、画面に表示する。

```cs
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace DiagnosticsTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var counterList = new List<(string machine, string category, string counter, string instance)>();
            var pcList = new List<PerformanceCounter>();

            // コンピュータ名 = "." はローカルコンピュータを表す。コンピュータ名は省略可能（省略時は"."）
            // Memory/Available MBytesのようにインスタンスを指定できない項目は、インスタンスを空文字にする

            // 取りたい情報を並べる
            counterList.Add((".", "Processor", "% Processor Time", "_Total"));
            counterList.Add((".", "Network Interface", "Bytes Total/Sec", "Realtek PCIe GBE Family Controller"));
            counterList.Add((".", "PhysicalDisk", "% Disk Time", "_Total"));
            counterList.Add((".", "Memory", "Available MBytes", ""));
            counterList.Add((".", "Process", "Working Set", "_Total"));
            counterList.Add((".", "Process", "IO Data Bytes/Sec", "_Total"));

            // エラーチェック後、PerformanceCounterオブジェクトの作成を作成
            counterList.ForEach((x) =>
            {
                if (!PerformanceCounterCategory.Exists(x.category, x.machine))
                {
                    //カテゴリが存在するか確かめる
                    Console.WriteLine("登録されていないカテゴリです：" + x.category);
                }
                else if (!PerformanceCounterCategory.CounterExists(x.counter, x.category, x.machine))
                {
                    //カウンタが存在するか確かめる
                    Console.WriteLine("登録されていないカウンタです：" + x.counter);
                }
                else
                {
                    //PerformanceCounterオブジェクトの作成
                    pcList.Add(new PerformanceCounter(x.category, x.counter, x.instance, x.machine));
                }
            });

            //1秒おきに値を取得する
            while (true)
            {
                Console.Clear();

                pcList.ForEach((x) =>
                {
                    //計算された値を取得し、表示する
                    Console.WriteLine(x.CategoryName + " / " + x.CounterName + "：" + x.NextValue());
                });

                Console.WriteLine("");

                //1秒待機する
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}

```

# メモ

上のやり方で情報をとれることは分かったが、いったいどういう情報が取れるのか、また、取れる情報は「カウンターの追加」画面を見たら一覧が出てるっぽいが、一覧の中の項目それぞれが一体何なのか？(例えば「Process」の「Working Set」が一体なんなのか？)がわからず、調べるのに手間取った。そのときのメモ。

## 取れる情報について

パフォーマンスモニターで取れる情報(たぶん≒`PerformanceCounter`クラスで取れる情報)は、「カウンターの追加」の画面に一覧として出てる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/1a4fbba5-6d3b-0e80-1932-7c9a18558ac1.png)

`PerformanceCounter`クラスには、マシン名、カテゴリ名、インスタンス名を指定するが、それぞれ下記のようにカウンターの追加画面には表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/28dafc69-7f1f-5e16-c50f-f1c64bd5db21.png)
メモするまでもないかもだが、それぞれ下記のようなイメージ。

|項目|説明|
|:--|:--|
|マシン名|どのPCの情報をとるかということ。<br>(試してないが、リモートPCの情報も見れるらしい)|
|カテゴリ名|大項目。<br>CPUごとの情報を取りたければ`Processor`、<br>プロセスごとの情報を取りたければ`Process`、等。|
|カウンタ名|小項目。<br>カテゴリの中のどういう情報か、を示すもの。<br>CPUなら使用率(`% Processor Time`)、<br>プロセスならメモリ使用量(`Working Set`)、等。|
|インスタンス名|測定対象をどれにするか、ということ。<br>CPUなら複数あるCPUのうちのどれにするか、<br>プロセスなら今起動してるプロセス(アプリ)のどれにするか、等。<br>_Totalを選ぶと、全部の合計、だったりする。|

## カウンターにどんなものがあるか

なにげにハマった内容。

パフォーマンスモニタに出てくる情報を取れることは分かったが、どんな情報をとれるのか、を知りたい。
MSDocsでその一覧を探したが、全然出てこない。
(いくつか、主だったところをいくつかわかりやすく紹介してくれているサイトはあった。下の「参照」に挙げている)

結局一覧は見つけられなかったが、「カウンターの追加」の画面に**「説明を表示する」**というチェックがあり、それをチェックすると、説明がでてくることを発見。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/e63a02e8-0d08-77e4-e749-531230b8a610.png)
わかりやすい説明ではないが、これを見てどういう内容かはだいたいわかりそう。
これでどういうカウンタがあるか調べることにした。


# 参考

PerformanceCounterクラス(MSDocs)

https://docs.microsoft.com/ja-jp/dotnet/api/system.diagnostics.performancecounter?view=net-5.0

パフォーマンスカウンタ一つ一つの項目の説明(別の、似た内容の説明?サーバーがどうとか言ってる...)
msdocs内を「Processor Time 」とかで調べるとでてきた内容。

https://docs.microsoft.com/ja-jp/previous-versions/office/exchange-server-analyzer/aa998175(v=exchg.80)

めちゃわかりやすいカウンタの説明

https://azuread.net/archives/3207

private bytesとはなにか？を見たページ

https://blog.systemjp.net/entry/2013/10/12/211541

カウンタ解説

https://sites.google.com/site/putise/performance/windows-performance

サンプルプログラム(CPU使用率の表示)

https://smdn.jp/programming/netfx/performancecounter/0_counter/