트레이스를 로그와 수동으로 연관시키려면 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):
# Datadog 형식의 트레이스 컨텍스트를 로그에 추가하는 예
# 출처: 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
# Datadog 형식의 트레이스 ID를 로그에 삽입하려면 사용자 정의 형식을 추가하세요.
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 표준 로깅 라이브러리를 사용합니다. 다른 로깅 라이브러리의 경우 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 Logger MDC Instrumentation을 활성화하세요. 그런 다음 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
Java 로그를 Datadog으로 보내는 방법은 Java 로그 수집을 참조하세요.
트레이스와 로그를 수동으로 연관시키려면 OpenTelemetry 형식의 trace_id
, span_id
를 Datadog 형식으로 변환하는 함수와 사용 중인 로깅 모듈을 패치합니다. 다음 예제에서는 logrus 라이브러리를 사용합니다.
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에서 사용하는 형식으로 변환합니다. dd.trace_id
및 dd.span_id
속성에서 해당 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");
}