Goのコンパイル時計装(compile-time instrumentation)

OpenTelemetryが2026年に発表した、Goアプリケーションをソースコード変更なしでトレーシング計装する仕組み。AlibabaとDatadogの協力で開発され、v1.0がリリースされた。

背景

Goのプログラムは単一の静的バイナリにコンパイルされる。Javaのように起動時にランタイムエージェントを注入して計装する手法が使えないため、これまでGoの自動計装は主に以下のいずれかだった。

  • ソースコードを手動で書き換えてSDKを呼び出す(手動計装)
  • eBPFでプロセス外からフックする(eBPFベースの計装。バイナリの再ビルドが不要な代わり、プロセス外からの観測になる)

Go compile-time instrumentationはこれらとは別の第三の道として、ビルド時にGoツールチェーンへ介入し、コンパイル中に計装コードを直接注入するアプローチを取る。

仕組み

otelcというCLIツールが標準のGoツールチェーンをラップする。

otelc go build ./...

のようにgo buildの前にotelcを挟むだけで、net/httpdatabase/sql・gRPC・Redisなど対応ライブラリの呼び出し箇所にテレメトリ送出コードがビルド時に埋め込まれる。ランタイムオーバーヘッドがないのが特徴(実行時にフックを行うeBPF計装や、リフレクション・プロキシを使う手法と対照的)。

取得できるメトリクス

生成されるメトリクスはOpenTelemetryのセマンティック規約に準拠する。対応ライブラリごとに主に以下のようなものが取れる。

HTTP(net/http)

  • http.server.request.duration(Histogram, 秒) — サーバー側のリクエスト処理時間
  • http.server.active_requests(UpDownCounter) — 処理中リクエスト数
  • http.client.request.duration(Histogram, 秒) — クライアント側のリクエスト時間
  • (opt-in) リクエスト/レスポンスのボディサイズ、コネクション数など

gRPC

  • rpc.server.duration / rpc.client.duration系 — リクエスト処理時間
  • メッセージサイズ、RPCあたりのメッセージ数

database/sql・Redis

  • クエリ/コマンド実行時間のduration系メトリクス(db.client.operation.duration系のセマンティック規約準拠)

Goランタイム

  • go.goroutine.count — ゴルーチン数
  • go.memory.used / go.memory.allocated — メモリ使用量・割り当て量
  • go.memory.gc.cycles / go.memory.gc.pause.duration — GCサイクル数・stop-the-worldの一時停止時間
  • go.processor.limitgo.schedule.duration など

「リクエスト処理時間(duration histogram)」+「今アクティブな数(UpDownCounter)」という定番の形が中心。GitHub上の各instrumentation/<pkg>ディレクトリの実装は発展途上で、メトリクス名の一覧表を網羅したドキュメントは2026年8月時点ではまだあまり整備されていない。

制限事項

v1では「中核的な計装」に対応範囲を絞っており、Goエコシステム全体をカバーしているわけではない。未対応ライブラリはルールの追加、または手動計装との併用で補う必要がある。

出典

#opentelemetry #golang #observability

作成日時: 2026-08-15 20:55 / 更新日時: 2026-08-15 21:17