OTelコンパイル時計装、3つ目の計装パラダイムが安定版に

Goで書かれたサービスにOpenTelemetryを組み込む方法が、ここにきて三択になった。手動でSDKを呼び出すか、eBPFでプロセス外から観測するか、そして新たにビルド時にコードへ計装を注入するかだ。OpenTelemetryは分散システムのログ・メトリクス・トレースを収集する業界標準規格で、SREやバックエンドチームの障害調査・性能分析を支えてきた。2026年7月、AlibabaとDatadogが主導する「OpenTelemetry Go Compile-Time Instrumentation」がv1の安定版に到達した[1]。go buildコマンドに-toolexecフラグを渡すだけで、ソースコードを書き換えずに計装済みバイナリが手に入る仕組みだ[2]。Goは単一の静的バイナリにコンパイルされるため、起動時にエージェントを差し込む余地がなく、これまでは手動計装かeBPFの二択しかなかった。第3の選択肢が実用段階に入った今、既存のGoサービスの計装戦略を見直す価値がある。

予備知識

  • OpenTelemetry(OTel): ログ・メトリクス・トレースを統一形式で収集するオブザーバビリティの業界標準規格。特定ベンダーに縛られずに複数の監視基盤へデータを送れる。
  • 計装(インストゥルメンテーション): アプリケーションにトレースやメトリクスを発行する処理を組み込むこと。手動で書く方法と自動生成する方法がある。
  • eBPF: Linuxカーネル内で安全に実行できる小さなプログラムを動的に注入する技術。アプリケーションのプロセス外からシステムコールや関数呼び出しを観測できる。
  • ビルド時 vs 実行時: ビルド時計装はコンパイル段階でコードに計装を焼き込む。実行時計装(エージェント方式)はプロセス起動後に外部から差し込む。

OTelの設計思想と全体像を先に押さえておくと、計装方式の違いが理解しやすくなる一冊。

Goの計装がなぜ二択で止まっていたのか

Goサービスの計装は、長らく手動SDK組み込みかeBPFエージェントの二択だった。

Java・Python・Node.js・.NETはランタイムが起動時にエージェントを差し込める仕組みを持ち、コード変更なしの計装が早くから普及した[1]。Goはコンパイル時に依存関係も含めて一つの静的バイナリに固められるため、起動後に割り込む場所がない[1]。そのため開発チームは自分でOTel SDKの呼び出しをコードに書き足すか、Grafana BeylaやOTel eBPF Instrumentation(OBI)のようにカーネルレベルで外部からトレースを推測するエージェントを使うしかなかった。

手動SDKは狙った箇所を正確に計装できる一方、ライブラリが増えるたびに人手でコードを書き足す必要があり保守負荷が大きい。eBPFはコード変更なしに複数言語のバイナリへ後付けできるが、プロセス外からの推測に頼るぶん取得できる情報の粒度に制約がある。

Goのビルドから実行までの流れと、実行時計装ができない理由を示す図
Goは実行時に計装コードを差し込むランタイムを持たない

計装方式の選択を「監視」ではなく「オブザーバビリティ」の視点で捉え直したいチームに向く。

3つの計装パラダイムを比較する

手動SDK・eBPFゼロコード・ビルド時注入は、計装をどの段階でどこに仕込むかが異なる。

方式導入コスト実行時オーバーヘッド保守性
手動SDK計装高い(呼び出し箇所ごとに手作業でコード追加)計装した範囲のみに限定できるライブラリ更新のたびに追従が必要
eBPFゼロコード低い(既存バイナリに後付け、コード変更なし)常駐エージェントのカーネル観測コストが発生バイナリ非改変で更新は容易だが取得情報の粒度に制約
ビルド時注入低い(ビルドコマンドの差し替えのみ)別プロセスの常駐エージェントは不要依存関係の更新に合わせて再ビルドで計装ルールも更新される

公式ブログは「ゼロランタイムオーバーヘッド」と表現するが、これは別プロセスの常駐エージェントが不要という意味だ[1]。注入されたコード自体はスパン生成・メトリクス記録・コンテキスト伝搬・エクスポートを行うため、そのCPUコストまで消えるわけではない[1]。ここを混同すると、導入後に「オーバーヘッドはゼロのはずなのに負荷が上がった」という誤解を招きやすい。

手動SDK・eBPFゼロコード・ビルド時注入それぞれのデータフローを比較する図
3つの計装パラダイムの処理の流れ
可観測性/障害

Grafana Cloudは、Grafana Labsが提供する監視SaaS(サービスとして提供される監視基盤)である。ログ集約OSSのLoki、メトリクス保存基盤のMimir、アラートルールを評価するルーラー(ruler)など複数[…]

ビルド時計装の仕組み——toolexecとトランポリンコード

ビルド時計装は、Goコンパイラの呼び出しを-toolexecフラグで横取りしてコードを書き換える。

