Correlación de logs y trazas de Python
Inyección
Registro de la biblioteca estándar
Para correlacionar tus [trazas1 con tus logs, completa los siguientes pasos:
- Activar la instrumentación automática.
- Incluir los atributos requeridos del registro de log.
Paso 1: Activar la instrumentación automática
Activa la instrumentación automática mediante una de las siguientes opciones:
Opción 1: inyección de biblioteca:
- Establece la variable de entorno
DD_LOGS_INJECTION=true
en el archivo deployment/manifest
de la aplicación. - Sigue las instrucciones de la Inyección de biblioteca para configurar el rastreo.
Opción 2: ddtrace-run
:
- Establece la variable de entorno
DD_LOGS_INJECTION=true
en el entorno donde se ejecuta la aplicación. - Importa ddtrace a la aplicación.
- Ejecuta la aplicación con
ddtrace-run
(por ejemplo, ddtrace-run python appname.py
).
Opción 3: patch
:
- Importa ddtrace a la aplicación.
- Añade
ddtrace.patch(logging=True)
al principio del código de la aplicación.
Paso 2: Incluir los atributos necesarios
Actualiza tu formato de log para incluir los atributos requeridos del registro de log.
Incluye los atributos dd.env
, dd.service
, dd.version
, dd.trace_id
y
dd.span_id
para tu registro de log en la cadena de formato.
He aquí un ejemplo que utiliza logging.basicConfig
para configurar la inyección de log:
import logging
from ddtrace import tracer
FORMAT = ('%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] '
'[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] '
'- %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger(__name__)
log.level = logging.INFO
@tracer.wrap()
def hello():
log.info('Hello, World!')
hello()
Para obtener más información sobre la inyección de logs, lee la documentación de ddtrace.
Sin registro de la biblioteca estándar
Si nos utiliza el módulo logging
de la biblioteca estándar, puedes utilizar el siguiente fragmento de código para inyectar información de rastreo en tus logs:
from ddtrace import tracer
span = tracer.current_span()
correlation_ids = (str((1 << 64) - 1 & span.trace_id), span.span_id) if span else (None, None)
Para demostrar este enfoque, el siguiente ejemplo define una función como un procesador en structlog
para añadir campos de rastreo a la salida del log:
import ddtrace
from ddtrace import tracer
import structlog
def tracer_injection(logger, log_method, event_dict):
# obtén IDs de correlación del contexto de rastreo actual
span = tracer.current_span()
trace_id, span_id = (str((1 << 64) - 1 & span.trace_id), span.span_id) if span else (None, None)
# añade IDs al diccionario de eventos de structlog
event_dict['dd.trace_id'] = str(trace_id or 0)
event_dict['dd.span_id'] = str(span_id or 0)
# añade el entorno, servicio y versión configurados para el rastreo
event_dict['dd.env'] = ddtrace.config.env or ""
event_dict['dd.service'] = ddtrace.config.service or ""
event_dict['dd.version'] = ddtrace.config.version or ""
return event_dict
structlog.configure(
processors=[
tracer_injection,
structlog.processors.JSONRenderer()
]
)
log = structlog.get_logger()
Una vez configurado el registrador, la ejecución de una función rastreada que loguea un evento arroja la información del rastreo inyectado:
>>> traced_func()
{"event": "In tracer context", "dd.trace_id": 9982398928418628468, "dd.span_id": 10130028953923355146, "dd.env": "dev", "dd.service": "hello", "dd.version": "abc123"}
Nota: Si no estás utilizando la integración de log de Datadog para analizar tus logs, tus reglas personalizadas de parseo de logs deben asegurar que dd.trace_id
y dd.span_id
se analizan como cadenas y se reasignan mediante el Reasignador de traza. Para obtener más información, consulta Los logs correlacionados no aparecen en el panel de ID de traza.
Consulta la documentación de registro de Python para asegurarte de que la integración de log de Python está correctamente configurada para que tus logs de Python se analicen automáticamente.
Leer más
Más enlaces, artículos y documentación útiles: