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
공급자가 작성하려는 최대 이벤트 수준을 나타내는 값입니다. 공급자는 일반적으로 matchAnyKeyword
Microsoft는 아래와 같이 수준 1-5의 의미 체계를 정의합니다. 값이 낮을수록 더 심각한 이벤트가 표시됩니다.
수준 각 값은 지정된 수준과 더욱 심각한 수준을 사용하도록 설정합니다. 예를 들어 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
시간 제한 0이면 이 함수는 공급자 구성을 비동기적으로 시작하고 즉시 반환됩니다(즉, 공급자 콜백이 완료될 때까지 기다리지 않고 반환됨).
그렇지 않으면 이 함수는 공급자 구성을 시작하고 모든 공급자 콜백이 완료될 때까지 기다리는 것을 포함하여 구성이 완료될 때까지 대기하기 시작합니다. 지정된 시간 제한 전에 구성이 완료되면 이 함수는 ERROR_SUCCESS반환합니다. 그렇지 않으면 이 함수는 ERROR_TIMEOUT반환합니다.
영원히 기다리려면 INFINITE
[in, optional] EnableParameters
공급자를 사용하도록 설정하는 데 사용되는 추적 매개 변수입니다. 자세한 내용은 ENABLE_TRACE_PARAMETERS참조하세요.
반환 값
함수가 성공하면 반환 값이 ERROR_SUCCESS.
함수가 실패하면 반환 값은
ERROR_INVALID_PARAMETER
매개 변수가 잘못되었습니다.
이 문제는 다음 중 어느 것이라도 true인 경우에 발생할 수 있습니다.
ProviderId NULL. - TraceHandle0.
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 공급자)는 최신 사용 시스템("crimson ETW"라고도 함)을 사용합니다. 세션에 대해 최신 공급자를 사용하거나 다시 구성하면 ETW 런타임은 수준, 64비트 MatchAnyKeyword 마스크, 64비트 MatchAllKeyword 마스크 및 추적 컨트롤러에서 지정한 사용자 지정 공급자 쪽 필터링 데이터를 공급자에게 알릴 수 있습니다. 공급자는 자체 논리를 사용하여 사용하도록 설정할 이벤트를 결정하지만 대부분의 공급자는 EventProviderEnabled논리를 복제합니다.
공급자는 라우팅을 위해 활성화된 이벤트를 ETW로 보냅니다. ETW로 전송된 이벤트 데이터에는 이벤트의 컨트롤 GUID, 메시지 ID, 수준 및 키워드가 포함됩니다. 그런 다음 ETW는 적절하게 추가 필터링을 수행하여 이벤트를 적절한 세션으로 라우팅합니다.
- 이벤트는 설명 정보를 사용하여 ETW로 전송되므로 ETW는 세션에 이벤트를 추가하기 전에 추가 필터링 및 라우팅을 수행할 수 있습니다. 적절한 경우 이벤트를 둘 이상의 세션으로 라우팅할 수 있습니다.
최신 사용 시스템(즉, EventRegister사용하는 공급자)을 사용하는 공급자의 경우 ETW는 EnableTraceEx2EnableParameters통해 추적 세션 컨트롤러에서 요청할 수 있는 여러 기능을 지원합니다. 자세한 내용은 EVENT_FILTER_DESCRIPTOR 참조하세요.
-
스키마화된 필터링 - 공급자 쪽 필터링이라고도 하는 기존의 필터링 설정입니다. 컨트롤러는 FilterData
EnableCallback 공급자에 전달되는 이진 개체로 사용자 지정 필터 집합을 정의합니다. 이러한 필터를 정의하고 해석하는 것은 컨트롤러 및 공급자의 맡입니다. 그런 다음 공급자는 EventWriteExFilter 매개 변수를 사용하여 공급자 쪽 필터링으로 인해 이벤트를 보내지 않아야 하는 세션을 나타낼 수 있습니다. 필터링할 수 있는 이진 개체의 형식과 형식이 정의되지 않았으므로 컨트롤러와 공급자를 긴밀하게 결합해야 합니다. TdhEnumerateProviderFilters 함수를 사용하여 매니페스트에 정의된 필터를 검색할 수 있습니다. - 범위 필터링 - 특정 공급자가 범위 필터에 지정된 조건을 충족하는지 여부에 따라 세션에 대해 활성화되거나 활성화되지 않습니다. PID(프로세스 ID), 실행 파일 이름, 앱 ID 및 앱 패키지 이름을 기반으로 필터링을 허용하는 여러 가지 유형의 범위 필터가 있습니다. 이 기능은 Windows 8.1, Windows Server 2012 R2 이상에서 지원됩니다.
- Stackwalk 필터링 - 지정된 이벤트 ID 집합 또는 (TraceLogging 이벤트의 경우) 이벤트 이름에 대해서만 스택 워크를 수행하도록 ETW에 알깁니다. 이 기능은 Windows 8.1, Windows Server 2012 R2 이상에서 지원됩니다.
- 특성 필터링 - 매니페스트 공급자의 경우 수준, 키워드, 이벤트 ID 또는 이벤트 이름과 같은 이벤트 특성을 기반으로 이벤트를 필터링할 수 있습니다.
- 이벤트 페이로드 필터링 - 매니페스트 공급자의 경우 하나 이상의 조건자에 따라 논리 식을 충족하는지 여부에 따라 이벤트를 즉석에서 필터링할 수 있습니다.
메모
ETW는 강력한 페이로드 및 특성 필터링을 지원하지만, 이벤트는 주로 컨트롤 GUID, 수준 및 키워드를 통해 필터링된 범위 필터를 통해 필터링되어야 합니다. 공급자는 일반적으로 이벤트가 생성되거나 ETW로 전송되기 전에 공급자 코드에서 직접 제어 GUID, 수준 및 키워드 필터링을 수행합니다. 대부분의 공급자에서 수준 또는 키워드로 사용하지 않도록 설정된 이벤트는 시스템 성능에 거의 영향을 주지 않습니다. 마찬가지로 범위 필터에서 사용하지 않도록 설정된 공급자는 시스템 성능에 거의 영향을 주지 않습니다. 다른 종류의 필터링(수준 및 키워드 이외의 페이로드 또는 특성에 따라)은 일반적으로 공급자가 이벤트를 생성하고 ETW 런타임으로 보낸 후에 수행됩니다. 즉, ETW 필터링에서 이벤트를 어떤 세션에서도 기록해서는 안 된다고 판단하더라도 이벤트가 시스템 성능(이벤트를 준비하고 ETW로 보내는 데 소요된 CPU 시간)에 영향을 줍니다. 이러한 종류의 필터링은 추적 데이터 볼륨을 줄이는 데에만 효과적이며 추적 CPU 오버헤드를 줄이는 데는 효과적이지 않습니다.
EnableTraceEx2
필터링을 사용하지 않도록 설정하고 로깅 세션에서 모든 공급자/이벤트를 사용하도록 설정하려면 FilterDescCount 멤버가 0으로 설정된 ENABLE_TRACE_PARAMETERS 구조를 가리키는 EnableParameters 매개 변수를 사용하여 EnableTraceEx2 호출합니다.
EnableTraceEx2 함수에 전달된 각 필터는 EVENT_FILTER_DESCRIPTORType 멤버에 의해 지정됩니다. EVENT_FILTER_DESCRIPTOR 구조체의 배열은 EnableParameters 매개 변수에 전달된 ENABLE_TRACE_PARAMETERS 구조체에서 EnableTraceEx2 함수에 전달됩니다.
각 필터 유형(특정 형식 멤버)은 EnableTraceEx2 함수에 대한 호출에서 한 번만 나타날 수 있습니다. 일부 필터 형식을 사용하면 여러 조건을 단일 필터에 포함할 수 있습니다. 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)
- 허용되는 요소 수: 세미콜론으로 구분된 여러 실행 파일 이름을 포함할 수 있는 단일 문자열입니다.
EVENT_FILTER_TYPE_PACKAGE_ID
- 필터 크기 제한: MAX_EVENT_FILTER_DATA_SIZE(1024)
- 허용되는 요소 수: 세미콜론으로 구분된 여러 패키지 ID를 포함할 수 있는 단일 문자열입니다.
EVENT_FILTER_TYPE_PACKAGE_APP_ID
- 필터 크기 제한: MAX_EVENT_FILTER_DATA_SIZE(1024)
- 허용되는 요소 수: 세미콜론으로 구분된 여러 패키지 상대 앱 ID(PRAID)를 포함할 수 있는 단일 문자열입니다.
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 값은 0xFFFFFFFFFFFFFFFF
MatchAnyKeyword 값과 동일하게 처리됩니다. 즉, 모든 이벤트 키워드를 사용하도록 설정합니다. 그러나 이 동작은 레거시(MOF 또는 TMF 기반 WPP) 공급자에는 적용되지 않습니다. 레거시 공급자의 모든 이벤트 키워드를 사용하도록 설정하려면 MatchAnyKeyword0xFFFFFFFF
설정합니다. 레거시 및 최신 공급자의 모든 이벤트 키워드를 사용하도록 설정하려면 MatchAnyKeyword0xFFFFFFFFFFFFFFFF
설정합니다.
이벤트의 키워드가 0이면 공급자는
공급자 그룹을 사용하도록 설정하려는 경우 EnableParametersEnableProperty 멤버에서 EVENT_ENABLE_PROPERTY_PROVIDER_GROUP
플래그를 사용합니다.
EnableTraceEx2호출하면 공급자가 아직 등록되어 있거나 등록되지 않을 수 있습니다. 공급자가 이미 등록된 경우 ETW는 공급자의 콜백 함수(있는 경우)를 호출하고 세션이 이벤트 수신을 시작합니다. 공급자가 아직 등록되지 않은 경우 ETW는 공급자가 등록한 직후 공급자의 콜백 함수(있는 경우)를 호출하고 세션은 이벤트 수신을 시작합니다. 공급자가 아직 등록되지 않은 경우 공급자의 콜백 함수는 원본 ID를 받지 못합니다.
공급자가 등록되어 있고 세션에 이미 사용하도록 설정된 경우
Windows 8.1, Windows Server 2012 R2 이상에서는 EnableTraceEx2 함수와 ENABLE_TRACE_PARAMETERS 및 EVENT_FILTER_DESCRIPTOR 구조체에서 이벤트 페이로드, 범위 및 스택 워크 필터를 사용하여 로거 세션의 특정 조건을 필터링할 수 있습니다. 이벤트 페이로드 필터에 대한 자세한 내용은 TdhCreatePayloadFilter및 TdhAggregatePayloadFilters 함수 및 ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR및 PAYLOAD_FILTER_PREDICATE 구조를 참조하세요.
EnableTraceEx2
Windows 11부터 시스템 추적 공급자 이벤트는 EnableTraceEx2사용하여 사용하도록 설정할 수 있습니다.
최대 8개의 추적 세션은 동일한 최신(매니페스트 기반 또는 TraceLogging) 공급자에서 이벤트를 사용하도록 설정하고 받을 수 있습니다. 그러나 하나의 추적 세션만 레거시(MOF, TMF 기반 WPP) 공급자를 사용하도록 설정할 수 있습니다. 둘 이상의 세션이 레거시 공급자를 사용하도록 설정하려고 하면 두 번째 세션에서 동일한 공급자를 사용하도록 설정하면 첫 번째 세션이 이벤트 수신을 중지합니다. 예를 들어 세션 A가 레거시 공급자를 사용하도록 설정한 다음 세션 B가 동일한 공급자를 사용하도록 설정한 경우 세션 B만 해당 공급자로부터 이벤트를 받습니다.
세션이 공급자를 사용하지 않도록 설정할 때까지 공급자가 세션에 대해 활성화된 상태로 유지됩니다. 세션을 시작한 애플리케이션이 공급자를 사용하지 않도록 설정하지 않고 종료되는 경우 공급자는 계속 사용하도록 설정됩니다.
매니페스트 기반 공급자를 사용하도록 설정하는 데 사용되는 수준 및 키워드를 확인하려면 다음 명령 중 하나를 사용합니다.
- 공급자 이름
logman 쿼리 공급자 - wevtutil gp provider-name
클래식 공급자의 경우 공급자가 잠재적인 컨트롤러에 심각도 수준을 문서화하고 사용할 수 있도록 하거나 지원하는 플래그를 사용하도록 설정해야 합니다. 공급자가 컨트롤러에서 사용하도록 설정하려는 경우 공급자는 심각도 수준에 대해 0을 수락하고 플래그를 사용하도록 설정하고 0을 기본 로깅을 수행하도록 요청으로 해석해야 합니다(무엇이든).
EnableTraceEx2 사용하여 클래식 공급자를 사용하도록 설정하는 경우 다음 변환이 수행됩니다.
- Level 매개 변수는 EnableTraceEnableLevel 매개 변수를 설정하는 것과 같습니다.
- MatchAnyKeyword 키워드 값이 64비트 값에서 32비트 값으로 잘린다는 점을 제외하고 EnableTraceEnableFlag 매개 변수를 설정하는 것과 같습니다.
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 앱] |
대상 플랫폼 | Windows |
헤더 | 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