Программа анализа производительности dotnet-trace

Эта статья относится к: ✔️ dotnet-trace 3.0.47001 и более поздним версиям

Установка

Есть два способа загрузки и установки dotnet-trace:

  • Средство dotnet global:

    Чтобы установить последнюю версию пакета NuGet dotnet-trace, используйте команду dotnet tool install.

    dotnet tool install --global dotnet-trace
    
  • Прямое скачивание:

    скачайте исполняемый файл средства, соответствующий вашей платформе:

    ОС Платформа
    Windows x86 x64 Arm-x64 Arm-x64 | | |
    Linux x64 Arm64 | | | musl-x64 musl-arm64 |

Краткие сведения

dotnet-trace [-h, --help] [--version] <command>

Description

Программа dotnet-trace —

  • это кроссплатформенное средство .NET Core.
  • Выполняет сбор трассировок .NET Core для запущенного процесса без встроенного профилировщика.
  • Построен на EventPipe среды выполнения .NET Core.
  • Предоставляет одинаковые возможности в Windows, Linux и macOS.

Параметры

  • -h|--help

    Отображение справки в командной строке.

  • --version

    Отображение версии служебной программы dotnet-trace.

  • --duration

    Как долго выполнять трассировку. --duration 00:00:00:05 будет запускаться в течение 5 секунд.

Команды

Команда
dotnet-trace collect
dotnet-trace convert
dotnet-trace ps
dotnet-trace list-profiles
dotnet-trace report

dotnet-trace collect

Собирает диагностическую трассировку из запущенного процесса или запускает дочерний процесс и отслеживает его (.NET 5 или более поздней версии). Чтобы запустить дочерний процесс и отслеживать его с момента запуска в средстве, добавьте -- к команде сбора данных.

Краткие сведения

dotnet-trace collect [--buffersize <size>] [--clreventlevel <clreventlevel>] [--clrevents <clrevents>]
    [--format <Chromium|NetTrace|Speedscope>] [-h|--help] [--duration dd:hh:mm:ss]
    [-n, --name <name>] [--diagnostic-port] [-o|--output <trace-file-path>] [-p|--process-id <pid>]
    [--profile <profile-name>] [--providers <list-of-comma-separated-providers>]
    [-- <command>] (for target applications running .NET 5 or later)
    [--show-child-io] [--resume-runtime]
    [--stopping-event-provider-name <stoppingEventProviderName>]
    [--stopping-event-event-name <stoppingEventEventName>]
    [--stopping-event-payload-filter <stoppingEventPayloadFilter>]

Параметры

  • --buffersize <size>

    Задает размер буфера в памяти в мегабайтах. По умолчанию используется значение 256 МБ.

    Примечание.

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

  • --clreventlevel <clreventlevel>

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

    «Строковое значение» Числовое значение
    logalways 0
    critical 1
    error 2
    warning 3
    informational 4
    verbose 5
  • --clrevents <clrevents>

    Список ключевых слов поставщика среды выполнения CLR, которые должны быть разделены знаками +. Это простое сопоставление, позволяющее указывать ключевые слова событий посредством псевдонимов строк, а не их шестнадцатеричных значений. Например, dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:3:4 запрашивает тот же набор событий, что и dotnet-trace collect --clrevents gc+gchandle --clreventlevel informational. В таблице ниже приведен список доступных ключевых слов.

    Псевдоним строки ключевого слова Шестнадцатеричное значение ключевого слова
    gc 0x1
    gchandle 0x2
    fusion 0x4
    loader 0x8
    jit 0x10
    ngen 0x20
    startenumeration 0x40
    endenumeration 0x80
    security 0x400
    appdomainresourcemanagement 0x800
    jittracing 0x1000
    interop 0x2000
    contention 0x4000
    exception 0x8000
    threading 0x10000
    jittedmethodiltonativemap 0x20000
    overrideandsuppressngenevents 0x40000
    type 0x80000
    gcheapdump 0x100000
    gcsampledobjectallocationhigh 0x200000
    gcheapsurvivalandmovement 0x400000
    gcheapcollect 0x800000
    gcheapandtypenames 0x1000000
    gcsampledobjectallocationlow 0x2000000
    perftrack 0x20000000
    stack 0x40000000
    threadtransfer 0x80000000
    debugger 0x100000000
    monitoring 0x200000000
    codesymbols 0x400000000
    eventsource 0x800000000
    compilation 0x1000000000
    compilationdiagnostic 0x2000000000
    methoddiagnostic 0x4000000000
    typediagnostic 0x8000000000

    Дополнительные сведения о поставщике CLR см. в справочной документации по поставщику среды выполнения .NET.

  • --format {Chromium|NetTrace|Speedscope}

    Задает формат выходных данных для преобразования файла трассировки. Значение по умолчанию — NetTrace.

  • -n, --name <name>

    Имя процесса, из которого нужно получить трассировку.

  • --diagnostic-port <path-to-port>

    Имя создаваемого порта диагностики. О том, как использовать этот параметр для сбора данных трассировки из запуска приложения, см. в разделе Использование порта диагностики для сбора данных трассировки из запуска приложения.

  • --duration <time-to-run>

    Время выполнения трассировки. dd:hh:mm:ss Используйте формат. Например 00:00:00:05 , он будет запускаться в течение 5 секунд.

  • -o|--output <trace-file-path>

    Выходной путь для собранных данных трассировки. Если он не указан по умолчанию <appname>_<yyyyMMdd>_<HHmmss>.nettrace, например "myapp_20210315_111514.nettrace".

  • -p|--process-id <PID>

    Идентификатор процесса, из которого нужно получить трассировку.

  • --profile <profile-name>

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

