Para correlacionar manualmente tus trazas con tus logs, parchea el módulo de registro que estés utilizando con un procesador que traduzca trace_id
y span_id
con formato de OpenTelemetry al formato de Datadog. El siguiente ejemplo utiliza la biblioteca de registro de structlog. Para otras bibliotecas de registro, puede ser más apropiado modificar los ejemplos del SDK de Datadog . También puedes encontrar un ejemplo de una aplicación Python instrumentada con OpenTelemetry con correlación de trazas y logs en el repositorio trace-examples
de GitHub.
# ########## injection.py
from opentelemetry import trace
class CustomDatadogLogProcessor(object):
def __call__(self, logger, method_name, event_dict):
# Un ejemplo de agregar contexto de traza con formato de Datadog a 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
# Añade un formato personalizado para inyectar IDs de traza con formato de Datadog en logs
structlog.configure(
processors=[
injection.CustomDatadogLogProcessor(),
structlog.processors.JSONRenderer(sort_keys=True)
],
)
log = structlog.getLogger()
log.info("Example log line with trace correlation info")
Para correlacionar manualmente tus trazas con tus logs, parchea el módulo de registro que estés utilizando con un procesador que traduzca trace_id
y span_id
con formato de OpenTelemetry al formato de Datadog. El siguiente ejemplo utiliza la biblioteca de registro de winston. Para otras bibliotecas de registro puede ser más apropiado modificar los ejemplos del SDK de Datadog. También puedes encontrar un ejemplo de aplicación de Node.js instrumentada por OpenTelemetry con correlación de trazas y logs en el repositorio trace-examples
de GitHub.
// ########## logger.js
// convertir a dd con:
// 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
//
// ...
// inicializar tu rastreador
// ...
//
const logger = require('./logger')
//
// usa el registrador en tu aplicación
logger.info("Example log line with trace correlation info")
Para correlacionar manualmente tus trazas con tus logs, parchea el módulo de registro que estés utilizando con un procesador que traduzca trace_id
y span_id
con formato de OpenTelemetry al formato de Datadog. El siguiente ejemplo utiliza la biblioteca de registro estándar de Ruby. Para aplicaciones de Rails u otras bibliotecas de registro, puede ser más apropiado modificar los ejemplos del SDK de Datadog. También puedes encontrar un ejemplo de aplicación de Ruby instrumentada por OpenTelemetry con correlación de trazas y logs en el repositorio trace-examples
de GitHub.
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")
Para correlacionar manualmente tus trazas con tus logs, primero activa la Instrumentación MDC del registrador openTelemetry-java-instrumentation. A continuación, parchea el módulo de registro que estés utilizando con un procesador que traduzca trace_id
y span_id
con formato de OpenTelemetry al formato de Datadog. El siguiente ejemplo utiliza Spring Boot y Logback. Para otras bibliotecas de logs, puede ser más apropiado modificar los ejemplos del SDK de Datadog.
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
Consulta la recopilación de log de Java para saber cómo enviar tus logs de Java a Datadog.
Para correlacionar manualmente tus trazas con tus logs, parchea el módulo de registro que estés utilizando con una función que traduzca trace_id
y span_id
con formato de OpenTelemetry al formato de Datadog. El siguiente ejemplo utiliza la biblioteca de 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)
}
Ponte en contacto con el soporte de Datadog si tienes alguna pregunta.
Para correlacionar manualmente trazas con logs, convierte TraceId
y SpanId
de OpenTelemetry al formato utilizado por Datadog. Añade esos IDs a tus logs bajo los atributos dd.trace_id
y dd.span_id
. El siguiente ejemplo utiliza la biblioteca de Serilog y muestra cómo convertir los IDs de traza y log de OpenTelemetry (System.DiagnosticSource.Activity
) al formato requerido por 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");
}