LoginSignup
0

More than 1 year has passed since last update.

dotnet-traceがどのようにして起動時からの監視を可能にしているか

Last updated at Posted at 2020-12-26

はじめに

dotnet-traceは、v5.0.160202から起動時からトレースログの収集を行えるようになった。
この記事では、どのようにその機能を実現しているかということを解説したいと思う。

dotnet-traceとは

詳しくは dotnet/diagnosticsのドキュメントを参照 してほしいが、要はEventSourceの情報を外部から収集するためのツールで、EventPipeの仕組みを使用している

dotnet-traceはv5.0.152202までは、起動中のプロセスから選択して収集するという方法しか取れなかった。
というのも、使用しているIPCプロトコルの都合上、PIDが接続時に必要で、これはどうしても起動しないとわからなかったからである。
そこで、Diagnostic Portsという概念を導入して、起動時からの監視をできるようにしたというわけである。

Diagnostic Portsとは

Diagnostic IPC Protocolは、PIDを含んだ名前付きパイプ、あるいはunixドメインソケットで通信を行うが、前述したように、
デフォルトで使用されるポートはランタイム側でPIDを含めた形で作成される。
しかし、一部のシナリオではこの仕組みは不都合な点があったため、追加で以下のような動作をランタイム側に追加した。

  1. 環境変数にDOTNET_DiagnosticPortsがあるか見る
  2. もしあれば、スタートアップで動作を停止し、その名前のパイプが作成されるまで待つ
  3. 誰かが指定した名前のパイプを作成して、ランタイムが接続に成功したら、そこにAdvertiseメッセージを送る
  4. 以後はその確立した接続を使用して通常のEventPipeのやり取りを行う

図にすると以下のような感じ
diagnosticports-seq.png

図中にあるAdvertiseメッセージは以下のようなフォーマット

オフセット サイズ 名前 概要
0 8 magic 固定データ(ADVR_V1\0)
8 16 runtimeCookie IPC ProtocolのProcessInfoのruntimeCookieと同じGUID(同一PIDで異なるプロセスの割り込みを防ぐため?)
24 8 PID プロセスID(リトルエンディアン)
32 2 reserved 将来のための予約領域(現在は常に0)

ProcessInfoに関しては、dotnet/diagnosticsのIPCプロトコルドキュメントを参考に

注意点

上記手順は現在のクライアントライブラリ(Microsoft.Diagnostics.NETCore.Client)では素直に実現はできない
なぜならば、
1. 図中で必要なResumeRuntimeメッセージを送るためのAPIがinternal
* ソースは https://github.com/dotnet/diagnostics/blob/5734230e3ee516339a4b0e4729def135027aa255/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/DiagnosticsClient.cs#L155
2. Collector側のパイプを待ち受ける処理もinternal
* ソースは https://github.com/dotnet/diagnostics/tree/v5.0.160202/src/Microsoft.Diagnostics.NETCore.Client/ReversedServer の辺り

dotnet-traceでこの辺りの処理ができているのは、クライアントライブラリでInternalsVisibleToされているからである。

1に関しては、一応パイプ待ち受け処理の中で手動でResumeRuntimeメッセージを送るという回避方法はある。
2に関してはAdvertiseメッセージにPIDが入っているため、これさえ取得できれば後はDiagnosticClientに渡せば通信可能。
この辺りがinternalな理由は、やはり一度publicにすると仕様変更が難しいためではないかと思う。
一応、dotnet-6.0のタイミングで対応を検討している模様なので、将来的には実装されるかもしれない。

終わりに

dotnet-traceで、起動時からEventSourceのログが取得できるようになったのは嬉しいことではある。
クライアントライブラリの方でもこの辺りの処理ができれば、夢が広がるというものである。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0