TraceLogging C/C++ 快速入門
下一節說明將 TraceLogging 新增至 C/C++ 使用者模式程式碼所需的基本步驟。
必要條件
- Microsoft Visual Studio 2013 或更新版本。
- Windows 10軟體發展工具組 (SDK) ,才能撰寫使用者模式提供者。
- Windows 10需要 Windows 驅動程式套件 (WDK) ,才能撰寫核心模式提供者。
重要
若要避免未解決 EventRegister
、 EventWriteTransfer
或 EventUnregister
函式的連結器錯誤,請在編譯這些範例時與 advapi32.lib
連結。
若要從這些範例收集及解碼事件,您必須使用 tracelog 或 traceview 之類的工具來啟動追蹤、執行範例、使用 tracelog 或 traceview 之類的工具來停止追蹤,以及使用 tracefmt 或 traceview 等解碼工具解碼追蹤。 例如,如果我的提供者是使用 GUID {0205c616-cf97-5c11-9756-56a2cee02ca7}
來定義,我可以使用 Windows SDK 工具 tracelog 和 tracefmt 來檢視這些範例中的事件,如下所示:
tracelog -start MyTraceSession -f MyTraceFile.etl -guid #0205c616-cf97-5c11-9756-56a2cee02ca7
- 執行範例。
tracelog -stop MyTraceSession
tracefmt -o MyTraceFile.txt MyTraceFile.etl
notepad MyTraceFile.txt
SimpleTraceLoggingExample.h
此範例標頭包含 TraceLogging API,並向前宣告將用來記錄事件的提供者控制碼。 任何想要使用 TraceLogging 的類別都會包含此標頭,然後就可以開始記錄。
#pragma once
#include <windows.h> // Definitions required by TraceLoggingProvider.h
#include <TraceLoggingProvider.h> // The C/C++ TraceLogging API
// Forward-declare the g_hMyComponentProvider variable that you will use for tracing in this component
TRACELOGGING_DECLARE_PROVIDER(g_hMyComponentProvider);
標頭檔包含 TraceLoggingProvider.h
定義 C/C++ TraceLogging API 的標頭檔。 您必須先包含 windows.h
,因為它會定義 所使用的 TraceLoggingProvider.h
常數。
標頭檔正向會宣告您將傳遞至 TraceLogging API 以記錄事件的提供者控制碼 g_hMyComponentProvider
。 此控制碼必須可供任何想要使用 TraceLogging 的程式碼存取。
TRACELOGGING_DECLARE_PROVIDER 是使用您提供的名稱建立 extern const TraceLoggingHProvider
控制碼的宏,在上述範例中為 g_hMyComponentProvider
。
您將在程式碼檔案中配置實際的提供者控制碼變數。
SimpleTraceLoggingExample.cpp
下列範例會註冊提供者、記錄事件,以及取消註冊提供者。
#include "SimpleTraceLoggingExample.h"
// Define a handle to a TraceLogging provider
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
// {0205c616-cf97-5c11-9756-56a2cee02ca7}
(0x0205c616,0xcf97,0x5c11,0x97,0x56,0x56,0xa2,0xce,0xe0,0x2c,0xa7));
void main()
{
char sampleValue[] = "Sample value";
// Register the provider
TraceLoggingRegister(g_hMyComponentProvider);
// Log an event
TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
"HelloWorldTestEvent", // Event Name that should uniquely identify your event.
TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
}
上述範例包含 SimpleTraceLoggingExample.h,其中包含程式碼將用來記錄事件的全域提供者變數。
TRACELOGGING_DEFINE_PROVIDER宏會配置儲存體,並定義提供者控制碼變數。 您提供給這個宏的變數名稱必須符合您在標頭檔 TRACELOGGING_DECLARE_PROVIDER 宏中使用的名稱。
註冊提供者控制碼
您必須先呼叫 TraceLoggingRegister 註冊提供者控制碼,才能使用提供者控制碼來記錄事件。 這通常是在 main () 或 DLLMain () 中完成,但只要在任何嘗試記錄事件之前,就可以隨時完成。 如果您在註冊提供者控制碼之前記錄事件,則不會發生任何錯誤,但不會記錄事件。 上述範例中的下列程式碼會註冊提供者控制碼。
// Define the GUID to use in TraceLoggingProviderRegister
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
// {0205c616-cf97-5c11-9756-56a2cee02ca7}
(0x0205c616,0xcf97,0x5c11,0x97,0x56,0x56,0xa2,0xce,0xe0,0x2c,0xa7));
void main()
{
char sampleValue[] = "Sample value";
// Register the provider
TraceLoggingRegister(g_hMyComponentProvider);
記錄追蹤記錄事件
註冊提供者之後,下列程式碼會記錄簡單的事件。
// Log an event
TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
"HelloWorldTestEvent", // Event Name that should uniquely identify your event.
TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
TraceLoggingWrite宏最多接受九十九個引數。 事件名稱會以 UTF-8 格式儲存。 您不得在事件名稱或功能變數名稱中使用內嵌 '\0'
字元。 雖然某些事件解碼器或事件處理器可能有自己的限制,但允許的字元沒有其他限制。
事件名稱後面的每個引數都必須包裝在 TraceLogging 包裝函式宏內。 如果您使用 C++,您可以使用 TraceLoggingValue
包裝函式宏來自動推算引數的類型。 如果您要以 C 撰寫,或想要對欄位類型進行更多控制,則必須使用類型特定的欄位宏,例如 TraceLoggingInt32
、 TraceLoggingUnicodeString
、 TraceLoggingString
等等。
除了記錄單一事件之外,您也可以使用TraceLoggingWriteActivity 或TraceLoggingWriteStart/TraceLoggingWriteStop宏,將事件分組在 TraceLoggingActivity.h 中。 活動會讓事件相互關聯,而且對於開頭和結尾的案例很有用。 例如,您可以使用活動來測量從啟動應用程式開始的案例、包含啟動顯示畫面可用所需的時間,並在應用程式的初始畫面變成可見時結束。
活動會擷取單一事件,並將該活動開始和結尾之間發生的其他活動巢狀化。 活動具有每個進程範圍,而且必須從執行緒傳遞至執行緒,才能適當地巢狀多執行緒事件。
提供者控制碼的範圍僅限於定義提供者控制碼的模組 (DLL、EXE 或 SYS 檔案) 。 控制碼不應傳遞至其他 DLL。 如果在 A.DLL中使用B.DLL中定義的提供者控制碼叫用 TraceLoggingWrite 宏,可能會導致問題。 符合此需求的最安全且最有效率的方式,就是一律直接參考全域提供者控制碼,且永遠不會傳遞提供者控制碼做為參數。
取消註冊提供者
在元件卸載之前,您必須取消註冊 TraceLogging 提供者。 這對於 DLL 和驅動程式特別重要。 如果 DLL 或驅動程式卸載而不註冊提供者,可能會當機。
下列程式碼會取消註冊提供者:
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
相容性
根據其設定,TraceLoggingProvider.h 可以回溯相容, (產生的程式將在 Windows Vista 或更新版本) 上執行,或者可以針對較新的作業系統版本進行優化。 TraceLoggingProvider.h 會使用 WINVER (使用者模式) 和NTDDI_VERSION (核心模式) 來判斷它是否應該與舊版作業系統相容,或針對較新的 OS 版本進行優化。
針對使用者模式,如果您在設定 WINVER 之前包含 <windows.h>
, <windows.h>
請將 WINVER 設定為 SDK 的預設目標 OS 版本。 如果 WINVER 設定為 0x602 或更高版本,請針對Windows 8或更新版本優化其行為, TraceLoggingProvider.h
且您的應用程式不會在舊版 Windows 上執行。 如果您需要程式在 Vista 或 Windows 7 上執行,請務必先將 WINVER 設定為適當的值,再包含 <windows.h>
。
同樣地,如果您在設定NTDDI_VERSION之前包含 <wdm.h>
, <wdm.h>
請將NTDDI_VERSION設定為預設值。 如果NTDDI_VERSION設定為 0x06040000 或更高版本,TraceLoggingProvider.h 會針對Windows 10優化其行為,而您的驅動程式將無法在舊版 Windows 上運作。
在包含 TraceLoggingProvider.h
之前設定 TLG_HAVE_EVENT_SET_INFORMATION
,即可控制此行為。
如需宏的詳細 TLG_HAVE_EVENT_SET_INFORMATION
資料,請參閱 標頭中的 TraceLoggingProvider.h
批註。
摘要和後續步驟
若要瞭解如何使用 Windows Performance Tools (WPT) 擷取及檢視 TraceLogging 資料,請參閱記錄和顯示 TraceLogging 事件。
如需更多 C++ TraceLogging 範例,請參閱 C/C++ 追蹤記錄 範例。