Go アプリケーションで分散トレーシングが必要であり、かつスタックで既に Zipkin を使用している場合、トレースデータを OpenTelemetry 向けマネージドサービスに直接レポートできます。統合後、コンソールでアプリケーションのトポロジー、トレース、異常なトランザクションと低速なトランザクション、SQL 分析を表示できます。
より豊富な機能、高度なトレーシング機能、そして優れたエクスペリエンスを得るには、OpenTelemetry プロトコルを使用してアプリケーションを OpenTelemetry 向けマネージドサービスに接続することを推奨します。詳細については、「事前準備」をご参照ください。
ARMS は、商用サポート付きの自己開発エージェントを Go アプリケーション向けに提供しています。このエージェントは、非侵入型のイベントトラッキングを可能にし、より豊富な機能セットと高い安定性を提供します。詳細については、「Go アプリケーションのモニタリング」をご参照ください。
仕組み
Zipkin は Twitter が開発したオープンソースの分散トレーシングシステムで、複数の異種システムからのリアルタイムモニタリングデータを集約します。
ご利用の Go アプリケーションは、Zipkin クライアントライブラリを使用してスパンを作成し、HTTP 経由で OpenTelemetry 向けマネージドサービスのエンドポイントに送信します。
前提条件
開始する前に、以下をご確認ください。
Go 開発環境
OpenTelemetry 向けマネージドサービスコンソールへのアクセス
ご利用のリージョンの Zipkin エンドポイント (「Zipkin エンドポイントの取得」をご参照ください)
Zipkin エンドポイントの取得
OpenTelemetry 向けマネージドサービスコンソールにログインします。
左側のナビゲーションウィンドウで、[クラスター設定] をクリックします。表示されたページで、[アクセスポイント情報] タブをクリックします。
上部のナビゲーションバーでリージョンを選択します。[クラスター情報] セクションで、[トークンの表示] をオンにします。
「クライアント」を Jaeger または Zipkin に設定します。この例では、Jaeger が選択されています。
[関連情報] 列からエンドポイントをコピーします。

アプリケーションが Alibaba Cloud の本番環境で実行されている場合は、VPC エンドポイントを使用してください。それ以外の場合は、パブリックエンドポイントを使用してください。v1 を使用する特別な理由がない限り、v2 エンドポイントを使用してください。
クイックスタート
独自のアプリケーションでイベントトラッキングを行う前に、ビルド済みのデモを実行して、トレースデータが OpenTelemetry 向けマネージドサービスに到達することを確認します。
デモプロジェクトをダウンロードします。
utils.goを開き、<endpoint>を「Zipkin エンドポイントの取得」で取得した Zipkin エンドポイントに置き換えます。依存関係をインストールします。
dep ensureアプリケーションを実行します。
go run main.goコンソールでトレースデータを確認します。
ARMS コンソールにログインします。
左側のナビゲーションウィンドウで、[アプリケーションモニタリング] > [アプリケーション] を選択します。
アプリケーション名をクリックして、そのトレースデータを表示します。
アイコンが [言語] 列に表示される場合、アプリケーションはアプリケーションモニタリングに接続されています。ハイフン (-) が表示される場合、アプリケーションは OpenTelemetry 向けマネージドサービスに接続されています。
アプリケーションをインストルメント化する
このセクションでは、依存関係の追加、トレーサーの作成、スパンの記録、スパンのタグ付け、サービス間でのコンテキストの伝播といった、各イベントトラッキングの手順を説明します。
依存関係の追加
Zipkin Go ライブラリとルーターをプロジェクトに追加します。
[[constraint]]
name = "github.com/openzipkin/zipkin-go"
version = "0.1.1"
[[constraint]]
name = "github.com/gorilla/mux"
version = "1.6.2"トレーサーの作成
トレーサーは、分散操作のタイミングとメタデータを記録するスパンを生成します。レポート用のエンドポイント、ローカルサービスの ID、サンプリング戦略を設定します。
func getTracer(serviceName string, ip string) *zipkin.Tracer {
// スパンを Zipkin エンドポイントに送信するレポーターを作成します。
// URL をコンソールから取得した実際のエンドポイントに置き換えます。
reporter := httpreporter.NewReporter("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_aokcdqnxyz@123456ff_abcdef123@abcdef123/api/v2/spans")
// スパンがこのサービスの ID でタグ付けされるように、ローカルエンドポイントを設定します。
endpoint, _ := zipkin.NewEndpoint(serviceName, ip)
// すべてのリクエストをサンプリングします。モジュロ値を大きくするとサンプリングが減り、レポートコストが削減されます (例: NewModuloSampler(10) は 10 件に 1 件をサンプリングします)。
sampler := zipkin.NewModuloSampler(1)
// レポーター、エンドポイント、サンプラーでトレーサーを初期化します。
tracer, _ := zipkin.NewTracer(
reporter,
zipkin.WithLocalEndpoint(endpoint),
zipkin.WithSampler(sampler),
)
return tracer
}スパンの作成
ルートスパンは、リクエストのトップレベルの操作を記録します。
span := tracer.StartSpan("some_operation")
// ... 操作を実行 ...
span.Finish()リクエスト内のサブ操作を追跡するには、親コンテキストを渡して子スパンを作成します。
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
// ... サブ操作を実行 ...
childSpan.Finish()カスタムタグとアノテーションの追加 (任意)
タグは、フィルタリングやデバッグのために、キーと値のメタデータをスパンにアタッチします。たとえば、HTTP ステータスコードを記録します。
childSpan.Tag("http.status_code", statusCode)アノテーションは、スパン内のタイムスタンプ付きイベントを記録します。これらを使用して、スタックトレース付きのエラーをログに記録します。
childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
// ... 操作を実行 ...
var events = make(map[string]string)
events["event"] = "error"
events["stack"] = "Runtime Exception: unable to find userid"
jsonStr, err := json.Marshal(events)
if err == nil {
childSpan.Annotate(time.Now(), string(jsonStr))
}
childSpan.Finish()サービス間でのコンテキストの伝播
トレースコンテキスト (TraceId、ParentSpanId、SpanId、Sampled) は、各リモートプロシージャコール (RPC) と共に渡される必要があります。これにより、異なるサービスからのスパンが単一のトレースにリンクされます。Zipkin は B3 ヘッダーを使用して、HTTP および gRPC 経由でコンテキストを伝播します。

クライアント側: 送信リクエストにコンテキストを挿入
req, _ := http.NewRequest("GET", "/", nil)
// トレースコンテキストを B3 ヘッダーとして HTTP リクエストに挿入します。
injector := b3.InjectHTTP(req)
injector(sp.Context())サーバー側: 受信リクエストからコンテキストを抽出
req, _ := http.NewRequest("GET", "/", nil)
b3.InjectHTTP(req)(sp.Context())
b.ResetTimer()
_ = b3.ExtractHTTP(copyRequest(req))トラブルシューティング
イベントトラッキング後のデータなし
アプリケーションからのエラー出力を確認してください。
failed the request with status code 403: ユーザー名またはパスワードが無効です。[アクセスポイント情報] タブから、認証セグメントを含む完全なエンドポイントをコピーしてください。エラーはないがデータがない: エンドポイント URL にプロトコル (
http://またはhttps://) と、/api/v2/spansで終わる完全なパスが含まれていることを確認してください。また、ご利用のネットワークがエンドポイントへのアウトバウンド接続を許可していることも確認してください。サンプリング設定:
NewModuloSamplerの値が 1 より大きい場合、リクエストの一部のみがサンプリングされます。テスト中は、すべてのリクエストをキャプチャするために値を1に設定してください。