Trazas
Las trazas nos dan una visión general de lo que ocurre cuando se hace una solicitud a una aplicación. Ya sea que tu aplicación sea un monolito con una sola base de datos o una sofisticada malla de servicios, las trazas son esenciales para entender la “ruta” completa que una solicitud toma en tu aplicación.
Exploremos esto con tres unidades de trabajo, representadas como Spans:
Los siguientes ejemplos en JSON no representan un formato específico, y especialmente no representan OTLP/JSON, que es más verboso.
Span hello
:
{
"name": "hello",
"context": {
"trace_id": "5b8aa5a2d2c872e8321cf37308d69df2",
"span_id": "051581bf3cb55c13"
},
"parent_id": null,
"start_time": "2022-04-29T18:52:58.114201Z",
"end_time": "2022-04-29T18:52:58.114687Z",
"attributes": {
"http.route": "some_route1"
},
"events": [
{
"name": "Guten Tag!",
"timestamp": "2022-04-29T18:52:58.114561Z",
"attributes": {
"event_attributes": 1
}
}
]
}
Este es el span raíz, que denota el principio y el final de toda la operación.
Observa que tiene un campo trace_id
que indica la traza, pero no tiene un
parent_id
. Así es como sabes que es el span raíz.
Span hello-greetings
:
{
"name": "hello-greetings",
"context": {
"trace_id": "5b8aa5a2d2c872e8321cf37308d69df2",
"span_id": "5fb397be34d26b51"
},
"parent_id": "051581bf3cb55c13",
"start_time": "2022-04-29T18:52:58.114304Z",
"end_time": "2022-04-29T22:52:58.114561Z",
"attributes": {
"http.route": "some_route2"
},
"events": [
{
"name": "hey there!",
"timestamp": "2022-04-29T18:52:58.114561Z",
"attributes": {
"event_attributes": 1
}
},
{
"name": "bye now!",
"timestamp": "2022-04-29T18:52:58.114585Z",
"attributes": {
"event_attributes": 1
}
}
]
}
Este span encapsula tareas específicas, como saludar, y su padre es el span
hello
. Ten en cuenta que comparte el mismo trace_id
que el span raíz, lo que
indica que es parte de la misma traza. Además, tiene un parent_id
que coincide
con el span_id
del span hello
.
Span hello-salutations
:
{
"name": "hello-salutations",
"context": {
"trace_id": "5b8aa5a2d2c872e8321cf37308d69df2",
"span_id": "93564f51e1abe1c2"
},
"parent_id": "051581bf3cb55c13",
"start_time": "2022-04-29T18:52:58.114492Z",
"end_time": "2022-04-29T18:52:58.114631Z",
"attributes": {
"http.route": "some_route3"
},
"events": [
{
"name": "hey there!",
"timestamp": "2022-04-29T18:52:58.114561Z",
"attributes": {
"event_attributes": 1
}
}
]
}
Este span representa la tercera operación en esta traza y, al igual que el
anterior, es un hijo del span hello
. Eso también lo convierte en un span
hermano del span hello-greetings
.
Estos tres bloques de JSON comparten el mismo trace_id
, y el campo parent_id
representa una jerarquía. ¡Eso lo convierte en una traza!
Otra cosa que notarás es que cada span parece un log estructurado. ¡Eso es porque, en cierto modo, lo es! Una forma de pensar en las trazas es que son una colección de logs estructurados con contexto, correlación, jerarquía y mucho más incorporado. Sin embargo, estos “logs estructurados” pueden provenir de diferentes procesos, servicios, máquinas virtuales, centros de datos, etc. Esto es lo que permite que el trazado represente una vista de extremo a extremo de cualquier sistema.
Para entender cómo funciona el trazado en OpenTelemetry, veamos una lista de los componentes que desempeñarán un papel en la instrumentación de nuestro código.
Proveedores de Trazas
Un Proveedor de Trazas (a veces llamado TracerProvider
) es una factoría para
Tracers
. En la mayoría de las aplicaciones, un TracerProvider
se inicializa
una vez y su ciclo de vida coincide con el ciclo de vida de la aplicación. La
inicialización del TracerProvider
también incluye la inicialización de
Resource
y Exporter
. Suele ser el primer paso en el trazado con
OpenTelemetry. En algunos SDK de lenguaje, ya se inicializa un Tracer Provider
global para ti.
Tracer
Un Tracer
crea spans que contienen más información sobre lo que está
sucediendo en una operación dada, como una solicitud en un servicio. Los
Tracers
se crean a partir de los Proveedor de Trazas.
Exportadores de trazas
Los exportadores de trazas envían trazas a un consumidor. Este consumidor puede ser la salida estándar para la depuración en tiempo de desarrollo, el OpenTelemetry Collector, o cualquier backend de código abierto o de proveedores de tu elección.
Propagación de contexto
La propagación de contexto es el concepto central que habilita el trazado distribuido. Con la propagación de contexto, los spans pueden correlacionarse entre sí y ensamblarse en una traza, independientemente de dónde se generen. Para saber más sobre este tema, consulta la página sobre Context Propagation.
Spans
Un span representa una unidad de trabajo u operación. Los spans son los bloques de construcción de las trazas. En OpenTelemetry, incluyen la siguiente información:
- Nombre
- ID del span padre (vacío para los spans raíz)
Timestamp
(marca de tiempo) de inicio y finalización- Contexto de span
- Atributos
- Eventos de span
- Links de span
- Estado del span
Ejemplo de span:
{
"name": "/v1/sys/health",
"context": {
"trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d",
"span_id": "086e83747d0e381e"
},
"parent_id": "",
"start_time": "2021-10-22 16:04:01.209458162 +0000 UTC",
"end_time": "2021-10-22 16:04:01.209514132 +0000 UTC",
"status_code": "STATUS_CODE_OK",
"status_message": "",
"attributes": {
"net.transport": "IP.TCP",
"net.peer.ip": "172.17.0.1",
"net.peer.port": "51820",
"net.host.ip": "10.177.2.152",
"net.host.port": "26040",
"http.method": "GET",
"http.target": "/v1/sys/health",
"http.server_name": "mortar-gateway",
"http.route": "/v1/sys/health",
"http.user_agent": "Consul Health Check",
"http.scheme": "http",
"http.host": "10.177.2.152:26040",
"http.flavor": "1.1"
},
"events": [
{
"name": "",
"message": "OK",
"timestamp": "2021-10-22 16:04:01.209512872 +0000 UTC"
}
]
}
Los spans pueden anidarse, como se insinúa por la presencia de un ID de span padre: los spans hijos representan sub-operaciones. Esto permite que los spans capturen de forma más precisa el trabajo realizado en una aplicación.
Contexto de span
El contexto de span es un objeto inmutable en cada span que contiene lo siguiente:
- El ID de traza (
Trace ID
) que representa la traza de la que el span forma parte - El ID de span (
Span ID
) del propio span Trace Flags
, una codificación binaria que contiene información sobre la trazaTrace State
, una lista de pares clave-valor que pueden llevar información de trazas específica del proveedor
El contexto de span es la parte de un span que se serializa y propaga junto con el Contexto Distribuido y el Baggage.
Debido a que el contexto de span contiene el ID de traza, se usa al crear Links de Span.
Atributos
Los atributos son pares clave-valor que contienen metadatos que puedes usar para anotar un span y llevar información sobre la operación que está rastreando.
Por ejemplo, si un span rastrea una operación que añade un artículo al carrito de compras de un usuario en un sistema de eCommerce, puedes capturar el ID del usuario, el ID del artículo a añadir al carrito y el ID del carrito.
Puedes añadir atributos a los spans durante o después de su creación. Es preferible añadir atributos al crear el span para que estén disponibles para el muestreo del SDK. Si tienes que añadir un valor después de la creación del span, actualiza el span con el valor.
Los atributos tienen las siguientes reglas que cada SDK de lenguaje implementa:
- Las claves deben ser valores de cadena no nulos
- Los valores deben ser una cadena no nula, un valor booleano, un valor de punto flotante, un entero o un array de estos valores
Además, existen Atributos Semánticos, que son convenciones conocidas de nomenclatura para los metadatos que suelen estar presentes en operaciones comunes. Es útil usar la nomenclatura de atributos semánticos siempre que sea posible para que los tipos comunes de metadatos estén estandarizados en todos los sistemas.
Eventos de span
Un evento de span puede considerarse como un mensaje de log estructurado (o anotación) en un span, que se usa típicamente para denotar un punto significativo y singular en el tiempo durante la duración del span.
Por ejemplo, considera dos escenarios en un navegador web:
- Rastrear la carga de una página
- Marcar cuándo una página se vuelve interactiva
Un span es la mejor opción para el primer escenario porque es una operación con un inicio y un final.
Un evento de span es la mejor opción para rastrear el segundo escenario, ya que representa un punto significativo y singular en el tiempo.
Cuándo usar eventos de span en lugar de atributos de span
Dado que los eventos de span también contienen atributos, la pregunta de cuándo usar eventos en lugar de atributos podría no tener siempre una respuesta obvia. Para ayudarte a decidir, considera si una marca de tiempo específica es significativa.
Por ejemplo, cuando estás rastreando una operación con un span y la operación se completa, es posible que quieras añadir datos de la operación a tu telemetría.
- Si el
timestamp
en el que se completa la operación es significativo o relevante, adjunta los datos a un evento de span. - Si el
timestamp
no es significativo, adjunta los datos como atributos de span.
Links de span
Los links existen para que puedas asociar un span con uno o más spans, lo que implica una relación causal. Por ejemplo, digamos que tenemos un sistema distribuido donde algunas operaciones son rastreadas por una traza.
En respuesta a algunas de estas operaciones, se pone en cola una operación adicional para ser ejecutada, pero su ejecución es asíncrona. Podemos rastrear esta operación subsiguiente con una traza también.
Nos gustaría asociar la traza de las operaciones subsiguientes con la primera traza, pero no podemos predecir cuándo comenzarán las operaciones subsiguientes. Necesitamos asociar estas dos trazas, así que usaremos un link de span.
Puedes enlazar el último span de la primera traza con el primer span de la segunda traza. Ahora, están asociados causalmente entre sí.
Los links son opcionales pero sirven como una buena manera de asociar spans de traza entre sí. Para más información, consulta Links de span.
Estado del span
Cada span tiene un estado. Los tres valores posibles son:
Unset
Error
Ok
El valor por defecto es Unset
. Un estado de span Unset
indica que la
operación que rastreó se completó con éxito y sin un error.
Cuando un estado de span es Error
, significa que ocurrió un error en la
operación que rastrea. Por ejemplo, esto podría deberse a un error HTTP 500 en
un servidor que maneja una solicitud.
Cuando un estado de span es Ok
, significa que el span fue marcado
explícitamente como libre de errores por el desarrollador de una aplicación.
Aunque esto no es intuitivo, no es obligatorio establecer un estado de span como
Ok
cuando se sabe que un span se ha completado sin error, ya que esto está
cubierto por Unset
. Lo que Ok
hace es representar una “llamada final”
inequívoca sobre el estado de un span que ha sido explícitamente establecido por
un usuario. Esto es útil en cualquier situación en la que un desarrollador desee
que no haya otra interpretación de un span que no sea “exitoso”.
Para reiterar: Unset
representa un span que se completó sin un error. Ok
representa cuando un desarrollador marca explícitamente un span como exitoso. En
la mayoría de los casos, no es necesario marcar explícitamente un span como
Ok
.
Tipo de span
Cuando se crea un span, este es uno de los siguientes: Client
, Server
,
Internal
, Producer
o Consumer
. Este tipo de span proporciona una pista al
backend de trazado sobre cómo se debe ensamblar la traza. Según la
especificación de OpenTelemetry, el padre de un span Server
es a menudo un
span Client
remoto, y el hijo de un span Client
suele ser un span Server
.
De manera similar, el padre de un span Consumer
es siempre un Producer
y el
hijo de un span Producer
es siempre un Consumer
. Si no se proporciona, se
asume que el tipo de span es Internal
.
Para más información sobre tipos de span, consulta SpanKind.
Client
Un span Client
representa una llamada remota saliente síncrona, como una
solicitud HTTP saliente o una llamada a base de datos. Ten en cuenta que en este
contexto, “síncrona” no se refiere a async/await
, sino al hecho de que no se
pone en cola para su posterior procesamiento.
Server
Un span Server
representa una llamada remota entrante síncrona, como una
solicitud HTTP entrante o una llamada a un procedimiento remoto.
Internal
Los spans Internal
representan operaciones que no cruzan un límite de proceso.
Cosas como instrumentar una llamada a función o un middleware de Express pueden
usar spans Internal
.
Producer
Los spans Producer
representan la creación de un trabajo que puede ser
procesado de forma asíncrona más tarde. Puede ser un trabajo remoto, como uno
insertado en una cola de trabajos, o un trabajo local manejado por un
event listener
.
Consumer
Los spans Consumer
representan el procesamiento de un trabajo creado por un
Producer
y pueden comenzar mucho después de que el span Producer
ya haya
terminado.
Especificación
Para más información, consulta la especificación de trazas.
Comentarios
¿Fue útil esta página?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!