Трассировка приложений .NET с помощью PerfCollect

Эта статья применяется к: ✔️ Пакет SDK для .NET Core 2.1 и более поздних версий

При возникновении проблем с производительностью в Linux сбор данных трассировки с perfcollect можно использовать для получения подробных сведений о том, что произошло на компьютере, когда возникла проблема с производительностью.

perfcollect — это скрипт Bash, использующий Linux Tracing Tookit-Next Generation (LTTng) для сбора событий, записываемых из среды выполнения, или EventSource, а также perf для сбора образцов ЦП целевого процесса.

Подготовка компьютера

Выполните следующие действия, чтобы подготовить компьютер к собранию трассировки производительности с perfcollect.

Примечание.

Если вы захватываете из контейнера, контейнер должен иметь соответствующие возможности. Минимальные необходимые возможности:PERFMONSYS_PTRACE Если запись завершается сбоем с минимальным набором, добавьте SYS_ADMIN возможность в контейнер. Дополнительные сведения о трассировке приложений в контейнерах с помощью PerfCollect см. в разделе Сбор диагностики в контейнерах.

  1. Загрузите perfcollect.

    curl -OL https://aka.ms/perfcollect
    
  2. Сделайте файл скрипта исполняемым.

    chmod +x perfcollect
    
  3. Установите необходимые компоненты для трассировки — фактические библиотеки трассировки.

    sudo ./perfcollect install
    

    На компьютере будут установлены следующие необходимые компоненты:

    1. perf: подсистема событий производительности Linux и сопутствующее приложение для сбора и просмотра в пользовательском режиме. perf является частью источника ядра Linux, но обычно не устанавливается по умолчанию.

    2. LTTng: используется для записи данных событий, возникших во время выполнения CoreCLR. Эти данные затем используются для анализа поведения различных компонентов среды выполнения, таких как GC, JIT и пул потоков.

Последние версии .NET Core и средство производительности Linux поддерживают автоматическое разрешение имен методов для кода платформы.

Для разрешения имен методов в собственных библиотеках DLL времени выполнения (например, libcoreclr.so) perfcollect будет разрешать символы при преобразовании данных, но только в том случае, если символы для этих двоичных файлов существуют. Дополнительные сведения см. в разделе Получение символов для собственной среды выполнения.

Сбор трассировки

  1. Понадобится две оболочки: одна для управления трассировкой, или [Trace], и одна для запуска приложения, или [App].

  2. [Trace] Запустите сбор.

    sudo ./perfcollect collect sampleTrace
    

    Ожидаемые выходные данные:

    Collection started.  Press CTRL+C to stop.
    
  3. [App] Настройте оболочку приложения со следующими переменными среды — это позволяет отслеживать конфигурацию CoreCLR.

    export DOTNET_PerfMapEnabled=1
    export DOTNET_EnableEventLog=1
    

    Примечание.

    При выполнении приложения с помощью .NET 7 необходимо также задать DOTNET_EnableWriteXorExecute=0 в дополнение к предыдущим переменным среды. Рассмотрим пример.

    export DOTNET_EnableWriteXorExecute=0
    

    Примечание.

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

  4. [App] Запустите приложение. Пусть оно выполняется до тех пор, пока вы не соберете данные о проблеме с производительностью. Приложение должно выполняться столько, сколько это необходимо для захвата периода, когда возникла соответствующая проблема с производительностью.

    dotnet run
    
  5. [Trace] Прекратите сбор, нажав клавиши CTRL+C.

    ^C
    ...STOPPED.
    
    Starting post-processing. This may take some time.
    
    Generating native image symbol files
    ...SKIPPED
    Saving native symbols
    ...FINISHED
    Exporting perf.data file
    ...FINISHED
    Compressing trace files
    ...FINISHED
    Cleaning up artifacts
    ...FINISHED
    
    Trace saved to sampleTrace.trace.zip
    

    Сжатый файл трассировки теперь хранится в текущем рабочем каталоге.

Просмотр трассировки

Существует несколько вариантов просмотра собранных данных трассировки. Удобнее всего просматривать трассировки с помощью PerfView в Windows, но их можно просматривать непосредственно в Linux с помощью PerfCollect или TraceCompass.

Использование PerfCollect для просмотра файла трассировки

Для просмотра собранной трассировки можно использовать PerfCollect. Для этого воспользуйтесь следующей командой:

./perfcollect view sampleTrace.trace.zip

По умолчанию при этом отображается трассировка ЦП приложения с помощью perf.

Чтобы изучить события, собранные с помощью LTTng, можно передать флаг -viewer lttng и просмотреть отдельные события:

./perfcollect view sampleTrace.trace.zip -viewer lttng

Для вывода полезных данных событий будет использоваться средство просмотра babeltrace:

# [01:02:18.189217659] (+0.020132603) ubuntu-xenial DotNETRuntime:ExceptionThrown_V1: { cpu_id = 0 }, { ExceptionType = "System.Exception", ExceptionMessage = "An exception happened", ExceptionEIP = 139875671834775, ExceptionHRESULT = 2148734208, ExceptionFlags = 16, ClrInstanceID = 0 }
# [01:02:18.189250227] (+0.020165171) ubuntu-xenial DotNETRuntime:ExceptionCatchStart: { cpu_id = 0 }, { EntryEIP = 139873639728404, MethodID = 139873626968120, MethodName = "void [helloworld] helloworld.Program::Main(string[])", ClrInstanceID = 0 }

Открытие файла трассировки с помощью PerfView

Чтобы просмотреть общее представление примера ЦП и событий, можно использовать PerfView на компьютере Windows.

  1. Скопируйте файл trace.zip из Linux на компьютер Windows.

  2. Скачайте PerfView с https://aka.ms/perfview.

  3. Запуск PerfView.exe

    PerfView.exe <path to trace.zip file>
    

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

  • Для изучения ресурсов ЦП выберите CPU stacks.

  • Для получения подробных сведений о сборке мусора выберите GCStats.

  • Чтобы получить сведения о JIT для каждого процесса, модуля или метода, выберите JITStats.

  • Если представления для необходимой информации нет, можно попробовать найти события в представлении необработанных событий. Выберите События.

Дополнительные сведения о интерпретации представлений в PerfView см. по ссылкам справки в самом представлении или в главном окне в PerfView, а также в руководстве по справкам> для пользователей.

Примечание.

События, записанные через API System.Diagnostics.Tracing.EventSource (включая события из Framework), не будут включать данные об имени поставщика. Они записываются как события EventSourceEvent от поставщика Microsoft-Windows-DotNETRuntime, а для их полезных данных выполняется сериализация в формате JSON.

Примечание.

Если вы наблюдаете [unknown] /memfd:doublemapper кадры в именах методов и вызовах, задайте перед DOTNET_EnableWriteXorExecute=0 запуском приложения, которое вы трассируете с помощью perfcollect.

Открытие файла трассировки с помощью TraceCompass

Eclipse TraceCompass — это еще один вариант, который можно использовать для просмотра трассировок. TraceCompass работает на компьютерах Linux, поэтому вам не нужно перемещать трассировку на компьютер Windows. Чтобы открыть файл трассировки с помощью TraceCompass, необходимо распаковать его.

unzip myTrace.trace.zip

perfcollect сохранит записанную трассировку LTTng в формате файла CTF в подкаталоге в lttngTrace. В частности, файл CTF будет находиться в аналогичном каталоге: lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\.

Вы можете открыть файл трассировки CTF в TraceCompass, выбрав File -> Open Trace и файл metadata.

Подробности см. в документации по TraceCompass.

Получение символов для собственной среды выполнения

В большинстве случаев вы заинтересованы в своем коде, который perfcollect разрешает по умолчанию. Иногда бывает полезно понять, что происходит внутри библиотек DLL .NET (как указано в последнем разделе), но иногда интересно узнать, что происходит в библиотеках собственной среды выполнения (обычно это libcoreclr.so). perfcollect будет разрешать символы при преобразовании данных, но только если символы для этих собственных библиотек DLL присутствуют (и находятся рядом с библиотекой, для которой они предназначены).

Для этого существует глобальная команда dotnet-symbol. Чтобы использовать dotnet-symbol для получения собственных символов среды выполнения:

  1. Установите dotnet-symbol:

    dotnet tool install -g dotnet-symbol
    
  2. Скачайте символы. Если установлена версия среды выполнения .NET Core 2.1.0, выполните следующую команду:

    mkdir mySymbols
    dotnet symbol --symbols --output mySymbols  /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
    
  3. Скопируйте символы в правильное место.

    sudo cp mySymbols/* /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0
    

    Если это не удается сделать из-за отсутствия доступа на запись к соответствующему каталогу, можно использовать perf buildid-cache для добавления символов.

После этого необходимо получить символьные имена для собственных библиотек DLL при запуске perfcollect.

Сборка в контейнере Docker

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

Подробнее о параметрах сбора

Можно указать следующие необязательные флаги с perfcollect, чтобы обеспечить более качественную диагностику.

Сбор в течение определенного периода времени

Если требуется получить трассировку за определенное время, можно использовать параметр -collectsec, после которого следует число, указывающее общее количество секунд для получения трассировки.

Получение трассировок времени потока

Указав -threadtime с perfcollect, можно получить данные об использовании ЦП для каждого потока. Это позволяет анализировать, на что каждый поток тратит время ЦП.

Сбор трассировок для управляемой памяти и производительности сборщика мусора

Следующие параметры позволяют специально собирать события сборки мусора из среды выполнения.

  • perfcollect collect -gccollectonly

Сбор только минимального набора событий коллекции сборки мусора. Это наименее подробный профиль сбора коллекции сборки мусора с наименьшим влиянием на производительность целевого приложения. Эта команда аналогична команде PerfView.exe /GCCollectOnly collect в PerfView.

  • perfcollect collect -gconly

Сбор более подробных событий коллекции сборки мусора с помощью JIT, загрузчика и событий исключений. Запрос более подробных событий (таких как сведения о выделении памяти и сведения о присоединении к сборке мусора), который влияет на производительность целевого приложения больше, чем вариант -gccollectonly. Эта команда аналогична команде PerfView.exe /GCOnly collect в PerfView.

  • perfcollect collect -gcwithheap

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