Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenTelemetryにおけるGoのゼロコード・コンパイル時計装について #fukuokago

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for quiver quiver
July 21, 2026

OpenTelemetryにおけるGoのゼロコード・コンパイル時計装について #fukuokago

「Fukuoka.go#23 - connpass」登壇資料

https://fukuokago.connpass.com/event/397937/

解説ブログ

GoのOpenTelemetryゼロコード計装、コンパイル時方式が安定版(v1)になったので動かしてみた #fukuokago
https://zenn.dev/quiver/articles/d7bdf991d562e5

Avatar for quiver

quiver

July 21, 2026

More Decks by quiver

Other Decks in Technology

Transcript

  1. Goとゼロコード 対応済みのJava / Python / Node.js / .NET 等はランタイム型 起動時にエージェントをアタッチして計装できる

    Goは静的リンクされたシングルバイナリ 起動時に割り込むランタイムフックがない コンパイル時に割り込む 8
  2. ビルドコマンドの頭に otelc を付けるだけ otelcのインストール go install go.opentelemetry.io/otelc/tool/cmd/otelc@latest ビルド otelc go

    build -o myapp main.go 内部的には以下と同等 otelc setup go build -toolexec=otelc toolexec ... 9
  3. otelcは -toolexec でビルドに割り込む でコンパイルをインターセプト 対象関数にトランポリン呼び出し(軽量なフックポイント)を注入 go:linkname でフックと計装コードを自動生成・リンク -toolexec This approach

    provides dynamic instrumentation without runtime overhead or invasive code modifications. https://github.com/open-telemetry/opentelemetry-go-compileinstrumentation/blob/main/docs/getting-started.md#how-it-works 10
  4. 何が注入されたかは確認できる $ ls -1F .otelc-build/debug/main/ go.mod otel.instrumentation.go # otelc.init_otelsdk.go #

    SDK otelc.runtime.go # 適用された計装の一覧 初期化コード(注入) 計装パッケージのインポート(注入) 11
  5. otelc.init_otelsdk.go: SDK初期化のinit()を注入 main パッケージに直接注入 package main import "go.opentelemetry.io/otelc/pkg/runtime" func init()

    { runtime.SetupOTelSDK() // TracerProvider / MeterProvider runtime.StartRuntimeMetrics() // } ランタイムメトリクスの収集を開始 を初期化 12
  6. otelc.runtime.go: 計装パッケージをブランクインポート はリンク時に対象シンボルがバイナリ内にないと解決できない 計装パッケージはユーザーコードから import されず、そのままではバイナリに入らな い ブランクインポート( import _

    ) で計装パッケージをビルドに組み込み、フック実装を リンク可能にする go:linkname import _ "go.opentelemetry.io/otelc/instrumentation/google.golang.org/grpc/server" import _ "go.opentelemetry.io/otelc/instrumentation/log/slog" import _ "go.opentelemetry.io/otelc/instrumentation/net/http/server" ... 13
  7. 起動すると自動計装されたログが流れる $ ./myapp {"time":"2026-07-20T14:48:38.603039+09:00","level":"INFO", "msg":"trace provider initialized with auto-export"} {"time":"2026-07-20T14:48:38.603241+09:00","level":"INFO",

    "msg":"meter provider initialized with auto-export"} {"time":"2026-07-20T14:48:38.603645+09:00","level":"INFO", "msg":"logger provider initialized with auto-export"} {"time":"2026-07-20T14:48:38.603664+09:00","level":"INFO", "msg":"OpenTelemetry initialized", "instrumentation_name":"go.opentelemetry.io/otelc", "instrumentation_version":"dev"} {"time":"2026-07-20T14:48:38.603931+09:00","level":"INFO", "msg":"runtime metrics enabled"} 2026/07/20 14:48:38 INFO gRPC server listening on :50051 15
  8. 要検証:動作確認で気になったこと net/http : トレースは出るがメトリクスは送信されない? instrumentation/net/http/semconv/server.go に RecordMetrics() は実 装されている 実行時のフック

    ( net/http/server/server_hook.go 、 .../client/client_hook.go )はス パンの生成のみ? ログはtrace_idの相関付けにとどまる? slog計装は slog.Record に trace_id / span_id を付与するだけ ログ本体をOTel LoggerProviderへ渡す処理がない slog のデフォルトロガーを差し替え ( slog.SetDefault(otelslog.NewLogger("myapp-grpc")) )が必要? 16