EnableTraceEx2 関数 (evntrace.h)
トレース セッション コントローラー EnableTraceEx2 を呼び出して、ETW イベント プロバイダーがトレース セッションにイベントを記録する方法を構成します。
この関数は、
構文
ULONG WMIAPI EnableTraceEx2(
CONTROLTRACE_ID TraceId,
[in] LPCGUID ProviderId,
[in] ULONG ControlCode,
[in] UCHAR Level,
[in] ULONGLONG MatchAnyKeyword,
[in] ULONGLONG MatchAllKeyword,
[in] ULONG Timeout,
[in, optional] PENABLE_TRACE_PARAMETERS EnableParameters
);
パラメーター
TraceId
[in] ProviderId
構成するイベント プロバイダーのプロバイダー ID (制御 GUID)。
[in] ControlCode
次のいずれかの制御コードを指定できます。
価値 | 意味 |
---|---|
EVENT_CONTROL_CODE_DISABLE_PROVIDER | セッションがプロバイダーからイベントを受信しないように、セッション構成を更新します。 |
EVENT_CONTROL_CODE_ENABLE_PROVIDER | セッション構成を更新して、セッションがプロバイダーから要求されたイベントを受信するようにします。 |
EVENT_CONTROL_CODE_CAPTURE_STATE | プロバイダーが状態情報をログに記録することを要求します。 |
[in] Level
プロバイダーが書き込むイベントの最大レベルを示す値。 通常、プロバイダーは、
Microsoft では、次に示すように、レベル 1 から 5 のセマンティクスを定義します。 値を小さくすると、より重大なイベントが示されます。
Level の各値により、指定されたレベルとより厳しいレベルがすべて有効になります。 たとえば、TRACE_LEVEL_WARNING
を指定すると、コンシューマーは警告、エラー、重大なイベントを受け取ります。
価値 | 意味 |
---|---|
TRACE_LEVEL_CRITICAL (1) | 異常終了イベントまたは終了イベント |
TRACE_LEVEL_ERROR (2) | 重大なエラー イベント |
TRACE_LEVEL_WARNING (3) | 割り当てエラーなどの警告イベント |
TRACE_LEVEL_INFORMATION (4) | エラー以外の情報イベント |
TRACE_LEVEL_VERBOSE (5) | 詳細な診断イベント |
TRACE_LEVEL
定数は、evntrace.hで定義されます。 同等の WINMETA_LEVEL
定数は、winmeta.hで定義されます。
[in] MatchAnyKeyword
プロバイダーが書き込むイベントのカテゴリを決定するキーワードの 64 ビット ビットマスク。 通常、プロバイダーは、イベントのキーワード ビットがこの値に設定されているビットの
[in] MatchAllKeyword
プロバイダーが書き込むイベントを制限するキーワードの 64 ビット ビットマスク。 通常、プロバイダーは、イベントのキーワード ビットがこの値に設定されているすべてのビット
この値は、多くの場合、0 に設定されます。
[in] Timeout
Timeout が 0 の場合、この関数はプロバイダーの構成を非同期的に開始し、すぐに戻ります (つまり、プロバイダーのコールバックが完了するのを待たずに戻ります)。
それ以外の場合、この関数はプロバイダーの構成を開始し、すべてのプロバイダー コールバックの完了を待機するなど、構成の完了の待機を開始します。 指定したタイムアウトの前に構成が完了した場合、この関数は ERROR_SUCCESSを返します。 それ以外の場合、この関数は ERROR_TIMEOUTを返します。
永遠に待つには、無限
[in, optional] EnableParameters
プロバイダーを有効にするために使用されるトレース パラメーター。 詳細については、ENABLE_TRACE_PARAMETERSを参照してください。
戻り値
関数が成功した場合、戻り値は ERROR_SUCCESS。
関数が失敗した場合、戻り値は
ERROR_INVALID_PARAMETER
パラメーターが正しくありません。
これは、次のいずれかに該当する場合に発生する可能性があります。
ProviderId は NULLです。 TraceHandle は 0です。
ERROR_TIMEOUT
タイムアウト値は、有効化コールバックが完了する前に期限切れになりました。 詳細については、Timeout パラメーターを参照してください。
ERROR_INVALID_FUNCTION
プロバイダーが登録されていない場合、レベルを更新することはできません。
ERROR_NO_SYSTEM_RESOURCES
プロバイダーを有効にできるトレース セッションの数を超えました。
ERROR_ACCESS_DENIED
管理者特権を持つユーザー、
Performance Log Users
グループ内のユーザー、LocalSystem
、LocalService
、またはNetworkService
として実行されているサービスのみが、イベント プロバイダーをクロスプロセス セッションに対して有効にすることができます。 制限付きユーザーにイベント プロバイダーを有効にする権限を付与するには、イベント プロバイダーをグループに追加するか、EventAccessControl 参照してください。 Windows XP と Windows 2000: 誰でもイベント プロバイダーを有効にできます。
備考
イベント トレース コントローラーは、この関数を呼び出して、セッションにイベントを書き込むイベント プロバイダーを構成します。 たとえば、コントローラーはこの関数を呼び出してプロバイダーからのイベントの収集を開始したり、プロバイダーから収集されるイベントのレベルやキーワードを調整したり、プロバイダーからのイベントの収集を停止したりできます。
プロバイダーの有効化動作は、プロバイダーが使用する API によって異なります。
-
RegisterTraceGuids を使用するプロバイダー (たとえば、TMF ベースの WPP または MOF を使用するプロバイダー) は、レガシ有効化システム ("クラシック ETW" と呼ばれることもあります) を使用します。 セッションに対してレガシ プロバイダーが有効または再構成されると、ETW ランタイムはプロバイダーに通知し、レベル、MatchAnyKeyword マスクの下位 32 ビット、およびセッション ID へのアクセスを提供します。 その後、プロバイダーは独自のロジックを使用して、有効にする必要があるイベントを決定し、それらのイベントを指定されたセッションに直接送信します。 実行時に ETW に送信されるイベント データには、イベントのデコード GUID とメッセージ ID が含まれますが、イベントのコントロール GUID、レベル、またはキーワードは含まれません。 ETW は、プロバイダーが必要なアクセス許可を持っていることを確認し、指定されたセッションにイベント データを追加します。
- イベントは制御 GUID、レベル、キーワード情報なしで特定のセッションに直接送信されるため、ETW では、レガシ有効化システムを使用するプロバイダーに対して追加のフィルター処理やルーティングを実行できません。 各イベントは、複数のセッションにルーティングできません。
-
EventRegister を使用するプロバイダー (マニフェスト ベースのプロバイダーや TraceLogging プロバイダーなど) は、最新の有効化システム ("真紅 ETW" とも呼ばれます) を使用します。 セッションに対して最新のプロバイダーが有効または再構成されると、ETW ランタイムは、レベル、64 ビット MatchAnyKeyword マスク、64 ビット MatchAllKeyword マスク、およびトレース コントローラーで指定されたカスタム プロバイダー側フィルター データを使用してプロバイダーに通知します。 その後、プロバイダーは独自のロジックを使用して、有効にする必要があるイベントを決定しますが、ほとんどのプロバイダーは EventProviderEnabledのロジック
複製するだけです。 プロバイダーは、有効なイベントをルーティングのために ETW に送信します。 ETW に送信されるイベント データには、イベントの制御 GUID、メッセージ ID、レベル、キーワードが含まれます。 ETW は、必要に応じて追加のフィルター処理を実行し、イベントを適切なセッションにルーティングします。 - イベントは説明情報を使用して ETW に送信されるため、ETW はセッションにイベントを追加する前に追加のフィルター処理とルーティングを実行できます。 必要に応じて、イベントを複数のセッションにルーティングできます。
最新の有効化システムを使用するプロバイダー (つまり、
- スキーマ化されたフィルター処理 - これは、プロバイダー側のフィルター処理とも呼ばれる従来のフィルター設定です。 コントローラーは、フィルターのカスタム セットをバイナリ オブジェクトとして定義し、EnableCallbackFilterDataでプロバイダーに渡します。 これらのフィルターを定義して解釈することは、コントローラーとプロバイダーに必要です。 プロバイダーは、EventWriteExFilter パラメーターを使用して、プロバイダー側のフィルター処理のためにイベントを送信しないセッションを示すことができます。 これには、フィルター処理できるバイナリ オブジェクトの型と形式が定義されていないため、コントローラーとプロバイダーの密接な結合が必要です。 TdhEnumerateProviderFilters 関数を使用して、マニフェストで定義されているフィルターを取得できます。
- スコープ フィルター - 特定のプロバイダーは、スコープ フィルターで指定された条件を満たしているかどうかに基づいて、セッションに対して有効または無効になります。 プロセス ID (PID)、実行可能ファイル名、アプリ ID、アプリ パッケージ名に基づくフィルター処理を可能にするスコープ フィルターには、いくつかの種類があります。 この機能は、Windows 8.1、Windows Server 2012 R2 以降でサポートされています。
- Stackwalk フィルタリング - これは、特定のイベント ID セットまたは (TraceLogging イベントの場合) イベント名に対してのみスタック ウォークを実行するように ETW に通知します。 この機能は、Windows 8.1、Windows Server 2012 R2 以降でサポートされています。
- 属性フィルター - マニフェスト プロバイダーの場合、イベントは、レベル、キーワード、イベント ID、イベント名などのイベント属性に基づいてフィルター処理できます。
- イベント ペイロードのフィルター処理 - マニフェスト プロバイダーの場合、イベントは、1 つ以上の述語に基づく論理式を満たすかどうかに基づいて、その場でフィルター処理できます。
手記
ETW では強力なペイロードと属性のフィルター処理がサポートされていますが、イベントは主にフィルター処理ベースのスコープ フィルター、または制御 GUID、レベル、およびキーワードを使用してフィルター処理する必要があります。 通常、プロバイダーは、イベントが生成または ETW に送信される前に、プロバイダーのコードで制御 GUID、レベル、およびキーワードのフィルター処理を直接実行します。 ほとんどのプロバイダーでは、レベルまたはキーワードによって無効になっているイベントは、システムのパフォーマンスにほとんど影響しません。 同様に、スコープ フィルターによって無効にされたプロバイダーは、システムのパフォーマンスにほとんど影響しません。 他の種類のフィルター処理 (ペイロードまたはレベルとキーワード以外の属性に基づく) は、通常、プロバイダーがイベントを生成して ETW ランタイムに送信した後に実行されます。つまり、イベントはシステム パフォーマンス (イベントの準備と ETW への送信に費やされた CPU 時間) に影響を与えます。これは、ETW フィルター処理によってイベントをセッションによって記録すべきでないと判断された場合でも発生します。 この種のフィルター処理は、トレース データ ボリュームの削減にのみ有効であり、トレース CPU のオーバーヘッドを減らすには効果的ではありません。
EnableTraceEx2
フィルター処理を無効にし、ログ セッション内のすべてのプロバイダー/イベントを有効にするには、
EnableTraceEx2 関数に渡される各フィルターは、EVENT_FILTER_DESCRIPTORの Type メンバーによって指定されます。 EVENT_FILTER_DESCRIPTOR 構造体の配列は、EnableParameters パラメーターで EnableTraceEx2 関数に渡される ENABLE_TRACE_PARAMETERS 構造体で渡されます。
各種類のフィルター (特定の 型 メンバー) は、EnableTraceEx2 関数の呼び出しに 1 回だけ表示できます。 フィルターの種類によっては、複数の条件を 1 つのフィルターに含める場合があります。 EnableTraceEx2 の呼び出しに含めることができるフィルターの最大数は、MAX_EVENT_FILTERS_COUNT によって設定されます (Evntprov.h ヘッダー ファイルで定義されています。値は、将来のバージョンの Windows SDK で変更される可能性があります)。
各フィルターの種類には、EVENT_FILTER_DESCRIPTOR 構造体の特定の Type メンバーに基づいて、独自のサイズまたはエンティティの制限があります。 次の一覧は、これらの制限を示しています。
EVENT_FILTER_TYPE_SCHEMATIZED
- フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
- 許可される要素の数: プロバイダーとコントローラーによって定義されます
EVENT_FILTER_TYPE_PID
- フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
- 使用できる要素の数: MAX_EVENT_FILTER_PID_COUNT (8)
EVENT_FILTER_TYPE_EXECUTABLE_NAME
- フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
- 使用できる要素の数: 複数の実行可能ファイル名をセミコロンで区切って含めることができる 1 つの文字列。
EVENT_FILTER_TYPE_PACKAGE_ID
- フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
- 使用できる要素の数: セミコロンで区切られた複数のパッケージ ID を含めることができる 1 つの文字列。
EVENT_FILTER_TYPE_PACKAGE_APP_ID
- フィルター サイズの制限: MAX_EVENT_FILTER_DATA_SIZE (1024)
- 使用できる要素の数: セミコロンで区切られた複数のパッケージ相対アプリ ID (PRAID) を含めることができる 1 つの文字列。
EVENT_FILTER_TYPE_PAYLOAD
- フィルター サイズの制限: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
- 使用できる要素の数: 1
EVENT_FILTER_TYPE_EVENT_ID
- フィルター サイズの制限: 定義されていません
- 使用できる要素の数: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
EVENT_FILTER_TYPE_STACKWALK
- フィルター サイズの制限: 定義されていません
- 使用できる要素の数: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
キーワードはイベント カテゴリを定義します。 たとえば、プロバイダーが InitializationKeyword =
モダン (マニフェスト ベースの または TraceLogging) プロバイダーと共に使用すると、0
の MatchAnyKeyword 値は、MatchAnyKeyword 値 0xFFFFFFFFFFFFFFFF
と同じように扱われます。つまり、すべてのイベント キーワードが有効になります。 ただし、この動作は、レガシ (MOF または TMF ベースの WPP) プロバイダーには適用されません。 レガシ プロバイダーからのすべてのイベント キーワードを有効にするには、MatchAnyKeyword 0xFFFFFFFFFFFFFFFF
に設定します。
イベントのキーワードが 0 の場合、
プロバイダー グループを有効にすることを示すには、EnableParametersの
EnableTraceEx2
プロバイダーが登録されていて、セッションに対して既に有効になっている場合は、
Windows 8.1 では、Windows Server 2012 R2 以降では、イベント ペイロード、スコープ、スタック ウォーク フィルターは、EnableTraceEx2 関数と ENABLE_TRACE_PARAMETERS および EVENT_FILTER_DESCRIPTOR 構造体で使用して、ロガー セッション内の特定の条件でフィルター処理できます。 イベント ペイロード フィルターの詳細については、
EnableTraceEx2では、特殊なシステム トレース プロバイダー イベント
Windows 11 以降では、EnableTraceEx2を使用して、
最大 8 つのトレース セッションで、同じモダン (マニフェスト ベースの または TraceLogging) プロバイダーからイベントを有効にして受信できます。 ただし、レガシ (MOF、TMF ベースの WPP) プロバイダーを有効にできるトレース セッションは 1 つだけです。 複数のセッションでレガシ プロバイダーを有効にしようとすると、2 番目のセッションで同じプロバイダーが有効になると、最初のセッションはイベントの受信を停止します。 たとえば、セッション A がレガシ プロバイダーを有効にした後、セッション B が同じプロバイダーを有効にした場合、セッション B のみがそのプロバイダーからイベントを受信します。
セッションがプロバイダーを無効にするまで、プロバイダーはセッションに対して有効なままになります。 プロバイダーを無効にせずにセッションを開始したアプリケーションが終了した場合、プロバイダーは有効のままです。
マニフェスト ベースのプロバイダーを有効にするために使用されるレベルとキーワードを決定するには、次のいずれかのコマンドを使用します。
- logman クエリ プロバイダー プロバイダー名
- wevtutil gp provider-name
従来のプロバイダーの場合、重大度レベルを文書化し、潜在的なコントローラーで使用できるようにするか、サポートされているフラグを有効にするかは、プロバイダーの責任です。 プロバイダーを任意のコントローラーで有効にする場合、プロバイダーは重大度レベルで 0 を受け入れ、フラグを有効にし、既定のログ記録を実行する要求として 0 を解釈する必要があります (何でも)。
EnableTraceEx2 を使用してクラシック プロバイダーを有効にすると、次の変換が行われます。
Level パラメーターは、EnableTraceでEnableLevel パラメーター設定する場合と同じです。 - MatchAnyKeyword は、EnableTrace で EnableFlag パラメーターを設定する場合と同じですが、キーワード値が 64 ビット値から 32 ビット値に切り捨てられる点が異なります。
ControlCallback コールバックでは、プロバイダーは GetTraceEnableLevel呼び出してレベルを取得し、GetTraceEnableFlags を して有効フラグを取得できます。 - その他のパラメーターは使用されません。
例
次の例は、
#define INITGUID
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <evntrace.h>
#include <tdh.h>
#define MAXIMUM_SESSION_NAME 1024
#define PATH_TO_MANIFEST_FILE L"c:\\ExampleManifest.man"
//
// The following definitions would be found in the include file generated by
// message compiler from the manifest file.
//
// Provider Example-Provider Event Count 2
EXTERN_C __declspec(selectany) const GUID EXAMPLE_PROVIDER = {0x37a59b93, 0xbb25, 0x4cee, {0x97, 0xaa, 0x8b, 0x6a, 0xcd, 0xc, 0x4d, 0xf8}};
//
// Event Descriptors
//
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_1 = { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_1_value 0x1
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_2 = { 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_2_value 0x2
//
// (End of snippet from include file)
//
// Allocate an EVENT_TRACE_PROPERTIES structure and set the needed logging session properties
PEVENT_TRACE_PROPERTIES AllocateTraceProperties(
_In_opt_ PCWSTR LoggerName,
_In_opt_ PCWSTR LogFileName
)
{
PEVENT_TRACE_PROPERTIES TraceProperties = NULL;
ULONG BufferSize;
BufferSize = sizeof(EVENT_TRACE_PROPERTIES) +
(MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);
TraceProperties = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);
if (TraceProperties == NULL) {
printf("Unable to allocate %d bytes for properties structure.\n", BufferSize);
goto Exit;
}
//
// Set the session properties.
//
ZeroMemory(TraceProperties, BufferSize);
TraceProperties->Wnode.BufferSize = BufferSize;
TraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
TraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
TraceProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
(MAXIMUM_SESSION_NAME * sizeof(WCHAR));
if (LoggerName != NULL) {
StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LoggerNameOffset),
MAXIMUM_SESSION_NAME,
LoggerName);
}
if (LogFileName != NULL) {
StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LogFileNameOffset),
MAX_PATH,
LogFileName);
}
Exit:
return TraceProperties;
}
// Free the EVENT_TRACE_PROPERTIES structure previously allocated
VOID FreeTraceProperties(
_In_ PEVENT_TRACE_PROPERTIES TraceProperties
)
{
free(TraceProperties);
return;
}
// Set the values needed in a PAYLOAD_FILTER_PREDICATE for a single payload filter
FORCEINLINE VOID PayloadPredicateCreate(
_Out_ PAYLOAD_FILTER_PREDICATE* Predicate,
_In_ PCWSTR FieldName,
USHORT CompareOp,
PCWSTR Value
)
{
Predicate->FieldName = (PWSTR)FieldName;
Predicate->CompareOp = CompareOp;
Predicate->Value = (PWSTR)Value;
return;
}
int __cdecl wmain()
{
UINT i;
PVOID EventFilters[2];
EVENT_FILTER_DESCRIPTOR FilterDescriptor;
UINT PredicateCount;
PAYLOAD_FILTER_PREDICATE Predicates[3];
ULONG FilterCount;
ULONG Status = ERROR_SUCCESS;
TRACEHANDLE SessionHandle = 0;
PEVENT_TRACE_PROPERTIES TraceProperties;
BOOLEAN TraceStarted = FALSE;
PCWSTR LoggerName = L"MyTrace";
ENABLE_TRACE_PARAMETERS EnableParameters;
ZeroMemory(EventFilters, sizeof(EventFilters));
ZeroMemory(Predicates, sizeof(Predicates));
TraceProperties = NULL;
FilterCount = 0;
//
// Load the manifest for the provider
//
Status = TdhLoadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
if (Status != ERROR_SUCCESS) {
printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
goto Exit;
}
//
// Create predicates that match the following high-level expression:
//
// INCLUDE Example_Event_1 IF
// Example_Event_1.Initiator == "User" AND
// 7 <= Example_Event_1.Level <= 16
//
PredicateCount = 0;
PayloadPredicateCreate(
&Predicates[PredicateCount++],
(PWSTR)L"Initiator",
PAYLOADFIELD_IS,
(PWSTR)L"User");
PayloadPredicateCreate(
&Predicates[PredicateCount++],
L"Level",
PAYLOADFIELD_BETWEEN,
L"7,16");
Status = TdhCreatePayloadFilter(
&EXAMPLE_PROVIDER,
&Example_Event_1,
FALSE, // Match all predicates (AND)
PredicateCount,
Predicates,
&EventFilters[FilterCount++]);
if (Status != ERROR_SUCCESS) {
printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
goto Exit;
}
//
// Create predicates that match the following high-level expression:
// INCLUDE Example_Event_2 IF
// Example_Event_2.Title CONTAINS "UNI" OR
// Example_Event_2.InstanceId == {0E95CFBC-58D4-44BA-BE40-E63A853536DF} OR
// Example_Event_2.ErrorCode != 0 //
PredicateCount = 0;
PayloadPredicateCreate(
&Predicates[PredicateCount++],
L"Title",
PAYLOADFIELD_CONTAINS,
L"UNI");
PayloadPredicateCreate(
&Predicates[PredicateCount++],
L"InstanceId",
PAYLOADFIELD_IS,
L" {0E95CFBC-58D4-44BA-BE40-E63A853536DF}");
PayloadPredicateCreate(
&Predicates[PredicateCount++],
L"ErrorCode",
PAYLOADFIELD_NE,
L"0");
Status = TdhCreatePayloadFilter(
&EXAMPLE_PROVIDER,
&Example_Event_2,
FALSE, // Match any predicates (OR)
PredicateCount,
Predicates,
&EventFilters[FilterCount++]);
if (Status != ERROR_SUCCESS) {
printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
goto Exit;
}
//
// Combine the interim filters into a final filter descriptor.
//
Status = TdhAggregatePayloadFilters(
FilterCount,
EventFilters,
NULL,
&FilterDescriptor);
if (Status != ERROR_SUCCESS) {
printf("TdhAggregatePayloadFilters() failed with %lu\n", Status);
goto Exit;
}
//
// Clean up the interim filters
//
for (i = 0; i < FilterCount; i++) {
Status = TdhDeletePayloadFilter(&EventFilters[i]);
if (Status != ERROR_SUCCESS) {
printf("TdhDeletePayloadFilter() failed with %lu\n", Status);
goto Exit;
}
}
//
// Create a new trace session
//
//
// Allocate EVENT_TRACE_PROPERTIES structure and perform some
// basic initialization.
//
// N.B. LoggerName will be populated during StartTrace call.
//
TraceProperties = AllocateTraceProperties(NULL, L"SystemTrace.etl");
if (TraceProperties == NULL) {
Status = ERROR_OUTOFMEMORY;
goto Exit;
}
TraceProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
TraceProperties->MaximumFileSize = 100; // Limit file size to 100MB max
TraceProperties->BufferSize = 512; // Use 512KB trace buffers
TraceProperties->MinimumBuffers = 8;
TraceProperties->MaximumBuffers = 64;
Status = StartTraceW(&SessionHandle, LoggerName, TraceProperties);
if (Status != ERROR_SUCCESS) {
printf("StartTrace() failed with %lu\n", Status);
goto Exit;
}
TraceStarted = TRUE;
//
// Enable the provider to a trace session with filtering enabled on the
// provider
//
ZeroMemory(&EnableParameters, sizeof(EnableParameters));
EnableParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
EnableParameters.EnableFilterDesc = &FilterDescriptor;
EnableParameters.FilterDescCount = 1;
Status = EnableTraceEx2(
SessionHandle,
&EXAMPLE_PROVIDER,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_VERBOSE,
0,
0,
0,
&EnableParameters);
if (Status != ERROR_SUCCESS) {
printf("EnableTraceEx2() failed with %lu\n", Status);
goto Exit;
}
//
// Clean up the payload descriptor
//
Status = TdhCleanupPayloadEventFilterDescriptor(&FilterDescriptor);
if (Status != ERROR_SUCCESS) {
printf("TdhCleanupPayloadEventFilterDescriptor() failed with %lu\n", Status);
goto Exit;
}
//
// Collect trace for 30 seconds
//
Sleep(30 * 1000);
Exit:
//
// Stop tracing.
//
if (TraceStarted != FALSE) {
Status = ControlTraceW(SessionHandle, NULL, TraceProperties, EVENT_TRACE_CONTROL_STOP);
if (Status != ERROR_SUCCESS) {
printf("StopTrace() failed with %lu\n", Status);
}
}
if (TraceProperties != NULL) {
FreeTraceProperties(TraceProperties);
}
TdhUnloadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
return Status;
}
必要条件
要件 | 価値 |
---|---|
サポートされる最小クライアント | Windows 7 [デスクトップ アプリ |UWP アプリ] |
サポートされる最小サーバー | Windows Server 2008 R2 [デスクトップ アプリ |UWP アプリ] |
ターゲット プラットフォーム の |
ウィンドウズ |
ヘッダー | evntrace.h |
ライブラリ | Windows 8.1 および Windows Server 2012 R2 の Sechost.lib。Windows 8、Windows Server 2012、Windows 7、Windows Server 2008 R2 の Advapi32.lib |
DLL | Windows 8.1 および Windows Server 2012 R2 での Sechost.dll。Windows 8、Windows Server 2012、Windows 7、Windows Server 2008 R2 での Advapi32.dll |
関連項目
StartTrace の
EnableCallback の