TraceLoggingWrite 宏 (traceloggingprovider.h)
發出 TraceLogging 事件。
語法
void TraceLoggingWrite(
[in] hProvider,
[in] eventName,
[in, optional] __VA_ARGS__
);
參數
[in] hProvider
用來寫入事件的 TraceLogging 提供者 控制碼。
[in] eventName
用來識別事件的簡短和唯一名稱。 這必須是字串常值,而不是變數。 它不能有任何內嵌 '\0'
字元。
[in, optional] __VA_ARGS__
最多 99 個額外的參數,可設定或新增欄位至事件。 每個參數都必須是其中一個 TraceLogging 包裝函式宏,例如 TraceLoggingLevel、 TraceLoggingKeyword或 TraceLoggingValue。
重要
ProviderId、Level 和 Keyword 是篩選事件的主要方法。 其他類型的篩選是可行的,但額外負荷較高。 一律將非零層級和關鍵字指派給每個事件。
傳回值
無
備註
TraceLoggingWrite宏的每個調用都會展開至透過指定的提供者控制碼將事件寫入 ETW 所需的程式碼。
- TraceLoggingWrite 會檢查指定的提供者是否已註冊。 如果未 註冊提供者, TraceLoggingWrite 就不會執行任何動作。
- TraceLoggingWrite 會檢查是否有任何取用者正在接聽事件,就像呼叫 TraceLoggingProviderEnabled一樣。 如果沒有取用者正在接聽事件, TraceLoggingWrite 不會執行任何動作。
- 否則, TraceLoggingWrite 會評估引數中指定的運行時程表達式、儲存結果、將必要的資料封裝到事件中,並呼叫 EventWriteTransfer 將事件傳送至 ETW。
產生的事件會建構如下:
- 事件的提供者識別碼、提供者名稱和提供者群組將來自 hProvider 參數。
- 事件的名稱會來自 eventName 參數。
- 在使用者模式中,事件的活動識別碼會來自執行緒的隱含活動識別碼。 在核心模式中,事件的活動識別碼將會GUID_Null。
- 事件不會有相關的活動識別碼。
- 事件的層級會來自 TraceLoggingLevel 引數。 如果沒有 TraceLoggingLevel 引數存在,則事件的層級會是 5 (WINEVENT_LEVEL_VERBOSE) 。 如果有多個 TraceLoggingLevel 引數存在,則會使用最後一個引數。 若要啟用有效的事件篩選,請一律將有意義的非零層級指派給每個事件。
- 事件的關鍵字會來自 TraceLoggingKeyword 引數。 如果沒有 TraceLoggingKeyword 引數存在,則事件的關鍵字將會是 0 (NONE) 。 如果有多個 TraceLoggingKeyword 引數存在,這些值將會一起或一起處理。 若要啟用有效的事件篩選,請一律將有意義的非零關鍵字指派給每個事件。
- 其他事件屬性可由 TraceLoggingOpcode、 TraceLoggingDescription、 TraceLoggingEventTag或 TraceLoggingChannel等引數設定。
- 事件欄位可以使用 TraceLoggingStruct來分組。
- 事件欄位是由 TraceLoggingValue、TraceLoggingInt32、TraceLoggingHResult、TraceLoggingString 等欄位引數所新增。如需詳細資訊 ,請參閱 TraceLogging 包裝函式宏 。
例如:
TraceLoggingWrite(
g_hProvider,
"MyEvent1",
TraceLoggingLevel(WINEVENT_LEVEL_WARNING), // Levels defined in <winmeta.h>
TraceLoggingKeyword(MyNetworkingKeyword),
TraceLoggingString(operationName), // Adds an "operationName" field.
TraceLoggingHResult(hr, "NetStatus")); // Adds a "NetStatus" field.
的叫用 TraceLoggingWrite(hProvider, "EventName", args...)
可視為擴充至程式碼,如下所示:
if (TraceLoggingProviderEnabled(hProvider, eventLevel, eventKeyword))
{
static const metadata = { GetMetadataFromArgs(args...) };
EVENT_DATA_DESCRIPTOR data[N] = { GetDataFromArgs(args...) };
EventWriteTransfer(etwHandle, metadata.desc, NULL, NULL, N, data);
}
注意
每個 TraceLoggingWrite 宏都會自動檢查 TraceLoggingProviderEnabled ,因此只有在取用者正在接聽提供者的事件時,才會寫入事件。 因此,通常不需要直接呼叫 TraceLoggingProviderEnabled。 中任何運行時程表達式 args...
都會在 啟用 事件時進行評估。 運行時程表達式不會多次評估。
如果產生複雜的事件,您可能會收到編譯器錯誤,指出行太長,或編譯器不在堆積空間中。 當 TraceLoggingWrite 宏展開至超過編譯器可支援的行時,就會發生這種情況。 如果發生這種情況,您必須簡化事件。
TraceLoggingWrite宏會使用EVENT_DATA_DESCRIPTOR陣列將資料傳送至 ETW。 ETW 所接受的描述項數目上限為 128。 由於每個參數可能需要使用 0、1 或 2 個描述元,因此在達到引數限制 (99) 之前,可以達到資料描述元限制 (128) 。
重要
請嘗試避免大型事件。 ETW 主要設計用於處理小型事件。 TraceLoggingWrite 會以無訊息方式卸載任何太大的事件。 事件的大小是根據 ETW 執行時間 () 、中繼資料 (,也就是提供者名稱、事件名稱、功能變數名稱、功能變數名稱) 和資料 (域值所新增的標頭總數) 。 如果事件的總大小大於 65535,或取用者會話使用小於事件大小的緩衝區大小,則不會記錄事件。
對 TraceLoggingWrite的呼叫與pActivityId和pRelatedActivity參數的TraceLoggingWriteActivity呼叫相同。 如果您需要指定事件的活動識別碼,請使用 TraceLoggingWriteActivity 。
範例
#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
"MyProvider", // Human-readable name of the provider
// ETW Control GUID: {b3864c38-4273-58c5-545b-8b3608343471}
(0xb3864c38,0x4273,0x58c5,0x54,0x5b,0x8b,0x36,0x08,0x34,0x34,0x71));
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 |
程式庫 | Advapi32.lib |