추적 로깅 C/C++ 빠른 시작
다음 섹션에서는 C/C++ 사용자 모드 코드에 TraceLogging을 추가하는 데 필요한 기본 단계를 설명합니다.
사전 요구 사항
- Microsoft Visual Studio 2013 이상
- Windows 10 SDK(소프트웨어 개발 키트)는 사용자 모드 공급자를 작성해야 합니다.
- 커널 모드 공급자를 작성하려면 Windows 10 WDK(Windows 드라이버 키트)가 필요합니다.
중요
해결되지 EventRegister
않은 , EventWriteTransfer
또는 EventUnregister
함수에 대한 링커 오류를 방지하려면 이러한 예제를 컴파일할 때 와 advapi32.lib
연결합니다.
이러한 예제에서 이벤트를 수집하고 디코딩하려면 tracelog 또는 traceview와 같은 도구를 사용하여 추적을 시작하고, 예제를 실행하고, tracelog 또는 traceview와 같은 도구를 사용하여 추적을 중지하고, tracefmt 또는 traceview와 같은 디코딩 도구를 사용하여 추적을 디코딩해야 합니다. 예를 들어 내 공급자가 GUID {0205c616-cf97-5c11-9756-56a2cee02ca7}
를 사용하여 정의된 경우 다음과 같이 Windows SDK 도구 추적 로그 및 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);
헤더 파일에는 C/C++ TraceLogging API를 정의하는 가 포함됩니다 TraceLoggingProvider.h
. 에서 사용하는 TraceLoggingProvider.h
상수를 정의하므로 먼저 를 포함 windows.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 를 호출하여 공급자 핸들을 등록해야 합니다. 이 작업은 일반적으로 기본() 또는 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 매크로는 최대 99개의 인수를 허용합니다. 이벤트 이름은 UTF-8 형식으로 저장됩니다. 이벤트 이름 또는 필드 이름에 포함된 '\0'
문자를 사용하면 안 됩니다. 일부 이벤트 디코더 또는 이벤트 프로세서에는 자체 제한 사항이 있을 수 있지만 허용되는 문자에는 다른 제한이 없습니다.
이벤트 이름 다음에 있는 각 인수는 TraceLogging 래퍼 매크로 내부에 래핑되어야 합니다. C++를 사용하는 경우 래퍼 매크로를 TraceLoggingValue
사용하여 인수의 형식을 자동으로 추론할 수 있습니다. C로 작성하거나 필드 형식에 대한 더 많은 제어를 원하는 경우 , , TraceLoggingUnicodeString
TraceLoggingString
등과 같은 TraceLoggingInt32
형식별 필드 매크로를 사용해야 합니다.
단일 이벤트 로깅 외에도 TraceLoggingWriteActivity 또는 TraceLoggingWriteStart/TraceLoggingWriteStop 매크로를 사용하여 활동별로 이벤트를 그룹화할 수도 있습니다. 활동은 이벤트의 상관 관계를 지정하며 시작과 끝이 있는 시나리오에 유용합니다. 예를 들어 활동을 사용하여 애플리케이션 시작부터 시작하는 시나리오를 측정하고, 시작 화면을 사용할 수 있게 되는 데 걸리는 시간을 포함하고, 애플리케이션의 초기 화면이 표시되면 종료할 수 있습니다.
활동은 단일 이벤트를 캡처하고 해당 활동의 시작과 끝 사이에 발생하는 다른 활동을 중첩합니다. 작업에는 프로세스별 scope 있으며 다중 스레드 이벤트를 올바르게 중첩하려면 스레드에서 스레드로 전달되어야 합니다.
공급자 핸들의 scope 정의된 모듈(DLL, EXE 또는 SYS 파일)로 제한됩니다. 핸들을 다른 DLL에 전달해서는 안 됩니다. B.DLL 정의된 공급자 핸들을 사용하여 A.DLL TraceLoggingWrite 매크로를 호출하면 문제가 발생할 수 있습니다. 이 요구 사항을 충족하는 가장 안전하고 효율적인 방법은 항상 전역 공급자 핸들을 직접 참조하고 공급자 핸들을 매개 변수로 전달하지 않는 것입니다.
공급자 등록 취소
구성 요소가 언로드되기 전에 TraceLogging 공급자의 등록을 취소해야 합니다. 이는 DLL 및 드라이버에 특히 중요합니다. DLL 또는 드라이버가 공급자를 등록 취소하지 않고 언로드하는 경우 충돌이 발생할 수 있습니다.
다음 코드는 공급자를 등록 취소합니다.
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
호환성
구성에 따라 TraceLoggingProvider.h는 이전 버전과 호환되거나(결과 프로그램은Windows Vista 이상에서 실행됨) 이후 OS 버전에 최적화될 수 있습니다. TraceLoggingProvider.h는 WINVER(사용자 모드) 및 NTDDI_VERSION(커널 모드)를 사용하여 이전 OS 버전과 호환되는지 아니면 최신 OS 버전에 최적화되어야 하는지 여부를 결정합니다.
사용자 모드의 경우 WINVER <windows.h>
을 설정하기 전에 를 포함하는 <windows.h>
경우 WINVER을 SDK의 기본 대상 OS 버전으로 설정합니다. WINVER이 0x602 이상으로 TraceLoggingProvider.h
설정된 경우 Windows 8 이상에 대한 동작을 최적화하고 앱이 이전 버전의 Windows에서 실행되지 않습니다. Vista 또는 Windows 7에서 프로그램을 실행해야 하는 경우 를 포함 <windows.h>
하기 전에 WINVER을 적절한 값으로 설정해야 합니다.
마찬가지로, NTDDI_VERSION 설정하기 전에 를 포함하는 <wdm.h>
경우 NTDDI_VERSION <wdm.h>
기본값으로 설정합니다. NTDDI_VERSION 0x06040000 이상으로 설정된 경우 TraceLoggingProvider.h는 Windows 10 대한 동작을 최적화하며 드라이버는 이전 버전의 Windows에서 작동하지 않습니다.
이 동작은 를 포함TraceLoggingProvider.h
하기 전에 를 설정 TLG_HAVE_EVENT_SET_INFORMATION
하여 방향을 제어할 수 있습니다.
매크로에 대한 자세한 내용은 머리글의 TraceLoggingProvider.h
주석을 TLG_HAVE_EVENT_SET_INFORMATION
참조하세요.
요약 및 다음 단계
WPT(Windows Performance Tools)를 사용하여 추적 로깅 데이터를 캡처하고 보는 방법을 보려면 추적 로깅 이벤트 기록 및 표시를 참조하세요.
자세한 C++ 추적 로깅 예제는 C/ C++ 추적 로깅 예제를 참조하세요.