7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ZOZOAdvent Calendar 2021

Day 17

マイクロサービスをdatadogで分散トレースする

Last updated at Posted at 2021-12-16

この記事は ZOZO #4 Advent Calendar 2021 17日目の記事になります。

今回はマイクロサービスのdatadogの分散トレースに挑戦したのでそれについて記載しようと思います。

構成は以下になります。

Untitled Diagram.jpeg

処理の流れは以下になります。

  1. Classic ASPからJava API【A】の登録APIを呼ぶ
  2. Java API【A】はDynamoDBに処理開始のレコードを登録する
  3. Java API【A】はKinesis Data Streams(以下、KDS)に登録情報を渡す
  4. Java API【B】はKDSから情報を取り出し、処理を行う
  5. Java API【B】はDynamoDBにレコードを処理完了に更新する

これにdatadogを仕込み、一連の処理をトレースします。

はじめにJava API【A】の登録APIでTraceを作成します。

public record Trace(TraceId traceId, DdCarrier ddCarrier) {
  public static Trace convert(String traceId) {
    Tracer tracer = GlobalTracer.get();
    Map<String, String> ddMap = new HashMap<>();
    tracer.inject(
        tracer.activeSpan().context(),
        Format.Builtin.TEXT_MAP_INJECT,
        new TextMapInjectAdapter(ddMap));
    return new Trace(new TraceId(traceId), new DdCarrier(ddMap));
  }
}

作成されたTraceをKDSに渡し、Java API【A】の登録APIの返却値として以下を返却します。

  • x-datadog-trace-id
  • x-datadog-sampling-priority
  • x-datadog-parent-id

Java API【B】はKDSを経由してdatadogのパラメータを受け取ります。
受け取ったパラメータを元にSpanを作成し、登録APIのtraceと紐付けます。
また、Java API【A】の参照APIもClassic ASPを経由して同じ様に対応します。

Tracer tracer = GlobalTracer.get();
SpanBuilder spanBuilder =
    new SpanBuilder()
        .generate(
            tracer,
            "処理API",
            traceId,
            datadogTraceId,
            datadogParentId,
            datadogSamplingPriority);
Span span = spanBuilder.start();
try (Scope scope = tracer.scopeManager().activate(span)) {
  // 処理
} catch (Exception e) {
  span.setTag(DDTags.ERROR_MSG, e.getMessage());
  span.setTag(DDTags.ERROR_STACK, Arrays.toString(e.getStackTrace()));
  throw e;
} finally {
  span.finish();
}
public class SpanBuilder {
  public Tracer.SpanBuilder generate(
      Tracer tracer,
      String operationName,
      String traceId,
      String datadogTraceId,
      String datadogParentId,
      String datadogSamplingPriority) {
    Tracer.SpanBuilder spanBuilder =
        tracer
            .buildSpan(operationName)
            .withTag("trace-id", traceId)
            .withTag("datadog-trace-id", datadogTraceId)
            .withTag("datadog-sampling-priority", datadogSamplingPriority)
            .withTag("datadog-parent-id", datadogParentId);
    Map<String, String> ddCarrier = new HashMap<>();
    ddCarrier.put("x-datadog-trace-id", datadogTraceId);
    ddCarrier.put("x-datadog-sampling-priority", datadogSamplingPriority);
    ddCarrier.put("x-datadog-parent-id", datadogParentId);
    SpanContext spanContext =
        tracer.extract(Format.Builtin.TEXT_MAP_EXTRACT, new TextMapExtractAdapter(ddCarrier));
    return spanBuilder.asChildOf(spanContext);
  }
}

これにより、以下のように一気通貫で処理をトレースすることができます。
処理の流れが追いやすくなり、エラーなどが発生した際も原因の特定がしやすくなりました。

スクリーンショット 2021-12-14 9.18.37.png

明日は @EnKUMA の記事になります。
読んでいただきありがとうございました。

参考 : datadog 分散トレースのコンテキストの挿入と抽出

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?