EventPipe

EventPipe est un composant de runtime qui peut être utilisé pour collecter des données de suivi, comme ETW ou LTTng. L’objectif d’EventPipe est de permettre aux développeurs .NET de suivre facilement leurs applications .NET sans avoir à s’appuyer sur des composants natifs du système d’exploitation spécifiques à la plateforme tels que ETW ou LTTng.

EventPipe est le mécanisme derrière de nombreux outils de diagnostic et peut être utilisé pour consommer des événements émis par le runtime, ainsi que des événements personnalisés écrits avec EventSource.

Cet article est une vue d’ensemble générale d’EventPipe. Il décrit quand et comment utiliser EventPipe, et comment le configurer en fonction de vos besoins.

Concepts de base d’EventPipe

EventPipe agrège les événements émis par les composants de runtime (par exemple, le compilateur juste-à-temps ou le récupérateur de mémoire) et les événements écrits à partir d’instances EventSource dans les bibliothèques et le code utilisateur.

Les événements sont ensuite sérialisés au format de fichier .nettrace et peuvent être écrits directement dans un fichier ou diffusés via un port de diagnostic pour une consommation hors processus.

Pour en savoir plus sur le format de sérialisation EventPipe, reportez-vous à la documentation sur le format EventPipe.

EventPipe vs. ETW/LTTng

EventPipe fait partie du runtime .NET (CoreCLR) et est conçu pour fonctionner de la même façon sur toutes les plateformes prises en charge par .NET Core. Cela permet aux outils de suivi basés sur EventPipe, tels que dotnet-counters, dotnet-gcdump et dotnet-trace, de fonctionner de manière fluide sur les plateformes.

Toutefois, étant donné que EventPipe est un composant intégré au runtime, son étendue est limitée au code managé et au runtime lui-même. EventPipe ne peut pas être utilisé pour le suivi de certains événements de niveau inférieur, tels que la résolution de la pile de code native ou l’obtention de différents événements de noyau. Si vous utilisez l’interopérabilité C/C++ dans votre application ou que vous souhaitez suivre le runtime lui-même (écrit en C++), ou effectuer un diagnostic plus approfondi du comportement de l’application qui nécessite des événements de noyau (c’est-à-dire, des événements de basculement de contexte de thread natif), vous devez utiliser ETW ou perf/LTTng.

Une autre différence majeure entre EventPipe et ETW/LTTng est l’exigence de privilège administrateur/racine. Pour suivre une application à l’aide d’ETW ou LTTng, vous devez être administrateur/racine. À l’aide d’EventPipe, vous pouvez suivre les applications tant que le traceur (par exemple, dotnet-trace) est exécuté en tant qu’utilisateur identique à l’utilisateur qui a lancé l’application.

Le tableau suivant récapitule les différences entre EventPipe et ETW/LTTng.

Fonctionnalité EventPipe ETW LTTng
Multiplateforme Oui Non (uniquement sur Windows) Non (uniquement sur les distributions Linux prises en charge)
Exiger le privilège d’administrateur/racine Non Oui Oui
Peut obtenir des événements de système d’exploitation/noyau Non Oui Oui
Peut résoudre des piles d’appels natives Non Oui Oui

Utiliser EventPipe pour suivre votre application .NET

Vous pouvez utiliser EventPipe pour suivre votre application .NET de plusieurs façons :

Une fois que vous avez produit un fichier nettrace qui contient vos événements EventPipe, vous pouvez afficher le fichier dans PerfView ou Visual Studio. Sur les plateformes non-Windows, vous pouvez convertir le fichier nettrace dans un format de suivi speedscope ou Chromium à l’aide de la commande dotnet-trace convert et l’afficher avec speedscope ou Chrome DevTools.

Vous pouvez également analyser les traces EventPipe par programme avec TraceEvent.

Outils qui utilisent EventPipe

