共用方式為


TraceLogging C/C++ 快速入門

下一節說明將 TraceLogging 新增至 C/C++ 使用者模式程式碼所需的基本步驟。

必要條件

  • Microsoft Visual Studio 2013 或更新版本。
  • Windows 10軟體發展工具組 (SDK) ,才能撰寫使用者模式提供者。
  • Windows 10需要 Windows 驅動程式套件 (WDK) ,才能撰寫核心模式提供者。

重要

若要避免未解決 EventRegisterEventWriteTransferEventUnregister 函式的連結器錯誤,請在編譯這些範例時與 advapi32.lib 連結。

若要從這些範例收集及解碼事件,您必須使用 tracelog 或 traceview 之類的工具來啟動追蹤、執行範例、使用 tracelog 或 traceview 之類的工具來停止追蹤,以及使用 tracefmt 或 traceview 等解碼工具解碼追蹤。 例如,如果我的提供者是使用 GUID {0205c616-cf97-5c11-9756-56a2cee02ca7} 來定義,我可以使用 Windows SDK 工具 tracelogtracefmt 來檢視這些範例中的事件,如下所示:

  • 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 撰寫,或想要對欄位類型進行更多控制,則必須使用類型特定的欄位宏,例如 TraceLoggingInt32TraceLoggingUnicodeStringTraceLoggingString 等等。

除了記錄單一事件之外,您也可以使用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++ 追蹤記錄 範例。