JetBrainsは2026年9月15日、アプリケーションの実行中にマイクロサービス間の実際の関係を描画する機能である、OpenTelemetryプラグインのService Mapがどのように動作するかについて、技術的な解説を公開した。この解説は、Rider ExecutionチームとSoftware Engineering Researchチームの協力によるもので、Nikita DukinとEgor Klimovが執筆した。
この考え方は、よく知られた実際的な問題から出発している。アーキテクチャ図は整然として見えても、数か月前のシステムの状態を反映している可能性があり、新しいサービスや、ドキュメントが更新されていないメッセージキューを示していないことがある。JetBrainsは、静的なコード解析だけでは常に十分とは限らないと考えている。なぜなら、静的解析が説明するのはソースコード上で起こり得ることであり、実行中にサービス間で実際に起きていることではないからだ。
トレースが地図の情報源
このプラグインは、ログ、メトリクス、トレースを収集するOpenTelemetryのデータに依存している。ログが何が起きたかを説明し、メトリクスが現象の規模を示す一方、トレースはシステムを通過するリクエストの経路を明らかにする。各トレースはスパンと呼ばれる作業単位で構成され、OpenTelemetryはHTTP ClientやHTTP Serverのスパンなど、統一されたセマンティック規約を提供している。
このプラグインは、特定のフレームワークや言語にアルゴリズムを結び付けることなく、これらのトレースを使って実行時の構造を把握する。アプリケーションやライブラリがOpenTelemetryの想定に従ってトレースを送信すれば、使用されている技術にかかわらず通信を可視化できる。JetBrainsによれば、同じロジックはJVM、.NET、Python、Goなどのアプリケーションで動作し、IntelliJ IDEA、GoLand、PyCharm、WebStorm、Riderでも利用できる。
開発環境内で地図はどのように構築されるのか
OpenTelemetryプラグインを有効にして開発環境を起動すると、プラグインはテレメトリーデータを受け取る軽量なローカルサーバーを起動する。アプリケーションの実行時、プラグインは標準のOpenTelemetry環境変数を設定し、アプリケーションがトレースをそのローカルサーバーへ送信するようにする。
サーバーは受信したトレースを非同期に処理し、アーキテクチャの内部モデルを構築して継続的に更新する。Service Mapタブを開くと、プラグインは最新の構造モデルを取得し、視覚的な図として表示する。したがって、この地図は手動で作成される固定文書ではなく、システムの実行中に検出された通信から直接得られる結果である。
課題は描画ではなくデータの解釈
トレースはそれぞれ独立して到着し、到着順が保証されていない。子サービスのトレースが親サービスのトレースより先に到着することもある。また、トレースが遅れて到着しないことを保証する最終的な終了時点を、トレース自体は示さない。さらに、OpenTelemetryは各トレースに対して厳密に分離された型を提供しているわけではなく、トレースは処理の意味を表すキーと値のペアのマップを保持している。
そのためJetBrainsは、構造の再構築をデータストリーム処理アルゴリズムとして分類した。プラグインはトレースの完了を待たず、到着するたびに直ちに調べる。http.request.methodやhttp.response.status_codeなどの属性を使って、その処理がHTTP通信かどうかを判定する一方、別の属性はデータベースクエリやメッセージシステムとのやり取りを示す。
トレースを分類した後、アルゴリズムはそれを発行したサービスを特定する。新しいサービスであれば地図に追加し、既存のサービスであれば新しいデータを統合して統計情報を更新する。HTTP通信では、呼び出し側サービスから発行されたCLIENTスパンと、受信側サービスで生成されたSERVERスパンの関係をプラグインが探す。リクエストとともにトレースコンテキストが伝播するため、SERVERスパンはCLIENTスパンの子になる。相手側が存在すれば関係は直ちに描画され、存在しなければ対応するデータが到着するまでスパンをメモリに保持する。
その他の依存関係では異なるルールを使用する。通常、データベース呼び出しは単一のCLIENTスパンで表され、プラグインはそのセマンティック属性に基づいてデータベースノードを推定する。一方、メッセージシステムにはより大きな柔軟性が必要になる。プロデューサーとコンシューマーの関係は、メッセージシステムや使用されているインストルメンテーションの方法に応じて、親子関係またはトレースリンクを通じて現れる可能性がある。
なぜ実際上重要なのか
ここでの基本的な価値は、地図が予想される構造だけでなく、観測された挙動を明らかにすることにある。開発中にシステムが複数のHTTP通信やデータベースへのクエリを示し、想定では通信が1つだけだった場合、その事実をリリース前に発見できる。また、文書化されていなかった依存関係や、時間の経過とともに変化した依存関係を理解する助けにもなる。
ただし、結果の正確さはテレメトリーの品質に左右される。アルゴリズムには、正しいトレース、サービス間でのトレースコンテキストの伝播、想定されたセマンティック属性の使用が必要である。そのため、プラグインをインストールしただけでService Mapがあらゆるシステムの完全な像を自動的に提供するわけではない。インストルメンテーションツールが送信しないものや、コンテキストなしで到着するものは、推定される関係に表示されない可能性がある。この記事はまた、新たな証拠が到着するにつれてモデルが発展するため、この地図は更新され続ける実行時の表現であり、アーキテクチャ設計に対する最終的な判断ではないことも説明している。