次の方法で共有


PENABLECALLBACK コールバック関数 (evntprov.h)

ETW イベント プロバイダーは、必要に応じて EnableCallback 関数を定義して、構成変更通知を受信します。 PENABLECALLBACK 型は、このコールバック関数へのポインターを定義します。 EnableCallback は、アプリケーション定義関数名のプレースホルダーです。

構文

PENABLECALLBACK Penablecallback;

void Penablecallback(
  [in]           LPCGUID SourceId,
  [in]           ULONG IsEnabled,
  [in]           UCHAR Level,
  [in]           ULONGLONG MatchAnyKeyword,
                 ULONGLONG MatchAllKeyword,
  [in, optional] PEVENT_FILTER_DESCRIPTOR FilterData,
  [in, optional] PVOID CallbackContext
)
{...}

パラメーター

[in] SourceId

プロバイダーを有効または無効にする呼び出し元によって指定された GUID。

値は、EnableTraceEx の SourceId パラメーター、または EnableTraceEx2 に渡されるENABLE_TRACE_PARAMETERSSourceId フィールドから取得されます。

注意

SourceId は、EnableTraceEx または EnableTraceEx2 API の呼び出しで指定されたセッションの値です。 セッションの GUID と同じである場合とそうでない場合があります。

SourceId は、通知にソース識別子がないいくつかのシナリオで GUID_NULL に設定されます。 たとえば、トレース セッションでプロバイダーが起動する前にプロバイダーが有効になっている場合、プロバイダーが停止しているとき、またはトレース コントローラーが SourceId を指定せずに EnableTrace API を呼び出した場合に発生する可能性があります。

[in] IsEnabled

この通知に対応する ControlCode を示します。 次のいずれかの値を指定できます。

意味
EVENT_CONTROL_CODE_DISABLE_PROVIDER (0) プロバイダーを有効にしたセッションはありません。
EVENT_CONTROL_CODE_ENABLE_PROVIDER (1) 1 つ以上のセッションでプロバイダーが有効になっています。
EVENT_CONTROL_CODE_CAPTURE_STATE (2) セッションは、プロバイダーが状態情報をログに記録することを要求しています。 プロバイダーは通常、プロバイダーの状態を含むイベントを書き込むことで応答します。

注意

IsEnabled の値は、このイベントをトリガーした EnableTrace API に渡される ControlCode と同じでない場合があります。 たとえば、2 つのセッションでこのプロバイダーが有効になっており、1 つのセッションで を呼び出 EnableTraceEx2(..., EVENT_CONTROL_CODE_DISABLE_PROVIDER, ...)してこのプロバイダーを無効にした場合、プロバイダーは IsEnabled が に EVENT_CONTROL_CODE_ENABLE_PROVIDER 設定された通知を受け取ります。これは、プロバイダーがもう一方のセッションで引き続き有効になっているためです。

DISABLE_PROVIDER通知を受け取った後、プロバイダーはすべてのイベントを無効にしてパフォーマンスを最適化できます。 ENABLE_PROVIDER通知を受信した後、プロバイダーはイベントの書き込みを有効にする必要があります。 また、Level、MatchAnyKeyword、MatchAllKeyword フィルターの値を記録し、フィルターを渡すイベントのみを書き込むことで、パフォーマンスを最適化することもできます ( 解説で説明します)。 CAPTURE_STATE通知を受け取った後、プロバイダーは適切なアクションを実行し、通常はコンポーネントの構成または状態を記述するイベントを書き込みます。

プロバイダーは、認識またはサポートされていない IsEnabled 値を持つ通知を無視する必要があります。

[in] Level

プロバイダーが書き込む必要があるイベントの詳細度を示す 値。 コントロール コード EVENT_CONTROL_CODE_ENABLE_PROVIDERを使用して呼び出された場合、プロバイダーは Level 値を記録し、その後、イベントの詳細レベルが記録された Level より大きいイベントをスキップする必要があります。つまり、イベントは、

eventDescriptor.Level <= recorded.Level

通知の Level は、このイベント プロバイダーの GUID を使用した EnableTrace、EnableTraceEx、または EnableTraceEx2呼び出しでトレース コントローラーによって指定されたレベルの最大値です。 つまり、複数のセッションが異なる詳細レベルでこのイベント プロバイダーからのイベントを記録している場合、EnableCallback 通知の Level パラメーターは、レベルの最高 (最も詳細) に設定されます。