Профиль Description
cpu-sampling Подходит для отслеживания загрузки ЦП и общих сведений среды выполнения .NET. Этот вариант используется по умолчанию, если другой профиль или поставщики не указаны.
gc-verbose Отслеживает коллекции GC и распределения объектов samples.
gc-collect Отслеживает коллекции GC только при очень низких издержках.
  • --providers <list-of-comma-separated-providers>

    Список применяемых поставщиков EventPipe, разделенный запятыми. Поставщики из этого списка применяются в дополнение к тем, которые подразумеваются в --profile <profile-name>. При наличии несогласованности по конкретному поставщику указанная здесь конфигурация имеет приоритет над неявной конфигурацией из профиля.

    Список поставщиков предоставляется в следующем формате:

    • Provider[,Provider]
    • Provider имеет формат KnownProviderName[:Flags[:Level][:KeyValueArgs]];
    • KeyValueArgs имеет формат [key1=value1][;key2=value2];

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

  • -- <command> (для целевых приложений под управлением .NET 5 или более поздней версии)

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

    Примечание.

    С помощью этого параметра выполняется мониторинг первого процесса .NET, который взаимодействует с инструментом, что означает, что если команда запускает несколько приложений .NET, она будет собирать только первое приложение. Поэтому рекомендуется использовать этот параметр для автономных приложений или с помощью параметра dotnet exec <app.dll>.

  • --show-child-io

    Показывает входные и выходные потоки запущенного дочернего процесса в текущей консоли.

  • --resume-runtime

    Возобновление выполнения после инициализации сеанса по умолчанию имеет значение true. Отключите возобновление выполнения с помощью --resume-runtime:false.

  • --stopping-event-provider-name

    Строка, проанализированная как есть, которая остановит трассировку при нажатии события с соответствующим именем поставщика. Для более конкретного события остановки дополнительно укажите --stopping-event-event-name и/или --stopping-event-payload-filter. Например --stopping-event-provider-name Microsoft-Windows-DotNETRuntime , чтобы остановить трассировку при нажатии первого события, созданного поставщиком Microsoft-Windows-DotNETRuntime событий.

  • --stopping-event-event-name

    Строка, проанализированная как есть, которая остановит трассировку при нажатии события с соответствующим именем события. Требуется --stopping-event-provider-name задать. Для более конкретного события остановки дополнительно укажите --stopping-event-payload-filter. Например --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted , чтобы остановить трассировку при нажатии первого Method/JittingStarted события, созданного поставщиком Microsoft-Windows-DotNETRuntime событий.

  • --stopping-event-payload-filter

    Строка, проанализированная как пара [payload_field_name]:[payload_field_value], разделенная запятыми, которая остановит трассировку при нажатии события, содержащего все указанные пары полезных данных. Требуется --stopping-event-provider-name и --stopping-event-event-name задано. Например, --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodNameSpace:Program,MethodName:OnButtonClick чтобы остановить трассировку при первом Method/JittingStarted событии метода OnButtonClick в Program пространстве имен, созданном поставщиком Microsoft-Windows-DotNETRuntime событий.

Примечание.

  • Для больших приложений остановка трассировки может занять много времени (до нескольких минут). Среде выполнения необходимо передать кэш типов для всего управляемого кода, захваченного при трассировке.
  • В Linux и macOS эта команда ожидает, что целевое приложение и dotnet-trace будут совместно использовать одну и ту же переменную среды TMPDIR. В противном случае время ожидания команды истечет.
  • Чтобы собрать трассировку с помощью dotnet-trace, необходимо запустить того же пользователя, что и пользователь, выполняющий целевой процесс или корневой каталог. В противном случае средство не сможет установить соединение с целевым процессом.
  • Если во время выполнения dotnet-trace collectвозникает необработанное исключение, это приводит к неполной трассировке. Если поиск основной причины исключения является вашим приоритетом, перейдите к разделу "Сбор дампов при аварийном сбое". В результате необработанного исключения трассировка усечена, когда среда выполнения завершает работу, чтобы предотвратить другие нежелательные действия, такие как зависание или повреждение данных. Несмотря на то, что трассировка является неполной, ее можно открыть, чтобы увидеть, что произошло до сбоя. Однако в конце трассировки отсутствуют сведения о rundown (это происходит в конце трассировки), поэтому стеки могут быть неразрешенными (в зависимости от того, какие поставщики были включены). Откройте трассировку, выполнив PerfView с флагом /ContinueOnError в командной строке. Журналы также будут содержать расположение, в котором было запущено исключение.
  • При указании события остановки с помощью --stopping-event-* параметров, так как eventStream анализируется асинхронно, будут происходить некоторые события, проходящие между временем, когда событие трассировки, соответствующее указанным параметрам события остановки, анализируется, и событие EventPipeSession останавливается.

dotnet-trace convert

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

Краткие сведения

dotnet-trace convert [<input-filename>] [--format <Chromium|NetTrace|Speedscope>] [-h|--help] [-o|--output <output-filename>]

Аргументы

  • <input-filename>

    Исходный файл трассировки для преобразования. По умолчанию используется значение trace.nettrace.

Параметры

  • --format <Chromium|NetTrace|Speedscope>

    Задает формат выходных данных для преобразования файла трассировки.

  • -o|--output <output-filename>

    Имя файла выходных данных. К нему добавляется расширение целевого формата.

Примечание.

Преобразование файлов nettrace в файлы chromium или speedscope является необратимым. Файлы speedscope и chromium не содержат всей информации, необходимой для воссоздания nettrace файлов. Однако команда convert сохраняет исходный файл nettrace, поэтому не удаляйте этот файл, если вы планируете открывать его в будущем.

dotnet-trace ps

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

Примечание.

Чтобы получить полную информацию о перечисленных 64-разрядных процессах, необходимо использовать 64-разрядную версию dotnet-trace средства.

Краткие сведения

dotnet-trace ps [-h|--help]

Пример

Предположим, что вы запускаете длинное приложение с помощью команды dotnet run --configuration Release. В другом окне выполните dotnet-trace ps команду. Выходные данные, которые вы увидите, приведены ниже. Аргументы командной строки, если они доступны, отображаются в dotnet-trace версии 6.0.320703 и более поздних версиях.

> dotnet-trace ps
  
  21932 dotnet     C:\Program Files\dotnet\dotnet.exe   run --configuration Release
  36656 dotnet     C:\Program Files\dotnet\dotnet.exe

dotnet-trace list-profiles

Список предварительно созданных профилей трассировки с перечислением поставщиков и фильтров в каждом профиле.

Краткие сведения

dotnet-trace list-profiles [-h|--help]

dotnet-trace report

Позволяет создать отчет в stdout из ранее созданной трассировки.

Краткие сведения

dotnet-trace report [-h|--help] <tracefile> [command]

Аргументы

  • <tracefile>

    Путь к файлу для анализируемой трассировки.

Команды

dotnet-trace report topN

Позволяет найти основные N методов, которые дольше всего были в стеке вызовов.

Краткие сведения
dotnet-trace report <tracefile> topN [-n|--number <n>] [--inclusive] [-v|--verbose] [-h|--help]
Параметры
  • -n|--number <n>

Предоставляет основные N методов в стеке вызовов.

  • --inclusive

Выводит основные N методов на основе инклюзивного времени. Если значение не указано, по умолчанию используется эксклюзивное время.

  • -v|--verbose

Вывод параметров каждого метода в полном объеме. Если значение не указано, параметры будут усечены.

Сбор трассировки с помощью dotnet-trace

Для сбора трассировок с помощью dotnet-trace выполните указанные ниже действия.

  • Получите идентификатор процесса (PID) для трассируемого приложения .NET Core.

    • В Windows его можно получить, например, через диспетчер задач или с помощью команды tasklist.
    • В Linux можно использовать, например, команду ps.
    • dotnet-trace ps
  • Выполните следующую команду:

    dotnet-trace collect --process-id <PID>
    

    Приведенная выше команда создает выходные данные наподобие следующих:

    Press <Enter> to exit...
    Connecting to process: <Full-Path-To-Process-Being-Profiled>/dotnet.exe
    Collecting to file: <Full-Path-To-Trace>/trace.nettrace
    Session Id: <SessionId>
    Recording trace 721.025 (KB)
    
  • Чтобы остановить сбор, нажмите клавишу <Enter>. dotnet-trace завершит запись событий в файл trace.nettrace.

Запуск дочернего приложения и получение трассировки от запуска с помощью dotnet-trace

Иногда бывает полезно получить трассировку процесса от запуска. Для приложений, использующих .NET 5 или более поздней версии, это можно сделать с помощью dotnet-trace.

Это приведет к запуску hello.exe с arg1 и arg2 в качестве аргументов командной строки и сбору трассировки при запуске среды выполнения:

dotnet-trace collect -- hello.exe arg1 arg2

Приведенная выше команда создает выходные данные наподобие следующих:

No profile or providers specified, defaulting to trace profile 'cpu-sampling'

Provider Name                           Keywords            Level               Enabled By
Microsoft-DotNETCore-SampleProfiler     0x0000F00000000000  Informational(4)    --profile
Microsoft-Windows-DotNETRuntime         0x00000014C14FCCBD  Informational(4)    --profile

Process        : E:\temp\gcperfsim\bin\Debug\net5.0\gcperfsim.exe
Output File    : E:\temp\gcperfsim\trace.nettrace


[00:00:00:05]   Recording trace 122.244  (KB)
Press <Enter> or <Ctrl+C> to exit...

Вы можете отключить сбор данных трассировки, нажав клавишу <Enter> или <Ctrl + C>. Это также приведет к выходу из hello.exe.

Примечание.

При запуске файла hello.exe с помощью dotnet-trace его входные и выходные данные будут перенаправлены, и вы не сможете взаимодействовать с ним в консоли по умолчанию. Используйте параметр --show-child-io, чтобы взаимодействовать с его потоками stdin/stdout. Выход из средства с помощью клавиш CTRL+C или SIGTERM приведет к безопасному завершению работы средства и дочернего процесса. Если дочерний процесс завершает работу до средства, средство также завершит работу, а трассировка будет доступна для безопасного просмотра.

Использование порта диагностики для сбора данных трассировки из запуска приложения

Порт диагностики — это функция среды выполнения, добавленная в .NET 5, которая позволяет начать трассировку из запуска приложения. Чтобы сделать это с помощью dotnet-trace, можно использовать либо dotnet-trace collect -- <command>, как показано в приведенных выше примерах, либо параметр --diagnostic-port.

Использование dotnet-trace <collect|monitor> -- <command> для запуска приложения в качестве дочернего процесса — самый простой способ быстрой трассировки приложения с момента запуска.

Однако если требуется более точное управление временем трассировки приложения (например, отслеживать приложение только в течение первых 10 минут, а затем продолжать выполнение), или если необходимо взаимодействовать с приложением их интерфейса командной строки, используйте параметр --diagnostic-port, который позволяет управлять как отслеживаемым целевым приложением, так и dotnet-trace.

  1. Следующая команда заставляет dotnet-trace создать сокет диагностики с именем myport.sock и ожидать соединения.

    dotnet-trace collect --diagnostic-port myport.sock
    

    Выходные данные:

    Waiting for connection on myport.sock
    Start an application with the following environment variable: DOTNET_DiagnosticPorts=/home/user/myport.sock
    
  2. В отдельной консоли запустите целевое приложение с переменной среды DOTNET_DiagnosticPorts, для которой задано значение в выходных данных dotnet-trace.

    export DOTNET_DiagnosticPorts=/home/user/myport.sock
    ./my-dotnet-app arg1 arg2
    

    Это должно позволить dotnet-trace начать трассировку my-dotnet-app:

    Waiting for connection on myport.sock
    Start an application with the following environment variable: DOTNET_DiagnosticPorts=myport.sock
    Starting a counter session. Press Q to quit.
    

    Внимание

    Запуск приложения с помощью dotnet run может привести к проблемам: интерфейс командной строки dotnet может порождать множество дочерних процессов, которые не относятся к вашему приложению, и если они подключатся к dotnet-trace раньше вашего приложения, оно будет приостановлено во время выполнения. Рекомендуется использовать автономную версию приложения или запускать его с помощью dotnet exec.

Просмотр трассировки, собранной с помощью dotnet-trace

В Windows можно просматривать файлы .nettrace в Visual Studio или PerfView для анализа.

В Linux можно просмотреть трассировку, изменив выходной формат dotnet-trace speedscopeна . Измените формат выходного файла с помощью -f|--format параметра. Вы можете выбрать варианты nettrace (по умолчанию) или speedscope. -f speedscope Параметр создаст dotnet-trace speedscope файл. Файлы Speedscope можно открывать с помощью https://www.speedscope.app.

Для трассировок, собранных на платформах, отличных от Windows, можно также переместить файл трассировки на компьютер Windows и просмотреть его в Visual Studio или PerfView.

Примечание.

Среда выполнения .NET Core создает трассировки в формате nettrace. В формат speedscope (если требуется) они преобразуются уже после завершения трассировки. Так как некоторые преобразования приводят к потере данных, исходный файл nettrace сохраняется рядом с преобразованным файлом.

Использование файла RSP, чтобы не вводить длинные команды

Можно запустить команду dotnet-trace с файлом .rsp, содержащим аргументы для передачи. Это может быть полезно при включении поставщиков, для которых требуются длинные аргументы, или при использовании среды оболочки, которая обрезает символы.

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

dotnet-trace collect --providers Microsoft-Diagnostics-DiagnosticSource:0x3:5:FilterAndPayloadSpecs="SqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandBefore@Activity1Start:-Command;Command.CommandText;ConnectionId;Operation;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nSqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandAfter@Activity1Stop:\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting@Activity2Start:-Command;Command.CommandText;ConnectionId;IsAsync;Command.Connection.ClientConnectionId;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted@Activity2Stop:",OtherProvider,AnotherProvider

Кроме того, в предыдущем примере аргумент содержит символ ". Так как кавычки в каждой оболочке обрабатываются по-разному, могут возникать различные проблемы. Например, команда в zsh будет отличаться от команды в cmd.

Вместо того чтобы вводить ее каждый раз, можно сохранить следующий текст в файл с именем myprofile.rsp.

--providers
Microsoft-Diagnostics-DiagnosticSource:0x3:5:FilterAndPayloadSpecs="SqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandBefore@Activity1Start:-Command;Command.CommandText;ConnectionId;Operation;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nSqlClientDiagnosticListener/System.Data.SqlClient.WriteCommandAfter@Activity1Stop:\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting@Activity2Start:-Command;Command.CommandText;ConnectionId;IsAsync;Command.Connection.ClientConnectionId;Command.Connection.ServerVersion;Command.CommandTimeout;Command.CommandType;Command.Connection.ConnectionString;Command.Connection.Database;Command.Connection.DataSource;Command.Connection.PacketSize\r\nMicrosoft.EntityFrameworkCore/Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted@Activity2Stop:",OtherProvider,AnotherProvider

После сохранения файла myprofile.rsp можно запустить dotnet-trace с этой конфигурацией, выполнив следующую команду:

dotnet-trace @myprofile.rsp

См. также