OpenTelemetry 向けマネージドサービスは、アプリケーションがバックエンドにトレースデータをレポートした後にのみ、分散トレースを表示します。このガイドでは、OpenTelemetry SDK for Go を使用して Go アプリケーションのイベントトラッキングを行い、OpenTelemetry Protocol (OTLP) を使用して gRPC または HTTP 経由でトレースデータを送信する方法について説明します。
前提条件
OpenTelemetry のエンドポイントを取得するには、次の手順を実行します。
OpenTelemetry 向けマネージドサービスコンソールにログインします。
左側のナビゲーションウィンドウで、[クラスター設定] をクリックします。次に、[アクセスポイント情報] タブをクリックします。
上部のナビゲーションバーでリージョンを選択します。[クラスター情報] セクションで、[トークンを表示] をオンにします。
[クライアント] セクションで、[OpenTelemetry] をクリックします。
下部にあるテーブルの [関連情報] 列で OpenTelemetry のエンドポイントを取得します。

アプリケーションが Alibaba Cloud の本番環境にデプロイされている場合は、Virtual Private Cloud (VPC) エンドポイントを使用してください。それ以外の場合は、パブリックエンドポイントを使用してください。
gRPC と HTTP: トランスポートの選択
gRPC と HTTP はどちらも OTLP を使用してトレースデータを配信します。SDK の初期化とイベントトラッキングのロジックはほぼ同じで、エクスポーターパッケージとクライアント設定のみが異なります。
| 項目 | gRPC | HTTP |
|---|---|---|
| インポートパッケージ | otlptracegrpc | otlptracehttp |
| エンドポイントのフォーマット | host:port (単一の値) | 個別の Endpoint (host:port) と URLPath |
| 認証 | Authentication トークンを含む WithHeaders マップ | URL パスに埋め込み |
| 一般的なユースケース | 低レイテンシー、高スループットの環境 | gRPC がブロックされている、または利用できない環境 |
どちらのトランスポートでも、2 つの送信パスが利用可能です。
| パス | 使用する状況 |
|---|---|
| SDK による直接送信 | アプリケーションから OpenTelemetry 向けマネージドサービスに直接トレースデータを送信します。「前提条件」セクションのエンドポイントと認証トークンが必要です。 |
| OpenTelemetry Collector による転送 | 自己管理の OpenTelemetry Collector を介してトレースデータをルーティングします。エンドポイントをオンプレミスサービスの IP アドレスに置き換え、認証ヘッダーを削除します。 |
サンプルコード
完全な実用例については、「oltp-exporter」をご参照ください。
gRPC 経由でのデータ送信
ステップ 1: 依存関係のインストール
go get go.opentelemetry.io/otel \
go.opentelemetry.io/otel/trace \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpcステップ 2: OpenTelemetry SDK の初期化
initProvider 関数は、OTLP gRPC エクスポーターを設定し、リソース属性をセットアップし、グローバルな TracerProvider を登録します。
otelAgentAddr と xtraceToken を、「前提条件」セクションで取得したエンドポイントと認証トークンに置き換えてください。
OpenTelemetry Collector を介してデータを転送する場合は、otelAgentAddr をオンプレミスサービスの IP アドレスに置き換え、headers マップを削除してください。
func initProvider() func() {
ctx := context.Background()
otelAgentAddr, xtraceToken, ok := common.ObtainXTraceInfo()
if !ok {
log.Fatalf("Cannot init OpenTelemetry, exit")
os.Exit(-1)
}
// OpenTelemetry 向けマネージドサービスの認証ヘッダーを設定します。
headers := map[string]string{"Authentication": xtraceToken}
traceClient := otlptracegrpc.NewClient(
otlptracegrpc.WithInsecure(),
otlptracegrpc.WithEndpoint(otelAgentAddr),
otlptracegrpc.WithHeaders(headers),
otlptracegrpc.WithDialOption(grpc.WithBlock()))
log.Println("start to connect to server")
traceExp, err := otlptrace.New(ctx, traceClient)
handleErr(err, "Failed to create the collector trace exporter")
res, err := resource.New(ctx,
resource.WithFromEnv(),
resource.WithProcess(),
resource.WithTelemetrySDK(),
resource.WithHost(),
resource.WithAttributes(
// OpenTelemetry 向けマネージドサービスコンソールに表示されるサービス名を設定します。
semconv.ServiceNameKey.String(common.ServerServiceName),
semconv.HostNameKey.String(common.ServerServiceHostName),
),
)
handleErr(err, "failed to create resource")
bsp := sdktrace.NewBatchSpanProcessor(traceExp)
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithResource(res),
sdktrace.WithSpanProcessor(bsp),
)
// グローバルプロパゲーターを tracecontext に設定します。デフォルトでは、グローバルプロパゲーターは指定されていません。
otel.SetTextMapPropagator(propagation.TraceContext{})
otel.SetTracerProvider(tracerProvider)
return func() {
cxt, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
if err := traceExp.Shutdown(cxt); err != nil {
otel.Handle(err)
}
}
}主な設定パラメーター:
| パラメーター | 説明 |
|---|---|
otelAgentAddr | コンソールから取得した gRPC エンドポイント |
xtraceToken | コンソールから取得した認証トークン |
Authentication | OpenTelemetry 向けマネージドサービスの認証に必要なヘッダーキー |
semconv.ServiceNameKey | コンソールに表示されるサービス名 |
ステップ 3: アプリケーションのイベントトラッキング
OpenTelemetry のイベントトラッキングでラップされた HTTP ハンドラを作成します。otelhttp.NewHandler ラッパーは、受信 HTTP リクエストに対して自動的にスパンを作成します。
shutdown := initProvider()
defer shutdown()
serverAttribute := attribute.String("server-attribute", "foo")
fmt.Println("start to gen chars for trace data")
initTraceDemoData()
fmt.Println("gen trace data done")
tracer := otel.Tracer(common.TraceInstrumentationName)
// HTTP ハンドラを OpenTelemetry のイベントトラッキングでラップします。
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// 遅延をシミュレートします。
var sleep int64
switch modulus := time.Now().Unix() % 5; modulus {
case 0:
sleep = rng.Int63n(2000)
case 1:
sleep = rng.Int63n(15)
case 2:
sleep = rng.Int63n(917)
case 3:
sleep = rng.Int63n(87)
case 4:
sleep = rng.Int63n(1173)
}
ctx := req.Context()
span := trace.SpanFromContext(ctx)
span.SetAttributes(serverAttribute)
actionChild(tracer, ctx, sleep)
w.Write([]byte("Hello World"))
})
wrappedHandler := otelhttp.NewHandler(handler, "/hello")
http.Handle("/hello", wrappedHandler)
http.ListenAndServe(":7080", nil)ステップ 4: 実行と検証
アプリケーションを起動します。
go run main.goOpenTelemetry 向けマネージドサービスコンソールの [アプリケーション] ページで、アプリケーション名をクリックします。表示されたページで、トレースデータを確認します。
HTTP 経由でのデータ送信
ステップ 1: 依存関係のインストール
go get go.opentelemetry.io/otel \
go.opentelemetry.io/otel/trace \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpgRPC の依存関係との唯一の違いは、otlptracegrpc の代わりに otlptracehttp を使用する点です。
ステップ 2: OpenTelemetry SDK の初期化
Endpoint と URLPath を、「前提条件」セクションで取得したエンドポイントの値に置き換えてください。
OpenTelemetry Collector を介してデータを転送する場合は、Endpoint をオンプレミスサービスの IP アドレスに置き換え、認証ヘッダーを削除してください。
func initProvider() func() {
ctx := context.Background()
traceClientHttp := otlptracehttp.NewClient(
otlptracehttp.WithEndpoint("127.0.XX.XX:8080"), // ご利用のエンドポイントのホストとポートに置き換えてください。
otlptracehttp.WithURLPath("/adapt_xxxxx/api/otlp/traces"), // ご利用のエンドポイントの URL パスに置き換えてください。
otlptracehttp.WithInsecure())
otlptracehttp.WithCompression(1)
traceExp, err := otlptrace.New(ctx, traceClientHttp)
handleErr(err, "Failed to create the collector trace exporter")
res, err := resource.New(ctx,
resource.WithFromEnv(),
resource.WithProcess(),
resource.WithTelemetrySDK(),
resource.WithHost(),
resource.WithAttributes(
// OpenTelemetry 向けマネージドサービスコンソールに表示されるサービス名を設定します。
semconv.ServiceNameKey.String(common.ClientServiceName),
semconv.HostNameKey.String(common.ClientServiceHostName),
),
)
handleErr(err, "failed to create resource")
bsp := sdktrace.NewBatchSpanProcessor(traceExp)
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithResource(res),
sdktrace.WithSpanProcessor(bsp),
)
// グローバルプロパゲーターを tracecontext に設定します。デフォルトでは、グローバルプロパゲーターは指定されていません。
otel.SetTextMapPropagator(propagation.TraceContext{})
otel.SetTracerProvider(tracerProvider)
log.Println("OTEL init success")
return func() {
cxt, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
if err := traceExp.Shutdown(cxt); err != nil {
otel.Handle(err)
}
}
}ステップ 3: アプリケーションのイベントトラッキング
この例では、HTTP ハンドラをラップする代わりに、ループ内で手動でスパンを作成します。各反復処理では、ExecuteRequest という名前のスパンを開始し、makeRequest を呼び出し、サービス境界を越えて伝播するバゲージメンバーをアタッチします。
tracer := otel.Tracer(common.TraceInstrumentationName)
method, _ := baggage.NewMember("method", "repl")
client, _ := baggage.NewMember("client", "cli")
bag, _ := baggage.New(method, client)
defaultCtx := baggage.ContextWithBaggage(context.Background(), bag)
for {
ctx, span := tracer.Start(defaultCtx, "ExecuteRequest")
makeRequest(ctx)
span.End()
time.Sleep(time.Duration(1) * time.Second)
}ステップ 4: 実行と検証
アプリケーションを起動します。
go run main.goOpenTelemetry 向けマネージドサービスコンソールの [アプリケーション] ページで、アプリケーション名をクリックします。表示されたページで、トレースデータを確認します。
一般的なフレームワークの自動インストルメンテーション
OpenTelemetry は、半自動のイベントトラッキングプラグインを提供しています。手動でスパンを作成する必要はありません。コード内でこれらのプラグインが提供する API オペレーションを呼び出すだけで、一般的なフレームワークに対してスパンが自動的に作成されます。サポートされているフレームワークの詳細については、「OpenTelemetry Registry」をご参照ください。
次のステップ
OpenTelemetry Go インストルメンテーションライブラリ - 一般的なフレームワーク向けの自動インストルメンテーション
OpenTelemetry SDK for Go -- SDK のソースコードとサンプル
OpenTelemetry Go documentation -- 詳細設定オプション