イベント ビューアー

パフォーマンス プロファイラーでは、アプリの実行中に診断情報を収集してから、収集した情報を事後分析のようにアプリの停止後に調査できます。

汎用イベント ビューアーには、モジュールの読み込み、スレッドの開始、システムの構成などのイベントの一覧を使用して、アプリのアクティビティが表示されます。 このビューを使用すると、Visual Studio プロファイラー内でのアプリの動作を診断しやすくなります。

セットアップ

  1. Alt + F2 キーを押して Visual Studio でパフォーマンス プロファイラーを開きます。

  2. [イベント ビューアー] チェック ボックスをオンにします。

    The Events Viewer check box selected

  3. [開始] ボタンを選択してツールを実行します。

  4. ツールの実行が開始されたら、アプリをプロファイリングするシナリオを完了します。 次に、 [収集の停止] を選択するかアプリを閉じてデータを確認します。

    A window showing Stop collection

ツールの効率を向上させる方法の詳細については、「プロファイラー設定の最適化」を参照してください。

データを理解する

An event viewer trace

列名 説明
プロバイダー名 イベント ソース
Event Name プロバイダーによって指定されたイベント
Text イベントのプロバイダー、イベント名、および ID の説明
タイムスタンプ (ミリ秒) イベントが発生した時間
プロバイダー GUID イベント プロバイダーの ID
イベント ID イベントの ID
プロセス ID イベントが発生したプロセス (わかっている場合)
プロセス名 プロセスの名前 (アクティブに実行されている場合)
スレッド ID イベントが発生したスレッドの ID (わかっている場合)

列が既定で見つからない場合は、既存の列ヘッダーのいずれかを右クリックし、追加する列を選択します。

Adding columns to the event viewer

イベントを選択すると、[追加のプロパティ] ウィンドウが表示されます。 [共通プロパティ] には、すべてのイベントで表示されるプロパティの一覧が表示されます。 [ペイロードのプロパティ] には、イベントに固有のプロパティが表示されます。 イベントによっては、[スタック] も表示される可能性があります。

The event viewer showing stacks

データを整理する

[テキスト] 列を除くすべての列は並べ替え可能です。

The event viewer trace

イベント ビューアーには、一度に最大 20,000 件のイベントが表示されます。 関心のあるイベントに焦点を合わせるために、[イベント フィルター] を選択することで、イベントの表示をフィルター処理できます。 また、各プロバイダーで発生したイベントの合計数の割合を確認することもできます。この情報により、時間が費やされている箇所の内訳を確認できます。 1 つのイベント フィルターにマウス ポインターを合わせると、以下を示すツールヒントが表示されます。

  • Event name
  • Provider
  • GUID
  • イベントの合計数に対する割合
  • イベント数

The event viewer event filter

プロバイダー フィルターでは、各プロバイダーで発生したイベントの合計数に対する割合が表示されます。 1 つのプロバイダーにマウス ポインターを合わると、プロバイダー名、イベントの合計数に対する割合、およびイベント数を示す同様のツールヒントが表示されます。

The event viewer provider filter

カスタム ETW イベントを有効にする

カスタム ETW イベントを使用してコードをインストルメント化し、イベント ビューアーに表示することができます。 カスタム イベントを有効にするには、次のようにします。

  1. カスタム イベント コードをビルドします。

    このセクションの最後に、C++ カスタム イベント コードの例が示されています。

  2. パフォーマンス プロファイラーを開き (Alt + F2 キー)、イベント ビューアーを有効にして、その横にある [設定] アイコン (歯車アイコン) を選択します。

    Screenshot of the events viewer settings icon.

  3. ダイアログ ボックスで、[追加のプロバイダー] の最初の行を有効にし、次のいずれかの操作を行います。

    • ネイティブ カスタム イベント コードの場合は、カスタム イベント コードの GUID に基づいて [プロバイダー GUID] を設定し、[プロバイダー名] の値を空のままにするか、既定値を使用します。

    • C# カスタム イベント コードの場合は、イベント コードを宣言するときに使用したのと同じ [プロバイダー名] の値を設定します。 この名前はバックグラウンドで GUID に変換されるため、[プロバイダー GUID] は空のままにします。

      ネイティブ カスタム イベントの場合、行は次の図のようになるはずです。

      Screenshot of the events viewer settings.

  4. [OK] を選択します。

    カスタム イベントは、診断トレースを収集して開くと、イベント ビューアーに表示されます。 次の図は、カスタム イベントのみを表示するようにフィルター処理が設定されたイベント ビューアーのカスタム イベントを示しています。

    Screenshot of the events viewer showing custom events.

C++ のカスタム イベント コードの例を以下に示します。

#include <Windows.h>
#include <evntprov.h>
#include <iostream>
#include <thread>

// This GUID must be regenerated so it is unique for your provider
// {7369B7AC-64EB-4618-B6B6-C8442B12E8F2}
GUID customEventProvider = { 0x7369b7ac, 0x64eb, 0x4618, { 0xb6, 0xb6, 0xc8, 0x44, 0x2b, 0x12, 0xe8, 0xf2 } };
REGHANDLE _customEventProviderRegHandle = 0;

// Id, Version, Channel, Level, OpCode, Task, Keyword
const EVENT_DESCRIPTOR CustomEventDescriptor = { 1, 0, 0, 0, 0, 0, 1 };

int main()
{
    // Register the provider
    ULONG res = ::EventRegister(&customEventProvider, nullptr, nullptr, &_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    byte data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
    EVENT_DATA_DESCRIPTOR eventData[1];
    ::EventDataDescCreate(&(eventData[0]), &data, sizeof(data));

    for (int i = 0; i < 10; ++i)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        ::EventWrite(_customEventProviderRegHandle, &CustomEventDescriptor, _countof(eventData), eventData);
        std::cout << "Wrote event\n";
    }

    res = ::EventUnregister(_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    return 0;
}