手動でトレースとログに相関性を持たせるには、OpenTelemetry 形式の trace_id
および span_id
を Datadog 形式に変換するプロセッサで、使用しているロギングモジュールにパッチを適用します。以下の例では、structlog ロギングライブラリを使用しています。その他のロギングライブラリの場合は、Datadog SDK の例を変更した方がより適切なことがあります。また、trace-examples
GitHub リポジトリでは、OpenTelemetry がインスツルメントされた Python アプリケーションとそのトレース-ログ相関の例が紹介されています。
# ########## injection.py
from opentelemetry import trace
class CustomDatadogLogProcessor(object):
def __call__(self, logger, method_name, event_dict):
# An example of adding datadog formatted trace context to logs
# from: https://github.com/open-telemetry/opentelemetry-python-contrib/blob/b53b9a012f76c4fc883c3c245fddc29142706d0d/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/propagator.py#L122-L129
current_span = trace.get_current_span()
if not current_span.is_recording():
return event_dict
context = current_span.get_span_context() if current_span is not None else None
if context is not None:
event_dict["dd.trace_id"] = str(context.trace_id & 0xFFFFFFFFFFFFFFFF)
event_dict["dd.span_id"] = str(context.span_id)
return event_dict
# ##########
# ########## app.py
import .injection
import logging
import structlog
# Add custom formatting to inject datadog formatted trace ids into logs
structlog.configure(
processors=[
injection.CustomDatadogLogProcessor(),
structlog.processors.JSONRenderer(sort_keys=True)
],
)
log = structlog.getLogger()
log.info("Example log line with trace correlation info")
手動でトレースとログに相関性を持たせるには、OpenTelemetry 形式の trace_id
および span_id
を Datadog 形式に変換するプロセッサで、使用しているロギングモジュールにパッチを適用します。以下の例では、winston ロギングライブラリを使用しています。その他のロギングライブラリの場合は、Datadog SDK の例を変更した方がより適切なことがあります。また、trace-examples
GitHub リポジトリでは、OpenTelemetry がインスツルメントされた Node.js アプリケーションとそのトレース-ログ相関の例が紹介されています。
// ########## logger.js
// 以下で dd に変換します。
// https://github.com/DataDog/dd-trace-js/blob/master/packages/dd-trace/src/id.js
const opentelemetry = require('@opentelemetry/api');
const winston = require('winston')
const tracingFormat = function () {
return winston.format(info => {
const span = opentelemetry.trace.getSpan(opentelemetry.context.active());
if (span) {
const { spanId, traceId } = span.spanContext();
const traceIdEnd = traceId.slice(traceId.length / 2);
info['dd.trace_id'] = BigInt(`0x${traceIdEnd}`).toString();
info['dd.span_id'] = BigInt(`0x${spanId}`).toString();
}
return info;
})();
}
module.exports = winston.createLogger({
transports: [new winston.transports.Console],
format: winston.format.combine(tracingFormat(), winston.format.json())
});
// ##########
// ########## index.js
//
// ...
// トレーサーを初期化します
// ...
//
const logger = require('./logger')
//
// アプリケーションでロガーを使用します
logger.info("Example log line with trace correlation info")
手動でトレースとログに相関性を持たせるには、OpenTelemetry 形式の trace_id
および span_id
を Datadog 形式に変換するプロセッサで、使用しているロギングモジュールにパッチを適用します。以下の例では、Ruby 標準ライブラリロギングを使用しています。Rails などその他のロギングライブラリの場合は、Datadog SDK の例を変更した方がより適切なことがあります。また、trace-examples
GitHub リポジトリでは、OpenTelemetry がインスツルメントされた Ruby アプリケーションとそのトレース-ログ相関の例が紹介されています。
logger = Logger.new(STDOUT)
logger.progname = 'multivac'
original_formatter = Logger::Formatter.new
logger.formatter = proc do |severity, datetime, progname, msg|
current_span = OpenTelemetry::Trace.current_span(OpenTelemetry::Context.current).context
dd_trace_id = current_span.trace_id.unpack1('H*')[16, 16].to_i(16).to_s
dd_span_id = current_span.span_id.unpack1('H*').to_i(16).to_s
if current_span
"#{{datetime: datetime, progname: progname, severity: severity, msg: msg, 'dd.trace_id': dd_trace_id, 'dd.span_id': dd_span_id}.to_json}\n"
else
"#{{datetime: datetime, progname: progname, severity: severity, msg: msg}.to_json}\n"
end
end
logger.info("Example log line with trace correlation info")
手動でトレースとログに相関性を持たせるには、まず openTelemetry-java-instrumentation ロガー MDC インスツルメンテーションを有効にします。次に、OpenTelemetry 形式の trace_id
および span_id
を Datadog 形式に変換するプロセッサで、使用しているロギングモジュールにパッチを適用します。以下の例では、Spring Boot および Logbackを使用しています。その他のロギングライブラリの場合は、Datadog SDK の例を変更した方がより適切なことがあります。
String traceIdValue = Span.current().getSpanContext().getTraceId();
String traceIdHexString = traceIdValue.substring(traceIdValue.length() - 16 );
long datadogTraceId = Long.parseUnsignedLong(traceIdHexString, 16);
String datadogTraceIdString = Long.toUnsignedString(datadogTraceId);
String spanIdHexString = Span.current().getSpanContext().getSpanId();
long datadogSpanId = Long.parseUnsignedLong(spanIdHexString, 16);
String datadogSpanIdString = Long.toUnsignedString(datadogSpanId);
logging.pattern.console = %d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg dd.trace_id=%X{datadogTraceIdString} dd.span_id=%X{datadogSpanIdString} %n
See Java Log Collection on how to send your Java logs to Datadog.
トレースをログと手動で関連付けるには、使用しているログモジュールに、OpenTelemetry 形式の trace_id
と span_id
を Datadog 形式に変換する関数を適用します。次の例では、logrus Library を使用しています。
package main
import (
"context"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel"
"strconv"
)
func main() {
ctx := context.Background()
tracer := otel.Tracer("example/main")
ctx, span := tracer.Start(ctx, "example")
defer span.End()
log.SetFormatter(&log.JSONFormatter{})
standardFields := log.Fields{
"dd.trace_id": convertTraceID(span.SpanContext().TraceID().String()),
"dd.span_id": convertTraceID(span.SpanContext().SpanID().String()),
"dd.service": "serviceName",
"dd.env": "serviceEnv",
"dd.version": "serviceVersion",
}
log.WithFields(standardFields).WithContext(ctx).Info("hello world")
}
func convertTraceID(id string) string {
if len(id) < 16 {
return ""
}
if len(id) > 16 {
id = id[16:]
}
intValue, err := strconv.ParseUint(id, 16, 64)
if err != nil {
return ""
}
return strconv.FormatUint(intValue, 10)
}
ご質問は、Datadog サポートまでお問い合わせください。
トレースとログを手動で相関付けるには、OpenTelemetry の TraceId
と SpanId
を Datadog が使用するフォーマットに変換します。これらの ID をログに dd.trace_id
と dd.span_id
属性で追加してください。次の例では、Serilog ライブラリを使用して、OpenTelemetry (System.DiagnosticSource.Activity
) のトレースとスパン ID を Datadog の要求するフォーマットに変換する方法を示しています。
var stringTraceId = Activity.Current.TraceId.ToString();
var stringSpanId = Activity.Current.SpanId.ToString();
var ddTraceId = Convert.ToUInt64(stringTraceId.Substring(16), 16).ToString();
var ddSpanId = Convert.ToUInt64(stringSpanId, 16).ToString();
using (LogContext.PushProperty("dd.trace_id", ddTraceId))
using (LogContext.PushProperty("dd.span_id", ddSpanId))
{
Serilog.Log.Logger.Information("Example log line with trace correlation info");
}