Каналы событий

EventPipe — это компонент среды выполнения, который можно использовать для получения данных трассировки, аналогично ETW или LTTng. Цель использования EventPipe заключается в том, чтобы позволить разработчикам .NET с легкостью отслеживать свои приложения .NET, не прибегая к собственным компонентам операционной системы, таким как ETW или LTTng.

EventPipe — это механизм для многих средств диагностики, который можно использовать для потребления событий, генерируемых средой выполнения, а также настраиваемых событий, написанных с помощью EventSource.

Эта статья представляет собой общий обзор EventPipe. Здесь описано, как и когда использовать EventPipe, а также как настроить это средство в соответствии с вашими потребностями.

Основы EventPipe

EventPipe объединяет события, созданные компонентами среды выполнения, например JIT-компилятором или сборщиком мусора, а также события, записанные из экземпляров EventSource в библиотеках и пользовательском коде.

Затем события сериализуются в .nettrace формате файла и могут быть записаны непосредственно в файл или передаваться через порт диагностики для использования внепроцессного использования.

Дополнительные сведения о формате сериализации EventPipe см. в документации по формату EventPipe.

EventPipe vs. ETW/LTTng

EventPipe является частью среды выполнения .NET (CoreCLR) и разработан так же, как и на всех платформах, поддерживаемых .NET Core. Это позволяет средствам трассировки, основанным на EventPipe, например dotnet-counters, dotnet-gcdump и dotnet-trace, беспрепятственно работать на разных платформах.

Однако, поскольку EventPipe является встроенным компонентом среды выполнения, его область ограничена управляемым кодом и самой средой выполнения. EventPipe нельзя использовать для отслеживания некоторых событий низкого уровня, таких как разрешение стека машинного кода или получение различных событий ядра. Если вы используете в своем приложении межпроцессное взаимодействие C/C++ или требуется отследить саму среду выполнения (написанную на C++), а может, хотите глубже отслеживать поведение приложения, которое требует событий ядра (то есть событий переключения контекста в собственном потоке), следует использовать ETW или perf/LTTng.

Еще одно важное различие между EventPipe и ETW/LTTng — обязательное наличие прав администратора или прав корневого уровня. Чтобы выполнить трассировку приложения с помощью ETW или LTTng, необходимо быть администратором или обладать правами корневого уровня. С помощью EventPipe можно выполнять трассировку приложений, если трассировка (например, dotnet-trace) выполняется от имени пользователя, запустившего приложение.

В следующей таблице приведена сводка различий между EventPipe и ETW/LTTng.

Функция Каналы событий Трассировка событий Windows LTTng
Кросс-платформенность Да Нет (только в Windows) Нет (только в поддерживаемых дистрибутивах Linux)
Требуются права администратора или корневого пользователя No Да Да
Может получить события операционной системы или ядра No Да Да
Может разрешить собственные стеки вызовов No Да Да

Использование EventPipe для трассировки приложения .NET

EventPipe можно использовать для трассировки приложения .NET различными способами:

После создания файла nettrace, содержащего события EventPipe, можно просмотреть файл в PerfView или Visual Studio. На платформах, отличных от Windows, можно преобразовать файл nettrace в формат трассировки speedscope или Chromium с помощью команды dotnet-trace convert и просмотреть ее с помощью speedscope или Chrome DevTools.

Трассировки EventPipe можно также анализировать программно с помощью TraceEvent.

Средства, использующие EventPipe

Это самый простой способ использовать EventPipe для трассировки приложения. Дополнительные сведения об использовании каждого из этих средств см. в документации к каждому средству.

  • dotnet-counters позволяет отслеживать и получать различные метрики, созданные средой выполнения .NET и основными библиотеками, а также пользовательские метрики, которые можно писать.

  • dotnet-gcdump позволяет выполнять сбор дампов кучи сборщика мусора для активных процессов для анализа управляемой кучи приложения.

  • dotnet-trace позволяет собирать данные анализа производительности приложений.

Трассировка с помощью переменных среды

Предпочтительным механизмом для использования EventPipe является средство dotnet-trace или библиотека Microsoft.Diagnostics.NETCore.Client.

Однако можно использовать следующие переменные среды для настройки сеанса EventPipe в приложении и записи трассировки непосредственно в файл. Чтобы прекратить трассировку, закройте приложение.

  • DOTNET_EnableEventPipe: задайте для этого значение, чтобы 1 запустить сеанс EventPipe, который записывает непосредственно в файл. Значение по умолчанию — 0.

  • DOTNET_EventPipeOutputPath: путь к выходному файлу трассировки EventPipe при настройке его запуска через DOTNET_EnableEventPipe. Значение по умолчанию — trace.nettrace, которое будет создано в том же каталоге, из которого выполняется приложение.

    Примечание.

    Начиная с версии .NET 6, экземпляры строки {pid} в DOTNET_EventPipeOutputPath заменяются идентификатором отслеживаемого процесса.

  • DOTNET_EventPipeCircularMB: шестнадцатеричное значение, представляющее размер внутреннего буфера EventPipe в мегабайтах. Это значение конфигурации используется только в том случае, если EventPipe настроен для выполнения через DOTNET_EnableEventPipe. Размер буфера по умолчанию — 1024 МБ, который для этой переменной среды преобразуется в значение 400, поскольку 0x400 == 1024.

    Примечание.

    Если для целевого процесса события записываются слишком часто, это может привести к переполнению буфера и удалению некоторых событий. Если удаляется слишком много событий, увеличьте размер буфера и посмотрите, уменьшается ли число удаленных событий. Если не уменьшается, причиной может быть медленная работа средства чтения, из-за чего целевой буфер процесса не освобождается.

  • DOTNET_EventPipeProcNumbers: установите значение 1, чтобы включить захват номеров процессоров в заголовках событий EventPipe. Значение по умолчанию — 0.

  • DOTNET_EventPipeConfig: настраивает конфигурацию сеанса EventPipe при запуске сеанса EventPipe с DOTNET_EnableEventPipe. Синтаксис выглядит следующим образом:

    <provider>:<keyword>:<level>

    Можно также указать несколько поставщиков, объединив их с помощью запятой:

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

    Если эта переменная среды не задана, но EventPipe включен с помощью DOTNET_EnableEventPipe, компонент начнет трассировку, включив следующие поставщики со следующими ключевыми словами и уровнями:

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

    Дополнительные сведения о некоторых известных поставщиках в .NET см. в статье Стандартные поставщики событий в .NET.

Примечание.

.NET 6 стандартизует префикс DOTNET_ вместо COMPlus_ для переменных среды, которые настраивают поведение .NET во время выполнения. Но префикс COMPlus_ будет и дальше работать. Если вы используете предыдущую версию среды выполнения .NET, следует и дальше использовать префикс COMPlus_ для переменных среды.