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 提供者名稱的字串常值。 此名稱應專屬於您的組織和元件,使其不會與其他元件的提供者衝突。 此名稱字串會包含在提供者所產生的每個 ETW 事件內,因此請嘗試使用相對簡短的名稱。 例如,您可以使用 類似 "MyCompany.MyComponent"
或 "MyCompany.MyOrganization.MyComponent"
的名稱。
這必須是字串常值。 請勿使用變數。
[in] providerId
提供者的 ETW 控制項 GUID,在括弧中指定為 11 個整數的逗號分隔清單。 例如,GUID {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
會以 表示 (0xce5fa4ea,0xab00,0x5402,0x8b,0x76,0x9f,0x76,0xac,0x85,0x8f,0xb5)
。
雖然任何唯一 GUID 都可用於提供者識別符,但 Microsoft 建議使用 ETW 名稱哈希演算法從提供者名稱產生的 GUID。 如需產生提供者標識碼的相關信息,請參閱下方。
[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 = ...;
產生的句柄具有模組範圍,而且可以在定義它的EXE、DLL或SS模組內的任何位置使用。 (視需要使用 TRACELOGGING_DECLARE_PROVIDER 宏,例如在標頭) 中轉送宣告句柄,以便讓元件中的其他 .c 或.cpp檔案使用它。
當元件開始執行時,提供者將會處於未註冊的狀態。
任何嘗試使用它來產生事件都會以無訊息方式忽略。 您必須先使用 TraceLoggingRegister 註冊提供者,才能回應任何寫入呼叫。 這通常會在元件啟動期間完成,例如在 、wmain
、WinMain
、 DllMain(DLL_PROCESS_ATTACH)
或 DriverEntry
中main
。 在元件關機時,呼叫 TraceLoggingUnregister 來取消註冊提供者。
注意
所 TRACELOGGING_DEFINE_PROVIDER
定義的提供者句柄範圍設定為模組。 句柄可以視需要在 EXE、DLL 或 SYS 檔案內使用,但不應在模組範圍之外使用,亦即不應將它傳遞至相同進程中的其他 DLL。 每個 EXE、DLL 或 SYS 檔案都應該使用自己的提供者句柄,而且應該執行自己的 Register 和 Unregister。 在偵錯組建中,如果您嘗試使用來自另一個模組的提供者句柄進行寫入,就會引發判斷提示。
提供者名稱和識別碼
ETW 會使用提供者標識符來執行事件篩選和路由, (也稱為提供者 GUID 或控制 GUID) 。 例如,如果您有名為 MyCompany.MyComponent
的提供者,且具有提供者標識符{ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
,則可以使用之類的 tracelog -start MySessionName -f MySession.etl -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5
tracelog 命令來啟動追蹤,以從此提供者擷取事件。
所有 ETW 提供者都是由提供者名稱和提供者識別碼來識別。 名稱和標識碼都必須是唯一的,因此不會與其他提供者衝突。 此外,應該連結名稱和標識碼:一旦特定名稱與 ETW 提供者的特定識別碼搭配使用,該名稱就不應該搭配任何其他標識碼使用,而且該標識元不應搭配任何其他名稱使用。
提供者標識碼可以是任何唯一的 GUID,例如使用 guidgen
SDK 工具或 https://uuidgen.org所產生的 GUID。不過,Microsoft 建議使用下面所述的 ETW 名稱哈希演算法,從提供者名稱產生提供者識別碼,而不是使用隨機產生的 GUID 給提供者識別碼。 這提供數個優點:記住名稱會比較容易;標識碼和名稱會自動連結;tracelog、traceview、EventSource 和 WPR 等工具對使用此演算法所產生標識符的提供者有特殊支援。
例如,如果您有名為 MyCompany.MyComponent
的提供者,且具有提供者標識符{ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
,則可以使用之類的 tracelog -start MySessionName -f MySession.etl -guid *MyCompany.MyComponent
tracelog 命令來啟動追蹤,以從此提供者擷取事件。
這是因為提供者識別碼是藉由哈希提供者 {ce5fa4ea-ab00-5402-8b76-9f76ac858fb5}
名稱 MyCompany.MyComponent
所產生,因此 tracefmt 工具會 -guid *MyCompany.MyComponent
考慮等於 -guid #ce5fa4ea-ab00-5402-8b76-9f76ac858fb5
。
您可以使用 PowerShell 透過 EventSource 類別,使用 ETW 名稱哈希演算法來取得特定提供者名稱的提供者識別碼:
[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 |