Zipkin は、元々 Twitter によって開発されたオープンソースの分散トレーシングシステムです。複数の異種システムからリアルタイムモニタリングデータを集約します。zipkin4net ライブラリを使用して .NET アプリケーションのイベントトラッキングを行い、トレースデータを Application Real-Time Monitoring Service (ARMS) のトレーシング分析にレポートできます。
このトピックでは、.NET および C# アプリケーション用の 3 つのインストルメンテーション方法について説明します。
イベントトラッキングメソッドの選択
ご利用のアプリケーションフレームワークに合ったメソッドを選択してください。
| メソッド | 最適な用途 | 必要な NuGet パッケージ |
|---|---|---|
| ASP.NET Core | ASP.NET Core 上に構築されたクロスプラットフォームの Web アプリ | zipkin4net.middleware.aspnetcore、zipkin4net |
| OWIN | OWIN ミドルウェアを使用する .NET Framework の Web アプリ | zipkin4net.middleware.aspnetcore、zipkin4net |
| 手動 | 詳細なスパン制御が必要なバックグラウンドジョブ、メッセージコンシューマー、またはカスタムプロトコル | zipkin4net |
前提条件
開始する前に、以下を確認してください。
ARMS がアクティベートされた Alibaba Cloud アカウント
.NET 開発環境
ご利用の ARMS トレーシング分析インスタンスの Zipkin エンドポイント (「Zipkin エンドポイントの取得」をご参照ください)
Zipkin エンドポイントの取得
トレーシング分析コンソールにログインします。
左側のナビゲーションウィンドウで、[クラスター設定] をクリックし、次に [アクセスポイント情報] タブをクリックします。
上部のナビゲーションバーでリージョンを選択します。[クラスター情報] セクションで、[トークンの表示] をオンにします。
[クライアント] セクションで、[Jaeger] または [Zipkin] をクリックします。
[関連情報] 列で、エンドポイント URL をコピーします。

