Instrumentación personalizada de Python utilizando la API de Datadog
Si no has leído las instrucciones de configuración de la instrumentación automática, empieza por las Instrucciones de configuración de Python.
Si no utilizas la instrumentación de biblioteca compatible (consulta Compatibilidad de bibliotecas), puede que desees instrumentar manualmente tu código.
También es posible que desees ampliar la funcionalidad de la biblioteca ddtrace
u obtener un control más preciso sobre la instrumentación de tu aplicación. La biblioteca proporciona varias técnicas para conseguirlo.
Creación de tramos
La biblioteca ddtrace
crea tramos automáticamente con ddtrace-run
para muchas bibliotecas y marcos. Sin embargo, es posible que desees obtener visibilidad de tu propio código y esto se logra utilizando tramos.
Dentro de tu solicitud web (por ejemplo, make_sandwich_request
), puedes realizar varias operaciones, como get_ingredients()
y assemble_sandwich()
, que son útiles para hacer mediciones.
def make_sandwich_request(request):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
ddtrace
proporciona un decorador tracer.wrap()
que puede utilizarse para añadir las funciones de interés. Esto es útil si deseas rastrear la función independientemente de desde donde se está llamando.
from ddtrace import tracer
@tracer.wrap(service="my-sandwich-making-svc", resource="resource_name")
def get_ingredients():
# go to the pantry
# go to the fridge
# maybe go to the store
return
# Puedes brindar más información para personalizar el tramo
@tracer.wrap("assemble_sandwich", service="my-sandwich-making-svc", resource="resource_name")
def assemble_sandwich(ingredients):
return
Para obtener más información, lee Detalles de la API del decorador para ddtrace.Tracer.wrap()
.
Para rastrear un bloque arbitrario de código, utiliza el gestor de contexto ddtrace.Span
como se indica a continuación, o consulta la documentación de uso avanzado.
from ddtrace import tracer
def make_sandwich_request(request):
# Captura ambas operaciones en un tramo
with tracer.trace("sandwich.make"):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
def make_sandwich_request(request):
# Captura ambas operaciones en un tramo
with tracer.trace("sandwich.create", resource="resource_name") as outer_span:
with tracer.trace("get_ingredients", resource="resource_name") as span:
ingredients = get_ingredients()
with tracer.trace("assemble_sandwich", resource="resource_name") as span:
sandwich = assemble_sandwich(ingredients)
Para más información, lee todos los detalles de la API de ddtrace.Tracer()
.
Si los métodos del decorador y del gestor de contexto aún no alcanzan para tus necesidades de rastreo, se proporciona una API manual que te permite iniciar y finalizar tramos como lo necesites:
def make_sandwich_request(request):
span = tracer.trace("sandwich.create", resource="resource_name")
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
span.finish() # remember to finish the span
Para más detalles de la API del decorador, lee la documentación de ddtrace.Tracer.trace
o la documentación de ddtrace.Span.finish
.
Acceso a tramos activos
La instrumentación incorporada y tu propia instrumentación personalizada crean tramos alrededor de operaciones significativas. Puedes acceder al tramo activo para incluir datos significativos.
from ddtrace import tracer
def make_sandwich_request(request):
# Captura ambas operaciones en un tramo
with tracer.trace("sandwich.make") as my_span:
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
def get_ingredients():
# Obtener el tramo activo
span = tracer.current_span()
# este es el tramo my_span from make_sandwich_request anterior
def assemble_sandwich(ingredients):
with tracer.trace("another.operation") as another_span:
# Obtener el tramo raíz activo
span = tracer.current_root_span()
# este tramo es my_span from make_sandwich_request anterior
Añadir etiquetas
Pueden añadirse etiquetas a un tramo utilizando el método set_tag
en un tramo:
from ddtrace import tracer
def make_sandwich_request(request):
with tracer.trace("sandwich.make") as span:
ingredients = get_ingredients()
span.set_tag("num_ingredients", len(ingredients))
Pueden establecerse etiquetas globalmente en el rastreador. Estas etiquetas se aplican a cada tramo que se crea.
from ddtrace import tracer
from myapp import __version__
# Esto se aplicará a cada tramo
tracer.set_tags({"version": __version__, "<TAG_KEY_2>": "<TAG_VALUE_2>"})
La información de la excepción se captura y se adjunta a un tramo si hay uno activo cuando se produce la excepción.
from ddtrace import tracer
with tracer.trace("throws.an.error") as span:
raise Exception("Oops!")
# `span` se marcará como un error y tendrá
# la stack trace y el mensaje de excepción adjuntos como etiquetas
También se puede marcar manualmente una traza como errónea:
from ddtrace import tracer
span = tracer.trace("operation")
span.error = 1
span.finish()
En caso que desees marcar el tramo raíz local con el error planteado:
import os
from ddtrace import tracer
try:
raise TypeError
except TypeError as e:
root_span = tracer.current_root_span()
(exc_type, exc_val, exc_tb) = sys.exc_info()
# esto establece el tipo de error, marca el tramo como un error y añade el rastreo
root_span.set_exc_info(exc_type, exc_val, exc_tb)
Puedes configurar la propagación de contexto para trazas distribuidas al inyectar y extraer encabezados. Consulta Propagación de contexto de traza para obtener información.
Filtrado de recursos
Las trazas se pueden excluir en función de su nombre de recurso, para eliminar el tráfico Synthetic, como los checks de estado, de la notificación de trazas a Datadog. Esta y otras configuraciones de seguridad y ajuste se pueden encontrar en la página de Seguridad o en Ignorar recursos no deseados.
Leer más
Más enlaces, artículos y documentación útiles: