dotnet-trace 診断ツールは、.NETアプリの「なぜ遅いのか」「どの処理に時間がかかっているのか」を、実行中のプロセスからトレースとして収集するための .NET CLI ツールです。結論から言うと、通常の dotnet-trace collect を使っている開発者は大きな移行作業を急ぐ必要はありません。一方で、Linux本番環境でネイティブフレームやカーネルイベントまで含めて分析したい管理者、cpu-sampling プロファイルを使っていたチーム、.NET 11以降でサンプリング間隔を調整したいチームは、設定と運用手順を見直す価値があります。
2026年5月時点で特に確認したいのは、EventPipe のスレッド時間サンプリング間隔を制御する DOTNET_EventPipeThreadSamplingRate、Linux専用の collect-linux、既存の cpu-sampling プロファイル運用、そしてトレース収集時の権限・バッファー・出力ファイル管理です。dotnet-trace は EventPipe を基盤にしており、ネイティブプロファイラーなしで実行中プロセスの .NET トレースを収集できます。Microsoft Learn では、対象が dotnet-trace 9.0.661903 以降とされ、グローバルツールまたはプラットフォーム別の直接ダウンロードで導入できると説明されています。(Microsoft Learn)
dotnet-trace 診断ツールは何をするものか
dotnet-trace 診断ツールは、.NETアプリケーションの実行時イベントを .nettrace 形式などで収集し、CPUホットスポット、GC、JIT、例外、スレッド、データベースコマンドなどの挙動を後から分析するためのツールです。標準的な collect はWindows、Linux、macOSなどで一貫した使い方ができ、Linux専用の collect-linux はOS固有の機能を使って、より広い範囲のイベントを扱えます。(Microsoft Learn)
実務では、次のような場面で役立ちます。
| 利用シーン | dotnet-traceで確認したいこと | 使い始めの判断基準 |
|---|---|---|
| Web APIのレスポンスが遅い | どのメソッドが長くスタック上にいるか | CPU使用率が高い、または一部リクエストだけ遅い |
| GCが多い気がする | GCイベント、割り当て傾向 | メモリ使用量が増え続ける、停止時間が気になる |
| 起動が遅い | 起動直後のJIT、Assembly Loader、例外 | アプリ開始直後に問題が出る |
| Linux本番でCPU原因を切り分けたい | マネージドコード、ネイティブフレーム、カーネルイベント | .NET 10以降、root権限、Linux要件を満たせる |
| DBアクセスが重い | ADO.NET / Entity Framework のコマンド | クエリ実行やDB待ちが疑わしい |
dotnet-trace は「常時監視ツール」ではなく、問題が起きたとき、または再現テスト時に短時間トレースを取る診断ツールとして使うのが基本です。dotnet-counters でCPUやGCなどの傾向を見てから、原因を深掘りする段階で dotnet-trace を使うと、無駄なトレース取得を避けやすくなります。
2026年5月時点で確認すべき主な変更点
DOTNET_EventPipeThreadSamplingRateでサンプリング間隔を調整できる
今回の関連公式情報で実務上大きいのは、dotnet-sampled-thread-time のサンプリングレートに関する説明です。dotnet-trace のページでは、dotnet-sampled-thread-time のサンプリングレートは DOTNET_EventPipeThreadSamplingRate 環境変数で変更でき、この設定はプロセス全体に影響し、すべてのEventPipeセッションに影響すると説明されています。(Microsoft Learn)
EventPipeの公式ページでは、DOTNET_EventPipeThreadSamplingRate は .NET 11以降で利用可能で、ミリ秒単位のサンプリング間隔を設定すると説明されています。未指定または 0 の場合はランタイムの既定値である10ms、つまり約100Hzが使われます。値を大きくするとサンプリングのオーバーヘッドは下がりますが、トレースの解像度も下がります。(Microsoft Learn)
この設定で注意すべき点は、dotnet-traceのコマンド単位ではなく、対象プロセス側の環境変数として効くことです。たとえば、コンテナーやsystemdサービスで設定している場合、そのプロセスの存続中に取得されるオンデマンドトレース全体に影響します。
# 例: サンプリング間隔を20msにする
export DOTNET_EventPipeThreadSamplingRate=20
dotnet myapp.dll
20msにするとサンプル数は減るため、短時間のCPUスパイクは見逃しやすくなります。逆に、既定値より細かくしようとすると、トレース量やオーバーヘッドが増える可能性があります。まずは既定値で取得し、トレースサイズや負荷が問題になった場合だけ調整するのが安全です。
collect-linuxはLinux本番分析の選択肢になるが、まだプレビュー扱い
collect-linux は、Linuxの perf_events などを使って診断トレースを収集するLinux専用の機能です。通常の collect と比べて、マシン全体の同時トレース、ネイティブライブラリやカーネルイベントの取得、ネイティブフレームを含むコールスタックの取得に対応します。一方で、Linuxカーネル6.4以上、CONFIG_USER_EVENTS=y、tracefs、root権限、.NET 10以上などの前提条件があります。(Microsoft Learn)
特に重要なのは、collect-linux がプレビュー機能であり、更新された .nettrace ファイル形式に依存する点です。公式情報では、最新のPerfViewは対応する一方、convert や report など他の使い方はまだ動作しない可能性があるとされています。(Microsoft Learn)
つまり、collect-linux は「すぐ全環境で標準化する機能」ではなく、Linux本番でネイティブ側やカーネル側まで含めた分析が必要なときに、検証済みの環境から段階的に使う機能です。
collectのcpu-samplingプロファイルは使い方を見直す
過去の dotnet-trace collect には cpu-sampling というプロファイルがありましたが、公式ドキュメントでは、この名前は誤解を招くため削除されたと説明されています。通常の collect で近い結果を得るには、--profile dotnet-sampled-thread-time,dotnet-common を使う案が示されています。以前の cpu-sampling の挙動に厳密に合わせたい場合のプロバイダー指定も公式に記載されています。(Microsoft Learn)
既存の手順書やCIジョブ、障害対応Runbookに次のようなコマンドが残っている場合は見直してください。
# 見直し対象になりやすい古い例
dotnet-trace collect --profile cpu-sampling --process-id <PID>
通常の collect では、次のように置き換えるのが現実的です。
dotnet-trace collect \
--profile dotnet-sampled-thread-time,dotnet-common \
--process-id <PID>
一方で、collect-linux には cpu-sampling プロファイルがあります。これは通常の collect から削除された旧プロファイルと同じ意味で捉えず、LinuxカーネルCPUサンプリングを使う別物として扱うべきです。collect-linux では、プロファイルを指定しない場合に dotnet-common と cpu-sampling が既定で有効になります。(Microsoft Learn)
影響を受ける管理者・開発者
| 対象者 | 影響度 | 確認すべきこと |
|---|---|---|
通常の dotnet-trace collect --process-id を使う開発者 | 低〜中 | 既定プロファイル、出力ファイル、バッファー設定を確認 |
古い cpu-sampling 手順を持つチーム | 高 | dotnet-sampled-thread-time,dotnet-common への置き換え |
| .NET 11以降を評価・導入するチーム | 中 | DOTNET_EventPipeThreadSamplingRate を設定していないか、既定値で十分か |
| Linux本番環境の管理者 | 高 | collect-linux のカーネル、glibc、root権限、tracefs、.NET 10以上の要件 |
| コンテナー運用チーム | 中〜高 | 診断ポート、プロセス名前空間、権限、出力先ボリューム |
| セキュリティ・運用監査担当 | 中 | トレースファイルにSQL、接続情報、パス、コマンドライン引数が含まれないか |
最も注意が必要なのは、Linux本番環境で「より詳しく取れるなら collect-linux に切り替えよう」と短絡的に判断するケースです。collect-linux はroot権限または CAP_PERFMON / CAP_SYS_ADMIN が必要で、通常の collect よりも権限面・運用面の確認事項が増えます。(Microsoft Learn)
インストールと更新で確認すること
dotnet-trace は、.NETグローバルツールとしてインストールする方法と、プラットフォーム別の実行ファイルを直接ダウンロードする方法があります。グローバルツールとして導入する場合の基本コマンドは次のとおりです。(Microsoft Learn)
dotnet tool install --global dotnet-trace
すでにグローバルツールとして入っている環境では、更新時に次のコマンドを使います。dotnet tool update は指定した .NET ツールを最新の安定版に更新するコマンドで、グローバルツール、指定パスのツール、ローカルツールの更新に対応しています。(Microsoft Learn)
dotnet tool update --global dotnet-trace
更新後は、必ずバージョンを確認します。
dotnet-trace --version
チームで同じ診断手順を再現したい場合は、「常に最新版」ではなく、検証済みバージョンを明記する運用も検討してください。障害対応時にツールの挙動が変わると、前回のトレースと比較しづらくなるためです。
基本的な使い方
実行中プロセスをトレースする
まず対象プロセスを探します。
dotnet-trace ps
dotnet-trace ps はトレース可能なdotnetプロセスを一覧表示します。dotnet-trace 6.0.320703以降では、利用可能な場合に各プロセスのコマンドライン引数も表示されます。64ビットプロセスの情報を十分に取得するには、64ビット版のdotnet-traceを使う必要があります。(Microsoft Learn)
PIDが分かったら、短い時間に区切って取得します。
dotnet-trace collect \
--process-id <PID> \
--duration 00:00:00:30 \
--output traces/app_30s.nettrace
--duration は dd:hh:mm:ss 形式で指定します。無指定で長時間取り続けると、ファイルサイズが膨らみ、トレースの読み込みや共有が難しくなります。まず30秒〜2分程度で試し、問題が再現しない場合に時間を延ばすのが実務的です。
起動直後の問題をトレースする
起動時のJIT、アセンブリ読み込み、初期化処理が問題の場合は、collect の後に -- を付けて対象コマンドを起動します。これは .NET 5以降の対象アプリで利用でき、プロセス開始直後からトレースできます。(Microsoft Learn)
dotnet-trace collect -- dotnet exec ./MyApp.dll
ここで失敗しやすいのは、dotnet run をそのまま使うケースです。公式ドキュメントでは、dotnet run は複数の子プロセスを生成する可能性があり、アプリ本体ではないプロセスが先に dotnet-trace に接続してしまう問題があるため、自己完結型アプリや dotnet exec <app.dll> の利用が推奨されています。(Microsoft Learn)
コンテナーや起動前プロセスには診断ポートを使う
対象プロセスが将来起動する場合や、コンテナー内など現在のプロセス名前空間に含まれないプロセスと通信する場合は、--diagnostic-port の明示が必要になることがあります。診断ポートはOSによって形式が異なり、Linux/macOSではUnixドメインソケット、Windowsでは名前付きパイプ、AndroidやiOSなどではIP:port形式が使われます。(Microsoft Learn)
dotnet-trace collect --diagnostic-port /tmp/myapp-trace.sock
別ターミナルやコンテナー起動設定側で、対象アプリに同じ診断ポートを渡します。
export DOTNET_DiagnosticPorts=/tmp/myapp-trace.sock
dotnet exec ./MyApp.dll
本番コンテナーで使う場合は、ソケットの配置先、権限、ボリューム、トレースファイルの書き込み先を事前に決めておく必要があります。障害発生後に場当たり的に設定すると、コンテナー再起動で情報が失われたり、権限不足で接続できなかったりします。
管理者が確認すべき設定・運用上の注意点
権限は通常のcollectとcollect-linuxで違う
通常の dotnet-trace collect では、対象プロセスを起動したユーザーと同じユーザー、またはrootで実行する必要があります。そうでない場合、対象プロセスへの接続に失敗します。(Microsoft Learn)
# 同じユーザーで実行する例
dotnet-trace collect --process-id <PID>
collect-linux はさらに厳しく、root権限または CAP_PERFMON / CAP_SYS_ADMIN が必要です。Linuxの本番環境では、診断時だけ昇格できる手順、取得できる担当者、トレースファイルの保管場所をあらかじめRunbook化しておくべきです。(Microsoft Learn)
Linux/macOSではTMPDIRの違いでタイムアウトすることがある
LinuxとmacOSでは、--name や --process-id を使う場合、対象アプリとdotnet-traceが同じ TMPDIR 環境変数を共有している必要があります。違っているとコマンドがタイムアウトする可能性があります。(Microsoft Learn)
systemd、Docker、Kubernetes、CI環境では、手元のシェルと対象プロセスで環境変数が違うことがよくあります。接続できない場合は、PIDの誤りだけでなく、ユーザー、TMPDIR、プロセス名前空間、コンテナー境界を確認してください。
バッファー不足は「取れているように見えて欠ける」原因になる
--buffersize の既定値は256MBです。対象プロセスがディスク書き込みより速くイベントを生成すると、バッファーがオーバーフローし、一部イベントが失われる可能性があります。公式ドキュメントでは、バッファーサイズを増やすか、記録するイベント数を減らすことで軽減できると説明されています。(Microsoft Learn)
dotnet-trace collect \
--process-id <PID> \
--buffersize 512 \
--duration 00:00:01:00 \
--output traces/highload.nettrace
ただし、バッファーを大きくすればよいわけではありません。高負荷時に詳細プロバイダーを増やしすぎると、トレース取得自体がアプリに影響します。まずは既定プロファイルで短時間取得し、必要なイベントだけを追加するのが基本です。
トレースファイルには機密情報が含まれる可能性がある
dotnet-trace の database プロファイルは、ADO.NETやEntity Frameworkのデータベースコマンドをキャプチャします。(Microsoft Learn) また、公式ドキュメントの .rsp ファイル例にも、SQL関連の診断ソースでコマンドテキストや接続情報に関わる項目を扱う例が示されています。(Microsoft Learn)
そのため、トレースファイルは単なるログファイルではなく、機密データを含み得る診断成果物として扱ってください。最低限、次を決めておきます。
- 本番トレースを取得できる担当者
- 保存先ディレクトリとアクセス権
- 外部共有前のマスキング・レビュー手順
- 保存期間と削除ルール
- チケットやチャットへ添付してよい条件
特に、DBコマンド、接続文字列、ファイルパス、ユーザー識別子が含まれる可能性がある環境では、トレースファイルをそのまま社外に渡さない運用が必要です。
開発者向けの使い分け
まずは既定プロファイルで十分なことが多い
--profile、--providers、--clrevents を指定しない場合、通常の dotnet-trace collect では dotnet-common と dotnet-sampled-thread-time が既定で有効になります。dotnet-common にはGC、AssemblyLoader、Loader、JIT、例外、スレッド、コンパイル関連イベントが含まれ、dotnet-sampled-thread-time は約100Hzで .NET スレッドスタックをサンプリングします。(Microsoft Learn)
最初から詳細な --providers を書くよりも、まず既定で取得し、分析結果を見て足りない情報を追加する方が失敗しにくいです。
dotnet-trace collect --process-id <PID> --duration 00:00:00:30
GCだけを軽く見たいならgc-collect
GCの発生だけを低オーバーヘッドで追いたい場合は、gc-collect を検討します。より詳しい割り当て情報が必要なら gc-verbose ですが、取得量と負荷が増える可能性があるため、再現環境や短時間の本番取得から始めるのが安全です。
dotnet-trace collect \
--process-id <PID> \
--profile gc-collect \
--duration 00:00:01:00
DBの遅さを疑うならdatabaseプロファイルを慎重に使う
ADO.NETやEntity FrameworkのDBコマンドを見たい場合は database プロファイルが候補になります。
dotnet-trace collect \
--process-id <PID> \
--profile database \
--duration 00:00:00:30
ただし、DBコマンドの内容は機密性が高い場合があります。開発環境やステージングで再現できるなら、まず本番以外で取得してください。本番で必要な場合は、取得時間を短くし、ファイルの取り扱いルールを明確にしてから実行します。
Linuxでcollect-linuxを使う前のチェックリスト
collect-linux は強力ですが、導入前の確認が不足すると「本番で実行できない」「取得したが解析できない」「権限が強すぎて監査で止まる」といった問題が起きます。
| 確認項目 | コマンド例・判断基準 | NGの場合の対応 |
|---|---|---|
| .NETバージョン | .NET 10以上の対象プロセスか | 通常の collect を使う |
| Linuxカーネル | uname -r で6.4以上か | 対応カーネルの環境で検証 |
| user_events | zgrep CONFIG_USER_EVENTS /proc/config.gz | カーネル設定を確認 |
| tracefs | /sys/kernel/tracing が使えるか | マウント設定を確認 |
| 権限 | rootまたは必要capabilityがあるか | 診断用の昇格手順を整備 |
| glibc | ldd --version で2.35以上か | 対応ディストリビューションを確認 |
| 対象プロセス対応 | dotnet-trace collect-linux --probe | 非対応なら通常の collect |
collect-linux --probe は、トレースを収集せずに、対象の .NET プロセスが collect-linux に対応しているかを確認できます。probeモード自体はroot権限なしで実行できますが、前提条件の検証までは行わない点に注意が必要です。(Microsoft Learn)
dotnet-trace collect-linux --probe
実際にマシン全体のトレースを取る場合は、次のように実行します。
sudo dotnet-trace collect-linux --duration 00:00:00:30
公式ドキュメントでは、collect-linux の例として、マシン全体のCPUサンプルを取得し、.NET 10以降のプロセスではGC、JIT、アセンブリ読み込みなどの軽量イベントも含める説明があります。複数バージョンの.NETが混在する環境では、probeモードで対応可否を確認するとよいとされています。(Microsoft Learn)
トレースの表示・変換で注意すること
Windowsでは、.nettrace ファイルをVisual StudioやPerfViewで表示できます。Linuxでは、-f|--format を使って speedscope 形式に変換して表示する方法があります。非Windows環境で収集したトレースをWindowsマシンへ移動し、Visual StudioやPerfViewで分析することもできます。(Microsoft Learn)
dotnet-trace collect \
--process-id <PID> \
--format Speedscope \
--duration 00:00:00:30
注意点は、変換後のファイルだけを残さないことです。公式情報では、.nettrace から chromium や speedscope への変換は不可逆で、元の .nettrace ファイルは保持されるため、後で開く予定があるなら削除しないよう説明されています。(Microsoft Learn)
移行・展開時の実務チェックリスト
チームで dotnet-trace の手順を標準化する場合は、次の順番で確認するとスムーズです。
| 手順 | 実施内容 | 失敗しやすいポイント |
|---|---|---|
| 既存手順の棚卸し | Runbook、Wiki、CI、障害対応メモを検索 | cpu-sampling の古い指定が残る |
| ツールバージョン確認 | dotnet-trace --version を記録 | 個人PCと本番踏み台でバージョンが違う |
| 基本コマンド統一 | 既定プロファイル、30秒取得、出力先を決める | 長時間取得で巨大ファイルになる |
| Linux要件確認 | collect-linux --probe とOS要件を確認 | root権限だけ確認してカーネル要件を見落とす |
| セキュリティ確認 | トレースの保存先、共有範囲、削除期限を決める | DBコマンドや接続情報を含む可能性を軽視する |
| 解析ツール確認 | Visual Studio、PerfView、Speedscopeで開けるか確認 | collect-linux のプレビュー形式を既存ツールで処理できない |
| サンプリング設定確認 | .NET 11以降で DOTNET_EventPipeThreadSamplingRate の有無を確認 | 環境変数が全EventPipeセッションに影響する点を忘れる |
特に移行で重要なのは、コマンドそのものより「誰が、どの権限で、どこに、何秒間、どのプロファイルで取得するか」です。dotnet-trace は簡単に実行できますが、取得する情報量と機密性は小さくありません。
よくある失敗と対処法
接続できない
PIDが正しいのに接続できない場合は、まず実行ユーザーを確認します。通常の collect でも、対象プロセスと同じユーザーまたはrootで実行する必要があります。Linux/macOSでは TMPDIR の違いも確認してください。(Microsoft Learn)
トレースを取ったのに肝心なイベントが欠けている
バッファー不足、取得時間の短さ、プロファイル不足が主な原因です。--buffersize を増やす、取得時間を調整する、必要なプロファイルを追加する順に試してください。最初から大量のプロバイダーを有効にすると、逆にオーバーヘッドやイベント欠落を招きます。
起動時トレースで別プロセスを捕まえてしまう
dotnet run 経由で起動すると、アプリ本体以外のプロセスが先に接続されることがあります。起動時トレースでは、自己完結型アプリを直接起動するか、dotnet exec <app.dll> を使う方が安全です。(Microsoft Learn)
collect-linuxの結果を既存の解析フローで処理できない
collect-linux はプレビュー機能であり、更新された .nettrace 形式に依存します。最新PerfViewでは対応すると説明されていますが、convert や report などはまだ動作しない可能性があります。既存の自動解析フローに組み込む前に、実際のトレースファイルで検証してください。(Microsoft Learn)
サンプリングレートを変えた影響範囲を見落とす
DOTNET_EventPipeThreadSamplingRate はプロセス全体に効き、dotnet-traceのオンデマンドトレースを含むすべてのEventPipeセッションに影響します。特定の調査のために設定した値が、別の診断にも影響する可能性があります。設定した場合は、サービス定義、コンテナー定義、CI環境変数、Runbookに明記しておきましょう。(Microsoft Learn)
まず何をすべきか
dotnet-trace 診断ツールを運用に取り入れているチームは、まず次の3つを確認してください。
1つ目は、既存の手順に古い cpu-sampling 指定が残っていないかです。通常の collect では dotnet-sampled-thread-time,dotnet-common への置き換えを検討します。
2つ目は、Linux環境で collect-linux を使う必要が本当にあるかです。ネイティブフレームやカーネルイベントまで必要なら価値がありますが、root権限、カーネル、glibc、.NETバージョン、解析ツール対応を事前に確認してください。
3つ目は、.NET 11以降の環境で DOTNET_EventPipeThreadSamplingRate を設定していないか、設定するなら意図と影響範囲を文書化しているかです。既定の約100Hzで足りる場合は、無理に変更する必要はありません。
dotnet-trace は、問題発生時に「感覚」ではなく「実行時の証拠」で原因を絞り込むための強力なツールです。まずは開発環境やステージングで、30秒程度の基本トレースを取得し、Visual Studio、PerfView、Speedscopeのいずれかで開けるところまでをチームの標準手順にしておくと、本番障害時の初動が大きく速くなります。

コメント