アプリケーションが Alibaba Cloud の本番環境で実行されている場合は、VPC アクセスポイントを使用してください。それ以外の場合は、パブリックエンドポイントを使用します。v1 を使用する特別な理由がない限り、v2 エンドポイントを使用してください。
ASP.NET Core によるインストルメンテーション
完全なデモプロジェクトをダウンロードし、その README.md の手順に従ってください。
ステップ 1:NuGet パッケージのインストール
dotnet add package zipkin4net.middleware.aspnetcore
dotnet add package zipkin4net| パッケージ | 目的 |
|---|---|
zipkin4net | コアトレーシングライブラリ。スパンを作成し、サンプリングを管理し、Zipkin 互換のバックエンドにトレースデータをレポートします。 |
zipkin4net.middleware.aspnetcore | ASP.NET Core ミドルウェア。受信する各 HTTP リクエストに対して自動的にサーバースパンを作成します。 |
ステップ 2:トレーサーの登録と開始
アプリケーションの起動ロジックに次のコードを追加して zipkin4net を構成し、ARMS トレーシング分析エンドポイントに接続します。
lifetime.ApplicationStarted.Register(() => {
TraceManager.SamplingRate = 1.0f;
var logger = new TracingLogger(loggerFactory, "zipkin4net");
// トレーシング分析コンソールから取得した Zipkin エンドポイントに置き換えます。
// URL の末尾に /api/v2/spans を追加しないでください。
var httpSender = new HttpZipkinSender("<your-zipkin-endpoint>", "application/json");
var tracer = new ZipkinTracer(httpSender, new JSONSpanSerializer());
TraceManager.RegisterTracer(tracer);
TraceManager.Start(logger);
});
lifetime.ApplicationStopped.Register(() => TraceManager.Stop());
app.UseTracing(applicationName);次のプレースホルダーを実際の値に置き換えてください。
| プレースホルダー | 説明 | 例 |
|---|---|---|
<your-zipkin-endpoint> | トレーシング分析コンソールから取得した Zipkin エンドポイント | http://tracing-analysis-dc-hz.aliyuncs.com/adapt_your_token |
ステップ 3:送信 HTTP リクエストのトレース
送信 HTTP 呼び出しが自動的にトレースされ、親スパンと関連付けられるように、TracingHandler を HttpClient パイプラインに追加します。
public override void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("Tracer").AddHttpMessageHandler(provider =>
TracingHandler.WithoutInnerHandler(provider.GetService<IConfiguration>()["applicationName"]));
}OWIN を使用したインストルメンテーション
Open Web Interface for .NET (OWIN) は、.NET Framework Web アプリケーション用のミドルウェア仕様です。
完全なデモプロジェクトをダウンロードし、その README.md の手順に従ってください。
ステップ 1:NuGet パッケージのインストール
dotnet add package zipkin4net.middleware.aspnetcore
dotnet add package zipkin4net| パッケージ | 目的 |
|---|---|
zipkin4net | コアトレーシングライブラリ。 |
zipkin4net.middleware.aspnetcore | ASP.NET Core ミドルウェア。受信する各 HTTP リクエストに対して自動的にサーバースパンを作成します。 |
ステップ 2:トレーサーの登録と開始
// Configure tracing.
TraceManager.SamplingRate = 1.0f;
var logger = new ConsoleLogger();
// トレーシング分析コンソールから取得した Zipkin エンドポイントに置き換えます。
// URL の末尾に /api/v2/spans を追加しないでください。
var httpSender = new HttpZipkinSender("<your-zipkin-endpoint>", "application/json");
var tracer = new ZipkinTracer(httpSender, new JSONSpanSerializer());
TraceManager.RegisterTracer(tracer);
TraceManager.Start(logger);
// Stop TraceManager when the application shuts down.
var properties = new AppProperties(appBuilder.Properties);
var token = properties.OnAppDisposing;
if (token != CancellationToken.None)
{
token.Register(() =>
{
TraceManager.Stop();
});
}
// Register OWIN middleware.
appBuilder.UseZipkinTracer(System.Configuration.ConfigurationManager.AppSettings["applicationName"]);ステップ 3:送信 HTTP リクエストのトレース
HttpClient を TracingHandler でラップして、サービス境界を越えてトレースコンテキストを伝播させます。
using (var httpClient = new HttpClient(new TracingHandler(applicationName)))
{
var response = await httpClient.GetAsync(callServiceUrl);
var content = await response.Content.ReadAsStringAsync();
await context.Response.WriteAsync(content);
}手動でのイベントトラッキング
バックグラウンドジョブ、メッセージコンシューマー、またはカスタムプロトコルのトレースなど、スパン作成を完全に制御するには、手動でのイベントトラッキングを使用します。
完全なデモプロジェクトをダウンロードし、その README.md の手順に従ってください。
ステップ 1:NuGet パッケージのインストール
手動でのイベントトラッキングには、コアトレーシングライブラリのみが必要です。
dotnet add package zipkin4netステップ 2:トレーサーの登録と開始
TraceManager.SamplingRate = 1.0f;
var logger = new ConsoleLogger();
// トレーシング分析コンソールから取得した Zipkin エンドポイントに置き換えます。
// URL の末尾に /api/v2/spans を追加しないでください。
var httpSender = new HttpZipkinSender("<your-zipkin-endpoint>", "application/json");
var tracer = new ZipkinTracer(httpSender, new JSONSpanSerializer());
TraceManager.RegisterTracer(tracer);
TraceManager.Start(logger);ステップ 3:スパンの作成と記録
各リクエストまたは操作に対してルートスパンを作成し、そのライフサイクルイベントを記録します。
var trace = Trace.Create();
Trace.Current = trace;
trace.Record(Annotations.ClientSend());
trace.Record(Annotations.Rpc("client"));
trace.Record(Annotations.Tag("mytag", "spanFrist"));
trace.Record(Annotations.ServiceName("dotnetManual"));
// ... perform your operation here
testCall();
trace.Record(Annotations.ClientRecv());子スパン (たとえば、同じリクエスト内のダウンストリーム呼び出し) を記録するには、現在のトレースで Child() を呼び出します。
var trace = Trace.Current.Child();
Trace.Current = trace;
trace.Record(Annotations.ServerRecv());
trace.Record(Annotations.Rpc("server"));
trace.Record(Annotations.Tag("mytag", "spanSecond"));
trace.Record(Annotations.ServiceName("dotnetManual"));
// ... perform your operation here
trace.Record(Annotations.ServerSend());(オプション) ステップ 4:カスタムタグの追加
トラブルシューティングを容易にするために、スパンにカスタムタグを添付します。たとえば、HTTP ステータスコードを記録したり、エラーにフラグを立てたりします。
tracer.activeSpan().setTag("http.status_code", "200");ステップ 5:サービス間でのトレースコンテキストの伝播
分散システムでは、トレースコンテキストは各 RPC リクエストとともに渡され、異なるサービスからのスパンが単一のトレースに相関付けられます。zipkin4net ライブラリは B3 伝播を使用し、HTTP ヘッダーを介して 4 つの値を渡します。
| トレースフィールド | HTTP ヘッダー |
|---|---|
| TraceId | X-B3-TraceId |
| ParentSpanId | X-B3-ParentSpanId |
| SpanId | X-B3-SpanId |
| Sampled | X-B3-Sampled |
Client Span Server Span
┌──────────────────┐ ┌──────────────────┐
│ │ │ │
│ TraceContext │ Http Request Headers │ TraceContext │
│ ┌──────────────┐ │ ┌───────────────────┐ │ ┌──────────────┐ │
│ │ TraceId │ │ │ X-B3-TraceId │ │ │ TraceId │ │
│ │ │ │ │ │ │ │ │ │
│ │ ParentSpanId │ │ Inject │ X-B3-ParentSpanId │Extract │ │ ParentSpanId │ │
│ │ ├─┼─────────>│ ├────────┼>│ │ │
│ │ SpanId │ │ │ X-B3-SpanId │ │ │ SpanId │ │
│ │ │ │ │ │ │ │ │ │
│ │ Sampled │ │ │ X-B3-Sampled │ │ │ Sampled │ │
│ └──────────────┘ │ └───────────────────┘ │ └──────────────┘ │
│ │ │ │
└──────────────────┘ └──────────────────┘クライアント側 -- 送信リクエストヘッダーにトレースコンテキストをインジェクトします。
_injector.Inject(clientTrace.Trace.CurrentSpan, request.Headers);サーバー側 -- 受信リクエストヘッダーからトレースコンテキストを抽出します。
var traceContext = traceExtractor.Extract(context.Request.Headers);
var trace = traceContext == null ? Trace.Create() : Trace.CreateFromId(traceContext);受信ヘッダーにトレースコンテキストが存在しない場合、新しいルートトレースが作成されます。それ以外の場合は、既存のトレースが継続されます。
よくある質問
Q:デモを実行した後、トレーシング分析コンソールにデータが表示されないのはなぜですか?
A:HttpZipkinSender の構成にある Zipkin エンドポイント URL が正しいことを確認してください。エンドポイントはトレーシング分析コンソールから直接コピーしてください。URL には /api/v2/spans を含めないでください。
// 正しい例:/api/v2/spans を含めずにベースエンドポイントを使用
var httpSender = new HttpZipkinSender("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_your_token", "application/json");