dotnet-trace 效能分析公用程式

本文適用: ✔️ dotnet-trace 3.0.47001 與更新版本

安裝

有兩種方法可下載並安裝 dotnet-trace

注意

若要在 x86 應用程式上使用 dotnet-trace,就需要對應的 x86 版工具。

概要

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

描述

dotnet-trace 工具:

  • 是跨平台的 .NET Core 工具。
  • 可以在沒有原生分析工具的情況下,收集執行中處理序的 .NET Core 追蹤。
  • 在 .NET Core 執行階段的 EventPipe 上建置。
  • 能在 Windows、Linux 或 macOS 上提供相同的體驗。

選項。

  • -h|--help

    顯示命令列說明。

  • --version

    顯示 dotnet-trace 公用程式的版本。

  • --duration

    追蹤的執行時間長度。 --duration 00:00:00:05 將執行它 5 秒。

命令

Command
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>

    設定記憶體內部緩衝區的大小 (MB)。 預設為 256 MB。

    注意

    如果目標處理序發出事件的速度比寫入磁碟的速度還快,那麼此緩衝區可能會溢位,使部分事件受到卸除。 您可以藉由增加緩衝區大小或減少所記錄的事件數目,來減輕此問題。

  • --clreventlevel <clreventlevel>

    要發出之 CLR 事件的詳細程度。 下表顯示可用的事件等級。

    [字串值] 數值
    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

    您可以在 .NET 執行階段提供者參考文件上深入閱讀 CLR 提供者的相關資訊。

  • --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>

    一組具名預先定義的提供者組態,可讓一般追蹤案例以簡潔方式指定。 可用的設定檔如下:

設定檔 描述
cpu-sampling 適合用來追蹤 CPU 使用方式和一般 .NET 執行階段資訊。 如果未指定任何設定檔或提供者,則這是預設選項。
gc-verbose 追蹤 GC 集合和範例物件配置。
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 中的某些已知提供者,請參閱已知的事件提供者 (部分機器翻譯)。

  • -- <command> (適用於執行 .NET 5 或更新版本的目標應用程式)

    使用者可以在收集設定參數之後附加 --,緊接著一個用於啟動最少具有 5.0 執行階段之 .NET 應用程式的命令。 在診斷於處理序中早期發生的問題時 (例如啟動效能問題或組件載入器和繫結器錯誤),這可能很有幫助。

    注意

    使用此選項會監視第一個向工具回應通訊的 .NET 5 處理序,這代表如果您的命令啟動了數個 .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 用於在命中 Microsoft-Windows-DotNETRuntime 事件提供者發出的第一個 Method/JittingStarted 事件時停止追蹤。

  • --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 用於在 Microsoft-Windows-DotNETRuntime 事件提供者發出 Program 命名空間中之方法 OnButtonClick 的第一個 Method/JittingStarted 事件時停止追蹤。

注意

  • 停止大型應用程式的追蹤可能需要很長的時間 (最多數分鐘)。 執行階段必須針對在追蹤中擷取的所有受控程式碼,透過類型快取傳送。
  • 在 Linux 和 macOS 上,此命令需要目標應用程式與 dotnet-trace 共用相同的 TMPDIR 環境變數。 否則,命令將會逾時。
  • 若要使用 dotnet-trace 收集追蹤,其執行身分必須與執行目標處理序的使用者或根使用者相同。 否則,此工具將無法與目標處理序建立連線。
  • 如果您看見以下類似的錯誤訊息:[ERROR] System.ComponentModel.Win32Exception (299): A 32 bit processes cannot access modules of a 64 bit process.,則代表您在嘗試使用位元與目標處理序不相符的 dotnet-trace 版本。 請務必在安裝連結中下載正確位元的工具。
  • 如果您在執行 dotnet-trace collect 時遇到未處理的例外狀況,這會導致追蹤不完整。 如果發現例外狀況的根本原因是您的優先順序,請巡覽至在損毀時收集傾印。 因為未處理的例外狀況,使得追蹤會在執行階段關閉時受到截斷,以避免發生其他非預期的行為,例如停止回應或資料損毀。 即使追蹤不完整,您仍然可以開啟它,查看導致失敗的原因。 不過,其將會缺少取消資訊 (這會發生在追蹤的結尾),因此可能無法解析堆疊 (取決於開啟的提供者)。 在命令列使用 /ContinueOnError 旗標執行 PerfView 來開啟追蹤。 記錄也會包含引發例外狀況的位置。
  • 透過 --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 檔案轉換為 chromiumspeedscope 檔案後,便無法復原。 speedscopechromium 檔案沒有重新建構 nettrace 所需的所有資訊。 不過,convert 命令會保留原始的 nettrace 檔案,所以如果您打算日後開啟該檔案的話,請勿予以刪除。

dotnet-trace ps

列出可從中收集追蹤的 dotnet 處理序。 dotnet-trace 6.0.320703 和更新版本也會顯示啟動每個處理序時所用的命令列引數 (如果有的話)。

概要

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 收集追蹤:

  • 取得要從中收集追蹤之 .NET Core 應用程式的處理序識別碼 (PID)。

    • 在 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 或更新版本的應用程式。

有時候從啟動收集處理序追蹤很有用。 對於執行 .NET 5 或更新版本的應用程式,可以使用 dotnet-trace 來執行此動作。

這會啟動具有命令列引數 arg1arg2hello.exe,並從其執行階段啟動收集追蹤:

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

注意

透過 dotnet-trace 啟動 hello.exe 會重新導向其輸入/輸出,根據預設,您將無法在主控台上與之互動。 請用 --show-child-io 參數來與其 stdin/stdout 互動。 透過 CTRL+C 或 SIGTERM 結束工具將會安全地結束工具和子處理序。 如果子處理序在工具之前結束,則工具也會結束,您應可安全地檢視追蹤。

使用診斷連接埠從應用程式啟動收集追蹤

重要

這僅適用於執行 .NET 5 或更新版本的應用程式。

診斷連接埠是 .NET 5 中新增的執行階段功能,可讓您從應用程式啟動開始追蹤。 如要使用 dotnet-trace 這麼做,您可以使用如上述範例中所述的 dotnet-trace collect -- <command>,或是使用 --diagnostic-port 選項。

如要快速地從應用程式啟動加以追蹤,那麼使用 dotnet-trace <collect|monitor> -- <command> 將應用程式作為子處理序啟動是最簡單的方法。

不過,當您想更精細地控制受追蹤的應用程式存留期 (例如只監控應用程式前 10 分鐘並繼續執行),或是需要使用 CLI 與應用程式互動時,使用 --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 CLI 可能會繁衍許多不是您應用程式的子處理序,且它們能在您的應用程式之前連線至 dotnet-trace,使您的應用程式在執行階段受到暫止。 建議您直接使用獨立版本的應用程式,或是 dotnet exec 來啟動應用程式。

檢視從 dotnet-trace 擷取的追蹤

在 Windows 上,您可以檢視 Visual StudioPerfView 中的 .nettrace 檔案以進行分析。

在 Linux 上,您可以將 dotnet-trace 的輸出格式變更為 speedscope 來檢視追蹤。 使用 -f|--format 選項變更輸出檔案格式。 您可以選擇 nettrace (預設選項) 和 speedscope。 選項 -f speedscope 會使 dotnet-trace 產生 speedscope 檔案。 您可在 https://www.speedscope.app 開啟 Speedscope 檔案。

如為不是在 Windows 平台上收集的追蹤,您也可以將追蹤檔案移動到 Windows 機器,並在 Visual Studio 或 PerfView 中加以檢視。

注意

.NET Core 執行階段會以 nettrace 格式產生追蹤。 如有指定,則追蹤會在完成後轉換為 speedscope 格式。 由於某些轉換可能會導致資料遺失,因此會保留已轉換檔案旁的原始檔案 nettrace

使用 dotnet-trace 收集一段時間的計數器值

dotnet-trace 可以:

  • 使用 EventCounter 在重視效能的環境中進行基本狀況監控。 例如,在生產環境中。
  • 請收集追蹤,以避免需要以即時方式檢視它們的必要。

舉例來說,如要收集執行階段效能計數器值,請使用以下命令:

dotnet-trace collect --process-id <PID> --providers System.Runtime:0:1:EventCounterIntervalSec=1

上述命令惠要求執行階段計數器每秒報告一次,以進行輕量型狀況監控。 使用較高的值 (例如 60) 取代 EventCounterIntervalSec=1,可以在計數器資料中以較低的細微性收集較小的追蹤。

比起前一個命令,下列命令更能減少額外負荷和追蹤大小:

dotnet-trace collect --process-id <PID> --providers System.Runtime:0:1:EventCounterIntervalSec=1,Microsoft-Windows-DotNETRuntime:0:1,Microsoft-DotNETCore-SampleProfiler:0:1

前一個命令會停用執行階段事件和受控堆疊分析工具。

請使用 .rsp 檔案以避免鍵入過長的命令

您可以使用包含所要傳遞之引數的 .rsp 檔案來啟動 dotnet-trace。 當您要啟用預期有長引數的提供者,或是要使用會刪除字元的殼層環境時,這會很有幫助。

舉例來說,每當您要追蹤以下提供者時,鍵入其名稱可能會很麻煩:

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

另請參閱