макрос TRACELOGGING_DEFINE_PROVIDER (traceloggingprovider.h)

Определяет дескриптор для поставщика TraceLogging.

Синтаксис

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

Параметры

[in] handleVariable

Имя, используемое для дескриптора поставщика с использованием соглашений об именовании компонента для глобальных переменных, например MyComponentLog или g_hMyProvider.

[in] providerName

Строковый литерал с именем поставщика TraceLogging. Это имя должно быть специфичным для вашей организации и компонента, чтобы не конфликтовать с поставщиками из других компонентов. Эта строка имени будет включена в каждое событие трассировки событий Windows, созданное поставщиком, поэтому попробуйте использовать относительно короткое имя. Например, можно использовать такое имя, как "MyCompany.MyComponent" или "MyCompany.MyOrganization.MyComponent".

Это должен быть строковый литерал. Не используйте переменную.

[in] providerId

GUID элемента управления ETW для поставщика, указанный в виде разделенного запятыми списка из 11 целых чисел в круглых скобках. Например, GUID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} будет выражен как (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5).

Хотя для идентификатора поставщика можно использовать любой уникальный ИДЕНТИФИКАТОР GUID, корпорация Майкрософт рекомендует использовать GUID, созданный из имени поставщика, с помощью алгоритма хэширования имен трассировки событий Windows. Сведения о создании идентификатора поставщика см. ниже.

[in, optional] __VA_ARGS__

Необязательные параметры для поставщика. Большинству поставщиков не требуется указывать необязательные параметры.

Если вы хотите, чтобы поставщик был связан с группой поставщиков etW, добавьте макрос TraceLoggingOptionGroup , чтобы указать GUID группы поставщика. В противном случае не указывайте никаких __VA_ARGS__ параметров.

Возвращаемое значение

None

Remarks

Поставщик 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 = ...;

Результирующий дескриптор имеет модуль область и может использоваться в любом месте модуля EXE, DLL или SYS, в котором он определен. При необходимости используйте макрос TRACELOGGING_DECLARE_PROVIDER (например, в заголовке), чтобы переадресовать дескриптор, чтобы его могли использовать другие файлы C или .cpp в компоненте.

При запуске компонента поставщик будет находиться в незарегистрированном состоянии. Любые попытки использовать его для создания событий будут игнорироваться без уведомления. Прежде чем он сможет отвечать на любые вызовы записи, необходимо зарегистрировать поставщик с помощью TraceLoggingRegister. Обычно это делается во время запуска компонента, например в main, wmain, WinMain, DllMain(DLL_PROCESS_ATTACH)или DriverEntry. При завершении работы компонента отмените регистрацию поставщика, вызвав TraceLoggingUnregister.

Примечание

Дескриптор поставщика, определенный параметром TRACELOGGING_DEFINE_PROVIDER , ограничен модулем . Дескриптор можно использовать по мере необходимости в файле EXE, DLL или SYS, но его не следует использовать за пределами область модуля, т. е. он не должен передаваться в другие библиотеки DLL в том же процессе. Каждый ФАЙЛ EXE, DLL или SYS должен использовать собственный дескриптор поставщика и выполнять собственные операции регистрации и отмены регистрации. В отладочных сборках утверждение срабатывает при попытке записи с помощью дескриптора поставщика из другого модуля.

Имя и идентификатор поставщика

Трассировка событий Windows выполняет фильтрацию и маршрутизацию событий с помощью идентификатора поставщика (также называемого GUID поставщика или GUID элемента управления). Например, если у вас есть поставщик с именем MyCompany.MyComponent с идентификатором {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} поставщика, можно запустить трассировку для записи событий от этого поставщика с помощью команды tracelog , такой как tracelog -start MySessionName -f MySession.etl -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5.

Все поставщики трассировки событий Windows идентифицируются как по имени поставщика, так и по идентификатору поставщика. Имя и идентификатор должны быть уникальными, чтобы они не конфликтовали с другими поставщиками. Кроме того, имя и идентификатор должны быть связаны: как только определенное имя используется с определенным идентификатором для поставщика ETW, это имя не должно использоваться с любым другим идентификатором, и этот идентификатор не должен использоваться с каким-либо другим именем.

Идентификатор поставщика может быть любым уникальным ИДЕНТИФИКАТОРом GUID, созданным guidgen с помощью средства SDK или https://uuidgen.org. Однако вместо использования случайно созданного GUID для идентификатора поставщика корпорация Майкрософт рекомендует создавать идентификатор поставщика из имени поставщика с помощью алгоритма хэширования имен трассировки событий Windows, описанного ниже. Это дает несколько преимуществ: проще запомнить только имя; идентификатор и имя связываются автоматически; Такие средства, как tracelog, traceview, EventSource и WPR, имеют специальную поддержку для поставщиков, использующих идентификаторы, созданные с помощью этого алгоритма.

Например, если у вас есть поставщик с именем MyCompany.MyComponent с идентификатором {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} поставщика, можно запустить трассировку для записи событий от этого поставщика с помощью команды tracelog , такой как tracelog -start MySessionName -f MySession.etl -guid *MyCompany.MyComponent. Это работает, так как идентификатор {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5} поставщика был создан путем хэширования имени MyCompany.MyComponentпоставщика , поэтому средство tracefmt считается -guid *MyCompany.MyComponent эквивалентным -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5.

С помощью PowerShell можно получить идентификатор поставщика для определенного имени поставщика с помощью алгоритма хэширования имен трассировки событий Windows с помощью класса EventSource :

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

Результат:

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

В C# алгоритм хэширования имен трассировки событий Windows можно реализовать следующим образом:

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
Header traceloggingprovider.h

См. также раздел

TRACELOGGING_DECLARE_PROVIDER

TraceLoggingWrite