-toolexecはGoツールチェーンが標準で持つフラグで、コンパイラやアセンブラの呼び出しを外部コマンドに差し替えられる[3][4]。プロジェクトが提供するotelcコマンドはこの仕組みを使い、otelc go buildのように既存コマンドをラップするか、GOFLAGSに-toolexec=otelc toolexecを設定して既存のMakefileやCIパイプラインを変更せずに組み込める[3]。利用にはGo 1.25以降が必要になる[2]。

otelcはまず対象モジュールの依存グラフを解析し、net/http・database/sql・gRPC・Redisなど計装ルールが用意されたパッケージを特定する[1][4]。該当パッケージのコンパイル時にAST(抽象構文木)を書き換え、対象関数の入口と出口に「トランポリンコード」と呼ぶ軽量なフック処理を挿入し、go:linknameでOpenTelemetryのSDK呼び出しと結び付ける[4]。生成物は特別なランタイムに依存しない通常のGo実行バイナリで、標準ライブラリや依存先まで計装対象に含められる点が手動SDKとの違いになる[2][4]。

otelcがGoコンパイラ呼び出しを横取りしてトランポリンコードを注入する流れ
-toolexecによるビルド時計装の処理フロー
障害

2026年7月15日(太平洋夏時間、日本時間では16日早朝)、Google Cloud(グーグルが提供するクラウド基盤サービス)のオランダ拠点で電源網の異常が発生し、冷却設備の停止を経て、europe-west4-a(オランダに置かれたア[…]

自社のGoサービスにどの計装方式を選ぶか

3方式は互いに排他ではなく、再ビルドの可否と計装の目的で使い分けるものだ。

OpenTelemetry公式は判断基準を示している。再ビルドが可能で、コード変更なしに依存先や標準ライブラリまで含めた網羅的な計装を求めるならビルド時注入が向く[1]。サードパーティのバイナリなど再ビルドできない対象や、複数言語混在の環境をプロセス外から一括で観測したいならeBPF(OBI)が向く[1]。ビジネス固有のスパンやドメイン知識を反映したメトリクスを狙って仕込みたい場面では、手動計装が他の2方式と組み合わせて使える[1]。

v1が対応するライブラリはnet/http・database/sql・gRPC・Redis・Goランタイムメトリクスなど主要なものに絞られている[1]。自社が使う全ライブラリを即座に網羅できるとは限らないため、導入時はまず自社サービスの依存ライブラリが対応リストに含まれるかを確認し、含まれない箇所は当面手動計装で補う判断になる。

再ビルド可否と保守体制から適した計装方式を選ぶ判断フロー図
計装方式を選ぶための簡易判断フロー
障害

MBAファシリテーション&ネゴシエーション講義ノート Day6/全6回(最終回) この記事でわかること 交渉の障害を3つに分類する視点(論理的構造・認知感情・環境) あるプロスポーツリーグのロックアウト――交渉が決裂に至るメカニズム […]

よくある質問(FAQ)

Q1. ビルド時計装を導入するとビルド時間は延びますか。
otelcはコンパイル対象パッケージのASTを書き換えるため、通常のgo buildよりビルド時間は増える。ただし計装済みビルドと通常ビルドでビルドキャッシュを分離する設計になっており、両者を切り替えても既存のキャッシュを壊さない[3]。

Q2. eBPFによるゼロコード計装と何が違いますか。
eBPFはプロセスの外側からカーネル経由で挙動を観測する方式で、バイナリの再ビルドが不要な代わりに取得できる情報の粒度に制約がある。ビルド時注入はコンパイル時にコード自体へフックを埋め込むため、標準ライブラリや依存先まで含めた詳細なトレースを取得できる[1]。

Q3. 手動SDK計装は不要になりますか。
不要にはならない。ビルド時注入は主要ライブラリの自動計装をカバーするが、ビジネス固有のスパンやドメイン知識を反映したメトリクスは今後も手動計装で書き足す想定になっている[1]。

まとめ

OTelのGoビルド時計装がv1安定版に達したことで、Goサービスの計装は手動SDK・eBPF・ビルド時注入の三択になった。ビルド時注入は常駐エージェントなしでコード変更ゼロという強みがあるが、対応ライブラリの範囲と「ゼロオーバーヘッド」の意味を正確に理解した上で選ぶ必要がある。自社にGoサービスがあるなら、まず依存ライブラリがv1の対応リストに含まれるかを確認したい。含まれる範囲はビルド時注入、独自のビジネスロジックは手動計装、再ビルドできない外部バイナリはeBPFという役割分担で計装戦略を組み直すのが、現実的な出発点になる。

出典

[1] https://opentelemetry.io/blog/2026/go-compile-time-instrumentation-v1/
[2] https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation
[3] https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation/blob/main/docs/getting-started.md
[4] https://www.dash0.com/guides/otelc-opentelemetry-go