[in] MatchAnyKeyword

プロバイダーが書き込む必要があるイベントのカテゴリを指定するビットマスク値。 コントロール コード EVENT_CONTROL_CODE_ENABLE_PROVIDERを使用して呼び出されると、プロバイダーは MatchAnyKeyword 値を記録し、その後、イベントのキーワード (keyword)が 0 以外であり、記録された MatchAnyKeyword のビットがないイベントをスキップする必要があります。つまり、イベントは、記録された場合にのみ書き込む必要があります

eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAnyKeyword) != 0

通知の MatchAnyKeyword は、このイベント プロバイダーの GUID に対する EnableTrace、EnableTraceEx、およびEnableTraceEx2 の呼び出しでトレース コントローラーによって指定された match-any-keywords (enable flags) の和集合 (OR) です。 つまり、複数のセッションが異なる match-any-キーワード (keyword) フィルターを使用してこのイベント プロバイダーからのイベントを記録している場合、EnableCallback 通知の MatchAnyKeyword パラメーターは、セッションの match-any-キーワード (keyword) フィルターのビットごとのOR値に設定されます。

MatchAllKeyword

プロバイダーが書き込む必要があるイベントのカテゴリを指定するビットマスク値。 コントロール コード EVENT_CONTROL_CODE_ENABLE_PROVIDERで通知を受け取った場合、プロバイダーは MatchAllKeyword 値を記録し、その後、イベントのキーワード (keyword)が 0 以外であり、記録された MatchAllKeyword のすべてのビットがないイベントをスキップする必要があります。つまり、イベントは、イベントを書き込む必要がある場合にのみ書き込む必要があります

eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAllKeyword) == recorded.MatchAllKeyword

通知の MatchAllKeyword は、このイベント プロバイダーの GUID に対する EnableTraceEx と EnableTraceEx2 の呼び出しでトレース コントローラーによって指定された match-all-keywords の disjunction (AND) です。 つまり、複数のセッションが異なる match-all-キーワード (keyword) フィルターを使用してこのイベント プロバイダーからのイベントを記録している場合、EnableCallback 通知の MatchAllKeyword パラメーターは、セッションの match-all-キーワード (keyword) フィルターのビットごとのAND値に設定されます。

[in, optional] FilterData

イベント プロバイダーのフィルター データを含む EVENT_FILTER_DESCRIPTOR へのポインター。

各セッションで指定できるフィルターは 1 つだけです。 コールバック通知のフィルター記述子には、プロバイダーを有効にするときにフィルター データを指定した各セッションのフィルターが 1 つ含まれます。

フィルター データは、コールバック内でのみ有効です。 コールバックが返された後にデータが必要になる場合、プロバイダーはデータのローカル コピーを作成する必要があります。

[in, optional] CallbackContext

コールバックのコンテキスト。 これは、イベント プロバイダーが EventRegister を呼び出したときに使用された CallbackContext パラメーターの値です。

戻り値

なし

解説

構成変更通知を必要とする ETW イベント プロバイダーは、EventRegister 経由で登録するときに、EnableCallback 実装へのポインターを提供する必要があります。 ETW は、プロバイダーが関係するトレース セッションの構成を変更すると、プロバイダーの EnableCallback 関数を呼び出します。 たとえば、トレース セッション コントローラーが EnableTraceEx2 を使用してトレースを構成したり、 ControlTrace を介してトレースを停止したりすると、ETW はプロバイダーの EnableCallback 関数を呼び出し、結果の構成を更新します。

注意

ほとんどのイベント プロバイダーは、 EnableCallback を 直接実装しません。 代わりに、ほとんどのイベント プロバイダーは、独自の EnableCallback 実装を提供し、 EventRegisterEventWrite、および EventUnregister の呼び出しをラップする ETW フレームワークを使用して実装されます。 たとえば、 イベント マニフェストを記述 し、 メッセージ コンパイラ を使用してイベントの C/C++ コードを生成したり、 TraceLogging を 使用してマニフェストが不要になる場合があります。 ETW フレームワークは通常、通知Levelの 、、MatchAnyKeywordおよび の値を記録する EnableCallback 関数を実装しMatchAllKeyword、フレームワークは記録された値を自動的に使用してイベントをフィルター処理します。 ユーザーがカスタム通知処理を必要とする場合、ETW フレームワークでは通常、ユーザー指定のコールバックの呼び出しがサポートされます。 たとえば、 TraceLoggingProvider.h では、 TraceLoggingRegisterEx を使用して通知コールバックを指定できます。

