DatadogAPMをOpencensusで活用しよう(ログとトレースの紐付け)


はじめに

こんにちわ、すえけん(@sueken5)です。

この記事ではDatadogAPMのトレースにログ情報を付随させる方法を書きます。

このようにログとトレースを紐付けると簡単にデバックできるのでとてもおすすめです。

紐づけるには

datadog APMとログを紐づけるにはログにtrace_idとspan_idをつける必要があります。実際のログは次のような感じです。

{"level":"DEBUG","ts":"2020-01-31T15:33:52.042+0900","msg":"hello world","dd.trace_id":10034860525566454582}

datadogの予約語?にdd.trace_idとdd.span_idがありますのでそれにidを入れます。

datadog用にTraceID/SpanIDを取得しよう

ここでハマったのですがTraceID/SpanIDは文字列の状態で送ってもうまくTraceIDが違い、トレースとログがくっつきません。なので次のようにします。

    spanCTX := trace.FromContext(ctx).SpanContext()
    fields = append(
        fields,
        zap.Uint64("dd.trace_id", binary.BigEndian.Uint64(spanCTX.TraceID[8:])),
        zap.Uint64("dd.span_id", binary.BigEndian.Uint64(spanCTX.SpanID[:])),
    )
    l.logger.Error(msg, fields...)

spanContextからTraceIDをとりbinaryパッケージを使って処理します。このやり方はdatadogのexporterのTraceIDの取得のやり方を参考にしています。

github.com/DataDog/opencensus-go-exporter-datadog/span.go
func (e *traceExporter) convertSpan(s *trace.SpanData) *ddSpan {
    startNano := s.StartTime.UnixNano()
    span := &ddSpan{
        TraceID:  binary.BigEndian.Uint64(s.SpanContext.TraceID[8:]),
        SpanID:   binary.BigEndian.Uint64(s.SpanContext.SpanID[:]),
        Name:     "opencensus",
        Resource: s.Name,
        Service:  e.opts.Service,
        Start:    startNano,
        Duration: s.EndTime.UnixNano() - startNano,
        Metrics:  map[string]float64{},
        Meta:     map[string]string{},
    }
        // 省略
}

この通りやるとトレースとログが紐づくようになります。

まとめ

トレースとログが紐づくっと一気にデバックがしやすくなります。おすすめです。