Início Rápido do TraceLogging C/C++
A seção a seguir descreve as etapas básicas necessárias para adicionar TraceLogging ao código do modo de usuário C/C++.
Pré-requisitos
- Microsoft Visual Studio 2013 ou posterior.
- O SDK (Kit de Desenvolvimento de Software) do Windows 10 é necessário para gravar um provedor no modo de usuário.
- O WDK (Windows Driver Kit) para Windows 10 é necessário para escrever um provedor no modo kernel.
Importante
Para evitar erros de vinculador para funções ou EventUnregister
funções não resolvidasEventRegister
EventWriteTransfer
, vincule-se advapi32.lib
ao compilar esses exemplos.
Para coletar e decodificar eventos desses exemplos, você precisará iniciar um rastreamento usando uma ferramenta como tracelog ou traceview, executar o exemplo, interromper o rastreamento usando uma ferramenta como tracelog ou traceview e decodificar o rastreamento usando uma ferramenta de decodificação como tracefmt ou traceview. Por exemplo, se meu provedor foi definido usando GUID {0205c616-cf97-5c11-9756-56a2cee02ca7}
, posso exibir os eventos desses exemplos usando o rastreamento e o tracefmt das ferramentas do SDK do Windows da seguinte maneira:
tracelog -start MyTraceSession -f MyTraceFile.etl -guid #0205c616-cf97-5c11-9756-56a2cee02ca7
- Execute o exemplo.
tracelog -stop MyTraceSession
tracefmt -o MyTraceFile.txt MyTraceFile.etl
notepad MyTraceFile.txt
SimpleTraceLoggingExample.h
Este cabeçalho de exemplo inclui as APIs do TraceLogging e o encaminhamento declara o identificador do provedor que será usado para registrar eventos. Qualquer classe que deseje usar o TraceLogging incluirá esse cabeçalho e poderá iniciar o registro em log.
#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);
O arquivo de cabeçalho inclui TraceLoggingProvider.h
o que define a API de TraceLogging C/C++. Você deve incluir windows.h
primeiro porque ele define constantes usadas por TraceLoggingProvider.h
.
O encaminhamento do arquivo de cabeçalho declara o identificador g_hMyComponentProvider
do provedor que você passará para as APIs do TraceLogging para registrar eventos. Esse identificador precisa ser acessível a qualquer código que deseje usar TraceLogging.
TRACELOGGING_DECLARE_PROVIDER é uma macro que cria um extern const TraceLoggingHProvider
identificador usando o nome que você fornece, que no exemplo acima é g_hMyComponentProvider
.
Você alocará a variável de identificador de provedor real em um arquivo de código.
SimpleTraceLoggingExample.cpp
O exemplo a seguir registra o provedor, registra um evento e cancela o registro do provedor.
#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);
}
O exemplo acima inclui SimpleTraceLoggingExample.h, que contém a variável de provedor global que seu código usará para registrar eventos em log.
A macro TRACELOGGING_DEFINE_PROVIDER aloca o armazenamento e define a variável de identificador do provedor. O nome da variável que você fornece a essa macro deve corresponder ao nome usado na macro TRACELOGGING_DECLARE_PROVIDER no arquivo de cabeçalho.
Registrar o identificador do provedor
Antes de usar o identificador do provedor para registrar eventos de log, você deve chamar TraceLoggingRegister para registrar o identificador do provedor. Normalmente, isso é feito em main() ou DLLMain(), mas pode ser feito a qualquer momento, desde que preceda qualquer tentativa de registrar um evento. Se você registrar um evento antes de registrar o identificador do provedor, nenhum erro ocorrerá, mas o evento não será registrado. O código a seguir do exemplo acima registra o identificador do provedor.
// 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);
Registrar um evento tracelogging
Depois que o provedor é registrado, o código a seguir registra um evento simples.
// 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).
A macro TraceLoggingWrite aceita até noventa e nove argumentos. O nome do evento é armazenado no formato UTF-8. Você não deve usar caracteres inseridos '\0'
no nome do evento ou nomes de campo. Não há outros limites para caracteres permitidos, embora alguns decodificadores de eventos ou processadores de eventos possam ter suas próprias limitações.
Cada argumento após o nome do evento deve ser encapsulado dentro de uma macro wrapper tracelogging. Se você estiver usando C++, poderá usar a macro wrapper TraceLoggingValue
para deduzir automaticamente o tipo do argumento. Se você estiver escrevendo em C ou se quiser ter mais controle sobre o tipo de campo, deverá usar macros de campo específicas de tipo, comoTraceLoggingInt32
, , TraceLoggingUnicodeString
TraceLoggingString
etc.
Além de registrar eventos únicos em log, você também pode agrupar eventos por atividade usando as macros TraceLoggingWriteActivity ou TraceLoggingWriteStart/TraceLoggingWriteStop encontradas em TraceLoggingActivity.h. As atividades correlacionam eventos e são úteis para cenários que têm um começo e um fim. Por exemplo, você pode usar uma atividade para medir um cenário que começa com o início de um aplicativo, inclui o tempo necessário para que a tela inicial fique disponível e termine quando a tela inicial do aplicativo ficar visível.
As atividades capturam eventos individuais e aninham outras atividades que ocorrem entre o início e o fim dessa atividade. As atividades têm escopo por processo e devem ser passadas de thread para thread para aninhar corretamente eventos multi-threaded.
O escopo de um identificador de provedor é limitado ao módulo (arquivo DLL, EXE ou SYS) no qual ele é definido. O identificador não deve ser passado para outras DLLs. Se uma macro TraceLoggingWrite for invocada em A.DLL usando um identificador de provedor definido em B.DLL, ela poderá causar problemas. A maneira mais segura e eficiente de atender a esse requisito é sempre referenciar diretamente o identificador do provedor global e nunca passar o identificador do provedor como um parâmetro.
Cancelar o registro do provedor
Antes do descarregamento do componente, você deve cancelar o registro do provedor traceLogging. Isso é especialmente importante para DLLs e drivers. Uma falha é provável se uma DLL ou um driver descarregar sem cancelar o registro do provedor.
O código a seguir cancela o registro do provedor:
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
Compatibilidade
Dependendo de sua configuração, TraceLoggingProvider.h pode ser compatível com versões anteriores (o programa resultante será executado noWindows Vista ou posterior) ou pode ser otimizado para versões posteriores do sistema operacional. TraceLoggingProvider.h usa WINVER (modo de usuário) e NTDDI_VERSION (modo kernel) para determinar se ele deve ser compatível com versões anteriores do sistema operacional ou ser otimizado para versões mais recentes do sistema operacional.
Para o modo de usuário, se você incluir <windows.h>
antes de definir WINVER, <windows.h>
definirá WINVER como a versão padrão do sistema operacional de destino do SDK. Se WINVER estiver definido como 0x602 ou superior, TraceLoggingProvider.h
otimize seu comportamento para o Windows 8 ou posterior e seu aplicativo não será executado em versões anteriores do Windows. Se você precisar que seu programa seja executado no Vista ou no Windows 7, defina WINVER com o valor apropriado antes de <windows.h>
incluir .
Da mesma forma, se você incluir <wdm.h>
antes de definir NTDDI_VERSION, <wdm.h>
definirá NTDDI_VERSION como um valor padrão. Se NTDDI_VERSION estiver definido como 0x06040000 ou superior, TraceLoggingProvider.h otimizará seu comportamento para o Windows 10 e seu driver não funcionará em versões anteriores do Windows.
Esse comportamento pode ser controlado pela configuração TLG_HAVE_EVENT_SET_INFORMATION
antes de TraceLoggingProvider.h
incluir .
Consulte os comentários no TraceLoggingProvider.h
cabeçalho para obter detalhes sobre a TLG_HAVE_EVENT_SET_INFORMATION
macro.
Resumo e próximas etapas
Para ver como capturar e exibir dados do TraceLogging usando as Ferramentas de Desempenho do Windows (WPT), consulte Registrar e exibir eventos de rastreamento de log.
Consulte exemplos de rastreamento C/C++ para obter mais exemplos de TraceLogging em C++.