重要

プロバイダーの EnableCallback 関数は、可能な限り単純である必要があります。 必要な情報を記録し、すぐに返す必要があります。 実行時間の長いコールバック関数は、 EnableTraceEx2ControlTrace などの ETW セッション制御 API で遅延を引き起こす可能性があります。 コールバック関数は、プロセスのローダー ロックを必要とする処理を行ってはなりません。つまり、 LoadLibrary または FreeLibrary を直接または間接的に呼び出してはなりません。 コールバック関数は、ロック時にブロックすることはできません。 コールバック関数は、ロックをブロックした場合、または StartTrace、ControlTraceEnableTrace などの ETW セッション制御 API を呼び出すと、デッドロックが発生する可能性があります。

通知コールバックを使用すると、プロバイダーがレベル、キーワード、およびその他のフィルターの独自の追跡を実行できるため、イベント プロバイダーをより効率的に実行できます。 フィルターを追跡することで、プロバイダーは有効になっていないイベントを効率的にスキップできます (つまり、プロバイダーはイベント データを準備したり、トレース セッションで不要なイベントに 対して EventWrite を呼び出したりする必要はありません)。

プロバイダーの正しい操作にはフィルター追跡は必要ありません。ETW は、プロバイダーが使用できる EventEnabled 関数と EventProviderEnabled 関数を提供し、ETW EventWrite API は無効なイベントをサイレントに無視します。 ただし、プロバイダーによって実装されたフィルター追跡は、 EventEnabled または EventProviderEnabled の呼び出しよりも効率的です。

通知コールバックを使用すると、プロバイダーはトレース セッションからの "キャプチャ状態" 要求を処理することもできます。 キャプチャ状態要求は、通常、プロバイダーからのイベントの記録を開始するときにトレース セッションによって送信されます。 キャプチャ状態がプロバイダーによってサポートされている場合は、状態情報 (要求前のコンポーネントの操作に関する構成情報や概要統計など) をログに記録することで、キャプチャ状態要求に応答する可能性があります。

ETW がコールバックに渡す Level 値は、実行中のトレース セッションでこのイベント プロバイダーに対して指定された最も高い (最も詳細な) レベルの値です。 たとえば、セッション A で警告 (レベル 3) イベントに対してこのプロバイダーを有効にした後、セッション B でプロバイダーがクリティカル (レベル 1) イベントを有効にした場合、コールバックの Level 値は 1 ではなく 3 になります。

同様に、 MatchAnyKeywordMatchAllKeyword の値は、イベント プロバイダーを有効にしたすべてのセッションの構成から計算された複合値です。 MatchAnyKeyword は、セッションの EnableFlags/MatchAnyKeyword 設定の OR です。 MatchAllKeyword は、セッションの MatchAllKeyword 設定の AND です。

プロバイダーの EnableCallback 関数がプロバイダーの Enabled、Level、MatchAnyKeyword、および MatchAllKeyword の状態をキャプチャしている場合、プロバイダーは、次のような関数を使用してイベントを記述する必要があるかどうかを判断できます。

BOOL MyProviderEventEnabled(
    _In_ const MY_PROVIDER_STATE* pProvider,
    _In_ const EVENT_DESCRIPTOR* pEvent)
{
    return
        pProvider->Enabled &&
        pEvent->Level <= pProvider->Level &&
        (pEvent->Keyword == 0 || (
            (pEvent->Keyword & pProvider->MatchAnyKeyword) != 0 &&
            (pEvent->Keyword & pProvider->MatchAllKeyword) == pProvider->MatchAllKeyword
        ));
}

要件

   
サポートされている最小のクライアント Windows Vista [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows Server 2008 [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー evntprov.h

関連項目

EventRegister

EnableTrace

EnableTraceEx2