다음을 통해 공유


TRACELOGGING_DEFINE_PROVIDER 매크로(traceloggingprovider.h)

TraceLogging 공급자에 대한 핸들을 정의합니다.

구문

void TRACELOGGING_DEFINE_PROVIDER(
  [in]            handleVariable,
  [in]            providerName,
  [in]            providerId,
  [in, optional]  __VA_ARGS__
);

매개 변수

[in] handleVariable

전역 변수에 대한 구성 요소의 명명 규칙(예: 또는 g_hMyProvider)을 사용하여 공급자의 핸들에 사용할 이름입니다. MyComponentLog

[in] providerName

TraceLogging 공급자의 이름을 가진 문자열 리터럴입니다. 이 이름은 다른 구성 요소의 공급자와 충돌하지 않도록 organization 및 구성 요소와 관련이 있어야 합니다. 이 이름 문자열은 공급자가 생성한 각 ETW 이벤트 내에 포함되므로 비교적 짧은 이름을 사용해 보세요. 예를 들어 또는 "MyCompany.MyOrganization.MyComponent"와 같은 "MyCompany.MyComponent" 이름을 사용할 수 있습니다.

문자열 리터럴이어야 합니다. 변수를 사용하지 마세요.

[in] providerId

괄호 안에 있는 11개의 정수의 쉼표로 구분된 목록으로 지정된 공급자에 대한 ETW 컨트롤 GUID입니다. 예를 들어 GUID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 는 로 (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5)표현됩니다.

공급자 ID에 고유한 GUID를 사용할 수 있지만 ETW 이름 해시 알고리즘을 사용하여 공급자 이름에서 생성된 GUID를 사용하는 것이 좋습니다. 공급자 ID 생성에 대한 자세한 내용은 아래를 참조하세요.

[in, optional] __VA_ARGS__

공급자에 대한 선택적 매개 변수입니다. 대부분의 공급자는 선택적 매개 변수를 지정할 필요가 없습니다.

공급자를 ETW 공급자 그룹과 연결하려면 TraceLoggingOptionGroup 매크로를 추가하여 공급자의 그룹 GUID를 지정합니다. 그렇지 않으면 매개 변수를 __VA_ARGS__ 지정하지 마세요.

반환 값

없음

설명

TraceLogging 공급자는 이벤트를 ETW로 보낼 수 있는 연결입니다. 매크로는 TRACELOGGING_DEFINE_PROVIDER TraceLogging 공급자를 정의하고 액세스하는 데 사용할 수 있는 핸들을 만듭니다. 공급자 이름 및 GUID와 같은 공급자 정보도 기록합니다.