Il s’agit du moyen le plus simple d’utiliser EventPipe pour suivre votre application. Pour en savoir plus sur l’utilisation de chacun de ces outils, reportez-vous à la documentation de chaque outil.

  • dotnet-counters vous permet de surveiller et de collecter différentes métriques émises par le runtime .NET et les bibliothèques principales, ainsi que les métriques personnalisées que vous pouvez écrire.

  • dotnet-gcdump vous permet de collecter des vidages de tas GC de processus en direct pour analyser le tas managé d’une application.

  • dotnet-trace vous permet de collecter des traces d’applications pour en analyser les performances.

Effectuer un suivi à l’aide de variables d’environnement

Le mécanisme préféré pour l’utilisation d’EventPipe consiste à utiliser dotnet-trace ou la bibliothèque Microsoft.Diagnostics.NETCore.Client.

Toutefois, vous pouvez utiliser les variables d’environnement suivantes pour configurer une session EventPipe sur une application et faire en sorte qu’elle écrive la trace directement dans un fichier. Pour arrêter le suivi, quittez l’application.

  • DOTNET_EnableEventPipe : définissez cette variable sur 1 pour démarrer une session EventPipe qui écrit directement dans un fichier. La valeur par défaut est 0.

  • DOTNET_EventPipeOutputPath : chemin d’accès au fichier de trace EventPipe de sortie lorsqu’il est configuré pour s’exécuter via DOTNET_EnableEventPipe. La valeur par défaut est trace.nettrace, qui sera créée dans le même répertoire que celui à partir duquel l’application s’exécute.

    Notes

    À partir de .NET 6, les instances de la chaîne {pid} dans DOTNET_EventPipeOutputPath sont remplacées par l’ID du processus en cours de suivi.

  • DOTNET_EventPipeCircularMB : valeur hexadécimale qui représente la taille de la mémoire tampon interne d’EventPipe en mégaoctets. Cette valeur de configuration est utilisée uniquement lorsque EventPipe est configuré pour s’exécuter via DOTNET_EnableEventPipe. La taille de mémoire tampon par défaut est de 1024 Mo, qui se traduit par cette variable d’environnement définie sur 400, depuis == 0x4001024.

    Notes

    Si le processus cible écrit des événements trop fréquemment, il peut dépasser la capacité de cette mémoire tampon et certains événements peuvent être supprimés. Si trop d’événements sont supprimés, augmentez la taille de la mémoire tampon pour voir si le nombre d’événements supprimés diminue. Si le nombre d’événements supprimés ne diminue pas avec une taille de mémoire tampon plus grande, cela peut être dû à un lecteur lent empêchant le vidage des mémoires tampons du processus cible.

  • DOTNET_EventPipeProcNumbers : définissez cette variable d’environnement sur 1 pour activer la capture des numéros de processeur dans les en-têtes d’événement EventPipe. La valeur par défaut est 0.

  • DOTNET_EventPipeConfig : définit la configuration de session EventPipe lors du démarrage d’une session EventPipe avec DOTNET_EnableEventPipe. La syntaxe est la suivante :

    <provider>:<keyword>:<level>

    Vous pouvez également spécifier plusieurs fournisseurs en les concaténant à l’aide d’une virgule :

    <provider1>:<keyword1>:<level1>,<provider2>:<keyword2>:<level2>

    Si cette variable d’environnement n’est pas définie, mais qu’EventPipe est activé par DOTNET_EnableEventPipe, il démarre le suivi en activant les fournisseurs suivants avec les mots clés et niveaux suivants :

    • Microsoft-Windows-DotNETRuntime:4c14fccbd:5
    • Microsoft-Windows-DotNETRuntimePrivate:4002000b:5
    • Microsoft-DotNETCore-SampleProfiler:0:5

    Pour en savoir plus sur certains fournisseurs connus dans .NET, reportez-vous aux fournisseurs d’événements connus.

Notes

.NET 6 se normalise sur le préfixe DOTNET_ au lieu de COMPlus_ pour les variables d’environnement qui configurent le comportement au moment de l’exécution de .NET. Toutefois, le préfixe COMPlus_ continuera à fonctionner. Si vous utilisez une version précédente du runtime .NET, vous devez tout de même utiliser le préfixe COMPlus_.