Démarrage rapide de TraceLogging C/C++
La section suivante décrit les étapes de base requises pour ajouter TraceLogging au code en mode utilisateur C/C++.
Prérequis
- Microsoft Visual Studio 2013 ou une version ultérieure.
- Windows 10 kit de développement logiciel (SDK) est requis pour écrire un fournisseur en mode utilisateur.
- Le Kit de pilotes Windows (WDK) pour Windows 10 est nécessaire pour écrire un fournisseur en mode noyau.
Important
Pour éviter les erreurs de l’éditeur de liens pour les fonctions , EventWriteTransfer
ou EventUnregister
non résoluesEventRegister
, liez avec advapi32.lib
lors de la compilation de ces exemples.
Pour collecter et décoder des événements à partir de ces exemples, vous devez démarrer une trace à l’aide d’un outil tel que tracelog ou traceview, exécuter l’exemple, arrêter la trace à l’aide d’un outil comme tracelog ou traceview, et décoder la trace à l’aide d’un outil de décodage comme tracefmt ou traceview. Par exemple, si mon fournisseur a été défini à l’aide du GUID {0205c616-cf97-5c11-9756-56a2cee02ca7}
, je peux afficher les événements de ces exemples à l’aide des outils de suivi et de tracefmt des outils sdk Windows comme suit :
tracelog -start MyTraceSession -f MyTraceFile.etl -guid #0205c616-cf97-5c11-9756-56a2cee02ca7
- Exécutez l'exemple.
tracelog -stop MyTraceSession
tracefmt -o MyTraceFile.txt MyTraceFile.etl
notepad MyTraceFile.txt
SimpleTraceLoggingExample.h
Cet exemple d’en-tête inclut les API TraceLogging et déclare le handle du fournisseur qui sera utilisé pour journaliser les événements. Toute classe qui souhaite utiliser TraceLogging inclut cet en-tête et peut ensuite démarrer la journalisation.
#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);
Le fichier d’en-tête inclut TraceLoggingProvider.h
qui définit l’API TraceLogging C/C++. Vous devez d’abord inclure windows.h
, car il définit les constantes utilisées par TraceLoggingProvider.h
.
Le transfert du fichier d’en-tête déclare le handle g_hMyComponentProvider
du fournisseur que vous passerez aux API TraceLogging pour journaliser les événements. Ce handle doit être accessible à tout code qui souhaite utiliser TraceLogging.
TRACELOGGING_DECLARE_PROVIDER est une macro qui crée un extern const TraceLoggingHProvider
handle à l’aide du nom que vous fournissez, qui est g_hMyComponentProvider
dans l’exemple ci-dessus.
Vous allouez la variable de handle fournisseur réelle dans un fichier de code.
SimpleTraceLoggingExample.cpp
L’exemple suivant inscrit le fournisseur, journalise un événement et annule l’inscription du fournisseur.
#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);
}
L’exemple ci-dessus inclut SimpleTraceLoggingExample.h qui contient la variable de fournisseur globale que votre code utilisera pour journaliser les événements.
La macro TRACELOGGING_DEFINE_PROVIDER alloue du stockage et définit la variable de handle du fournisseur. Le nom de la variable que vous fournissez à cette macro doit correspondre au nom que vous avez utilisé dans la macro TRACELOGGING_DECLARE_PROVIDER dans votre fichier d’en-tête.
Inscrire le handle du fournisseur
Avant de pouvoir utiliser le handle du fournisseur pour journaliser les événements, vous devez appeler TraceLoggingRegister pour inscrire votre handle de fournisseur. Cette opération est généralement effectuée dans main() ou DLLMain(), mais elle peut être effectuée à tout moment tant qu’elle précède toute tentative de journalisation d’un événement. Si vous journalisez un événement avant d’inscrire le handle du fournisseur, aucune erreur ne se produit, mais l’événement n’est pas journalisé. Le code suivant de l’exemple ci-dessus inscrit le handle du fournisseur.
// 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);
Journaliser un événement Tracelogging
Une fois le fournisseur inscrit, le code suivant journalise un événement simple.
// 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).
La macro TraceLoggingWrite accepte jusqu’à quatre-vingt-dix-neuf arguments. Le nom de l’événement est stocké au format UTF-8. Vous ne devez pas utiliser de caractères incorporés '\0'
dans le nom de l’événement ou les noms de champs. Il n’existe aucune autre limite sur les caractères autorisés, bien que certains décodeurs d’événements ou processeurs d’événements puissent avoir leurs propres limitations.
Chaque argument suivant le nom de l’événement doit être encapsulé à l’intérieur d’une macro wrapper TraceLogging. Si vous utilisez C++, vous pouvez utiliser la TraceLoggingValue
macro wrapper pour déduire automatiquement le type de l’argument. Si vous écrivez en C ou si vous souhaitez mieux contrôler le type de champ, vous devez utiliser des macros de champ spécifiques au type telles que TraceLoggingInt32
, TraceLoggingUnicodeString
, TraceLoggingString
, etc.
En plus de journaliser des événements uniques, vous pouvez également regrouper des événements par activité à l’aide des macros TraceLoggingWriteActivity ou TraceLoggingWriteStart/TraceLoggingWriteStop trouvées dans TraceLoggingActivity.h. Les activités mettent en corrélation les événements et sont utiles pour les scénarios qui ont un début et une fin. Par exemple, vous pouvez utiliser une activité pour mesurer un scénario qui commence par le lancement d’une application, inclut le temps nécessaire pour que l’écran de démarrage devienne disponible et se termine lorsque l’écran initial de l’application devient visible.
Les activités capturent des événements uniques et imbriquez d’autres activités qui se produisent entre le début et la fin de cette activité. Les activités ont une étendue par processus et doivent être passées d’un thread à un autre pour imbriquer correctement les événements multithread.
L’étendue d’un handle de fournisseur est limitée au module (FICHIER DLL, EXE ou SYS) dans lequel il est défini. Le handle ne doit pas être passé à d’autres DLL. Si une macro TraceLoggingWrite est appelée dans A.DLL à l’aide d’un handle de fournisseur défini dans B.DLL, cela peut entraîner des problèmes. Le moyen le plus sûr et le plus efficace de répondre à cette exigence consiste simplement à toujours référencer directement le handle du fournisseur global et à ne jamais le transmettre en tant que paramètre.
Annuler l’inscription du fournisseur
Avant le déchargement de votre composant, vous devez annuler l’inscription du fournisseur TraceLogging. Ceci est particulièrement important pour les DLL et les pilotes. Un incident est probable si une DLL ou un pilote se décharge sans désinscrire du fournisseur.
Le code suivant annule l’inscription du fournisseur :
// Stop TraceLogging and unregister the provider
TraceLoggingUnregister(g_hMyComponentProvider);
Compatibilité
En fonction de sa configuration, TraceLoggingProvider.h peut être à compatibilité descendante (le programme résultant s’exécutera sur Windows Vista ou version ultérieure) ou peut être optimisé pour les versions ultérieures du système d’exploitation. TraceLoggingProvider.h utilise WINVER (mode utilisateur) et NTDDI_VERSION (mode noyau) pour déterminer s’il doit être compatible avec les versions antérieures du système d’exploitation ou optimisé pour les versions plus récentes du système d’exploitation.
Pour le mode utilisateur, si vous incluez <windows.h>
avant de définir WINVER, <windows.h>
définit WINVER sur la version du système d’exploitation cible par défaut du SDK. Si WINVER est défini sur 0x602 ou supérieur, TraceLoggingProvider.h
optimise son comportement pour Windows 8 ou version ultérieure et votre application ne s’exécutera pas sur les versions antérieures de Windows. Si vous avez besoin que votre programme s’exécute sur Vista ou Windows 7, veillez à définir WINVER sur la valeur appropriée avant d’inclure <windows.h>
.
De même, si vous incluez <wdm.h>
avant de définir NTDDI_VERSION, <wdm.h>
définit NTDDI_VERSION sur une valeur par défaut. Si NTDDI_VERSION est défini sur 0x06040000 ou une version ultérieure, TraceLoggingProvider.h optimise son comportement pour Windows 10 et votre pilote ne fonctionnera pas sur les versions antérieures de Windows.
Ce comportement peut être contrôlé en définissant TLG_HAVE_EVENT_SET_INFORMATION
avant d’inclure TraceLoggingProvider.h
.
Pour plus d’informations sur la macro, reportez-vous aux commentaires dans TraceLoggingProvider.h
l’en-tête TLG_HAVE_EVENT_SET_INFORMATION
.
Résumé et étapes suivantes
Pour savoir comment capturer et afficher des données TraceLogging à l’aide des outils de performances Windows (WPT), consultez Enregistrer et afficher les événements TraceLogging.
Pour plus d’exemples de traceLogging C/C++ , consultez Exemples de suivi C/C++.