이 매크로는 .c 또는 .cpp 파일에서 호출하여 TraceLogging 공급자에 대한 핸들을 정의해야 합니다. 예를 들어 공급자 이름이 지정 MyCompany.MyComponent 되고 컨트롤 GUID가 {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 인 경우 다음 코드를 구성 요소의 .c 또는 .cpp 파일 중 하나에 추가하여 공급자를 정의합니다.

TRACELOGGING_DEFINE_PROVIDER( // defines g_hProvider
    g_hProvider, // Name of the provider handle
    "MyCompany.MyComponent", // Human-readable name for the provider
    // {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
    (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5));

위의 TRACELOGGING_DEFINE_PROVIDER 매크로는 다음과 같은 코드와 유사하게 g_hMyProvider 공급자 핸들 상수를 정의하는 것으로 간주할 수 있습니다.

const TraceLoggingHProvider g_hMyProvider = ...;

결과 핸들에는 모듈 scope 있으며 정의된 EXE, DLL 또는 SYS 모듈 내의 어디에서나 사용할 수 있습니다. 필요에 따라 TRACELOGGING_DECLARE_PROVIDER 매크로(예: 헤더)를 사용하여 핸들을 전달 선언하여 구성 요소의 다른 .c 또는 .cpp 파일에서 사용할 수 있도록 합니다.

구성 요소의 실행이 시작되면 공급자는 등록되지 않은 상태가 됩니다. 이벤트를 생성하는 데 사용하려는 모든 시도는 자동으로 무시됩니다. 쓰기 호출에 응답하려면 TraceLoggingRegister를 사용하여 공급자를 등록해야 합니다. 이 작업은 일반적으로 구성 요소를 시작하는 동안 수행됩니다(예: , , wmain, WinMainDllMain(DLL_PROCESS_ATTACH)또는 DriverEntry)main. 구성 요소 종료 시 TraceLoggingUnregister를 호출하여 공급자 등록을 취소합니다.

참고

에 정의된 TRACELOGGING_DEFINE_PROVIDER 공급자 핸들의 범위는 모듈로 지정됩니다. 핸들은 EXE, DLL 또는 SYS 파일 내에서 필요에 따라 사용할 수 있지만 모듈의 scope 외부에서 사용하면 안 됩니다. 즉, 동일한 프로세스의 다른 DLL에 전달해서는 안 됩니다. 각 EXE, DLL 또는 SYS 파일은 자체 공급자 핸들을 사용해야 하며 자체 등록 및 등록 취소를 수행해야 합니다. 디버그 빌드에서 다른 모듈의 공급자 핸들을 사용하여 작성하려고 하면 어설션이 발생합니다.

공급자 이름 및 ID

ETW는 공급자 ID(공급자 GUID 또는 컨트롤 GUID라고도 함)를 사용하여 이벤트 필터링 및 라우팅을 수행합니다. 예를 들어 공급자 ID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 가 있는 라는 MyCompany.MyComponent 공급자가 있는 경우 와 같은 tracelog -start MySessionName -f MySession.etl -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5tracelog 명령을 사용하여 이 공급자의 이벤트를 캡처하는 추적을 시작할 수 있습니다.

모든 ETW 공급자는 공급자 이름과 공급자 ID로 식별됩니다. 이름과 ID는 모두 고유해야 다른 공급자와 충돌하지 않습니다. 또한 이름과 ID를 연결해야 합니다. 특정 이름을 ETW 공급자의 특정 ID와 함께 사용하면 해당 이름을 다른 ID와 함께 사용하면 안 되며 해당 ID를 다른 이름과 함께 사용하면 안 됩니다.

공급자 ID는 SDK 도구 또는 https://uuidgen.org를 사용하여 guidgen 생성된 고유한 GUID일 수 있습니다. 그러나 공급자 ID에 대해 임의로 생성된 GUID를 사용하는 대신 아래에 설명된 ETW 이름 해시 알고리즘을 사용하여 공급자 이름에서 공급자 ID를 생성하는 것이 좋습니다. 이렇게 하면 이름만 더 쉽게 기억할 수 있는 몇 가지 이점이 있습니다. ID와 이름이 자동으로 연결됩니다. tracelog, traceview, EventSource 및 WPR과 같은 도구는 이 알고리즘을 사용하여 생성된 ID를 사용하는 공급자를 특별히 지원합니다.

예를 들어 공급자 ID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 가 있는 라는 MyCompany.MyComponent 공급자가 있는 경우 와 같은 tracelog -start MySessionName -f MySession.etl -guid *MyCompany.MyComponenttracelog 명령을 사용하여 이 공급자의 이벤트를 캡처하는 추적을 시작할 수 있습니다. 이는 공급자 이름 를 해시하여 공급자 ID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} 가 생성되었기 때문에 작동하므로 tracefmt 도구는 와 동일하다고 -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5간주합니다-guid *MyCompany.MyComponent.MyCompany.MyComponent

PowerShell을 사용하여 EventSource 클래스를 통해 ETW 이름 해시 알고리즘을 사용하여 특정 공급자 이름에 대한 공급자 ID를 가져올 수 있습니다.

[System.Diagnostics.Tracing.EventSource]::new("MyCompany.MyComponent").Guid

결과:

Guid
----
ce5fa4ea-ab00-5402-8b76-9f76ac858fb5

C#에서 ETW 이름 해시 알고리즘은 다음과 같이 구현할 수 있습니다.

static Guid ProviderIdFromName(string name)
{
    var signature = new byte[] {
        0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
        0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB };
    var nameBytes = System.Text.Encoding.BigEndianUnicode.GetBytes(name.ToUpperInvariant());
    using (var sha1 = new System.Security.Cryptography.SHA1Managed())
    {
        sha1.TransformBlock(signature, 0, signature.Length, null, 0);
        sha1.TransformFinalBlock(nameBytes, 0, nameBytes.Length);
        var hash = sha1.Hash;
        Array.Resize(ref hash, 16);
        hash[7] = (byte)((hash[7] & 0x0F) | 0x50);
        return new Guid(hash);
    }
}

예제

#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h> // For event level definitions.
#include <TraceLoggingProvider.h>

TRACELOGGING_DEFINE_PROVIDER( // defines g_hProvider
    g_hProvider, // Name of the provider handle
    "MyCompany.MyComponent", // Human-readable name for the provider
    // {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
    (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5));

int main(int argc, char* argv[]) // or DriverEntry for kernel-mode.
{
    TraceLoggingRegister(g_hProvider);

    TraceLoggingWrite(
        g_hProvider,
        "MyEvent1",
        TraceLoggingLevel(WINEVENT_LEVEL_WARNING), // Levels defined in <winmeta.h>
        TraceLoggingKeyword(MyEventCategories), // Provider-defined categories
        TraceLoggingString(argv[0], "arg0"), // field name is "arg0"
        TraceLoggingInt32(argc)); // field name is implicitly "argc"

    TraceLoggingUnregister(g_hProvider);
    return 0;
}

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2008 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 traceloggingprovider.h

추가 정보

TRACELOGGING_DECLARE_PROVIDER

TraceLoggingWrite