¿Qué es el seguimiento distribuido y la correlación de telemetría?

Nota:

La siguiente documentación se basa en la API clásica de Application Insights. El plan a largo plazo de Application Insights consiste en recopilar datos mediante OpenTelemetry. Para más información, consulte Habilitación de Azure Monitor OpenTelemetry para aplicaciones de .NET, Node.js, Python y Java.

La nube moderna y las arquitecturas de microservicios han permitido servicios sencillos e independientes que reducen los costes a la vez que aumentan la disponibilidad y el rendimiento. Han supuesto también, por contra, que los sistemas generales sean más difíciles de deducir y depurar. El seguimiento distribuido resuelve este problema proporcionando un generador de perfiles de rendimiento que funciona como pilas de llamadas para arquitecturas de microservicios y en la nube.

Azure Monitor proporciona dos experiencias para consumir datos de seguimiento distribuido: la vista de diagnósticos de la transacción para una sola transacción o solicitud y la vista de mapa de aplicación para mostrar cómo interactúan los sistemas.

Application Insights puede supervisar cada componente por separado y detectar qué componente es responsable de errores o degradación del rendimiento mediante la correlación de telemetría distribuida. En este artículo se explica el modelo de datos, las técnicas de propagación de contexto, los protocolos y la implementación de tácticas de correlación en diferentes lenguajes y plataformas que utiliza Application Insights.

Habilitación del seguimiento distribuido

Para habilitar el seguimiento distribuido de una aplicación, agregue el agente, el SDK o la biblioteca adecuados a cada servicio en función de su lenguaje de programación.

Activación mediante Application Insights a través de la instrumentación automática o SDK

Los SDK o agentes de Application Insights para .NET, .NET Core, Java, Node.js y JavaScript admiten el seguimiento distribuido de forma nativa. Hay instrucciones para instalar y configurar cada SDK de Application Insights para:

Con el SDK de Application Insights instalado y configurado correctamente, los auto colectores de dependencias del SDK recopilan automáticamente información de rastreo de los marcos, bibliotecas y tecnologías más populares. La lista completa de tecnologías compatibles está disponible en la Documentación de la recolección automática de dependencias.

También se puede realizar un seguimiento manual de cualquier tecnología con una llamada a TrackDependency en TelemetryClient.

Habilitación mediante OpenTelemetry

Application Insights admite ahora el seguimiento distribuido mediante OpenTelemetry. OpenTelemetry proporciona una instrumentación neutral del proveedor para enviar seguimientos, métricas y registros a Application Insights. Inicialmente, la comunidad de OpenTelemetry se hizo cargo del seguimiento distribuido. Las métricas y los registros todavía están en proceso.

Una historia de observabilidad completa incluye los tres pilares. Compruebe el estado de nuestras ofertas basadas en OpenTelemetry de Azure Monitor para ver el estado más reciente sobre qué se incluye, qué ofertas están disponibles con carácter general y las opciones de soporte técnico.

Las páginas siguientes constan de una guía de cada lenguaje para habilitar y configurar las ofertas basadas en OpenTelemetry de Microsoft. Lo importante es que compartimos la funcionalidad y las limitaciones disponibles de cada oferta para que pueda determinar si OpenTelemetry es adecuado para su proyecto.

Habilitación mediante OpenCensus

Además de los SDK de Application Insights, Application Insights también admite el seguimiento distribuido mediante OpenCensus. OpenCensus es una distribución de bibliotecas de código abierto e independiente del proveedor que proporciona recopilación de métricas y seguimiento distribuido para los servicios. También permite a la comunidad de código abierto habilitar el seguimiento distribuido con tecnologías conocidas como Redis, Memcached o MongoDB. Microsoft colabora en OpenCensus junto con varios otros asociados de supervisión y en la nube.

Para obtener más información sobre OpenCensus para Python, vea Configuración de Azure Monitor para una aplicación Python.

El sitio web de OpenCensus mantiene la documentación de referencia de la API para Python y Go, así como algunas guías sobre cómo usar OpenCensus.

Modelo de datos de correlación de telemetría

Application Insights define el modelo de datos para la correlación de telemetría distribuida. Para asociar la telemetría con una operación lógica, todos los elementos de telemetría tienen el campo de contexto denominado operation_Id. Cada elemento de telemetría del seguimiento distribuido comparte este identificador. De este modo, aun si pierde telemetría desde una sola capa, se pueden seguir asociando los datos telemétricos notificados por otros componentes.

Habitualmente, una operación lógica distribuida consta de un conjunto de operaciones más pequeñas, que son solicitudes que se procesan en uno de los componentes. La telemetría de solicitud define estas operaciones. Cada elemento de telemetría de solicitudes cuenta con su propio id, que lo identifica de manera global e inequívoca. Además, todos los elementos de telemetría (como los seguimientos y las excepciones) que están asociados a la solicitud deben establecer operation_parentId en el valor de la solicitud id.

La telemetría de dependencias representa todas las operaciones salientes, como una llamada HTTP a otro componente. También define su propio id, que es globalmente único. La telemetría de solicitudes, que se inicia mediante esta llamada de dependencia, utiliza este id como su operation_parentId.

Puede crear una vista de la operación lógica distribuida usando operation_Id, operation_parentId y request.id con dependency.id. Estos campos también definen el orden de causalidad de las llamadas de telemetría.

En el entorno de los microservicios, los seguimientos de componentes pueden ir a distintos elementos de almacenamiento. Cada componente puede tener su propia cadena de conexión en Application Insights. Para obtener la telemetría de la operación lógica, Application Insights consulta los datos de cada elemento de almacenamiento.

Si el número de elementos de almacenamiento es grande, necesita una pista para saber dónde debe mirar a continuación. El modelo de datos de Application Insights define dos campos, request.source y dependency.target, para solucionar este problema. El primer campo identifica el componente que inició la solicitud de dependencia. El segundo campo identifica qué componente devolvió la respuesta de la llamada de dependencia.

Para obtener información sobre cómo realizar consultas desde varias instancias dispares mediante la expresión de consulta app, consulte la expresión app() en la consulta de Azure Monitor.

Ejemplo

Veamos un ejemplo. Una aplicación llamada Stock Prices muestra el precio de mercado actual de una acción mediante una API externa denominada Stock. La aplicación Stock Prices tiene una página llamada Stock page que el explorador web del cliente abre mediante GET /Home/Stock. La aplicación consulta la API Stick mediante el uso de una llamada HTTP GET /api/stock/value.

Puede analizar la telemetría resultante ejecutando una consulta:

(requests | union dependencies | union pageViews)
| where operation_Id == "STYz"
| project timestamp, itemType, name, id, operation_ParentId, operation_Id

En los resultados, todos los elementos de telemetría comparten la raíz operation_Id. Cuando se realiza una llamada Ajax desde la página, se asigna un nuevo identificador único (qJSXU) a la telemetría de dependencia y el identificador de pageView se usa como operation_ParentId. La solicitud al servidor utiliza después el identificador de Ajax como operation_ParentId.

itemType name id operation_ParentId operation_Id
pageView Stock page STYz STYz
dependency GET /Home/Stock qJSXU STYz STYz
solicitud GET Home/Stock KqKwlrSt9PA= qJSXU STYz
dependency GET /api/stock/value bBrf2L7mm2g= KqKwlrSt9PA= STYz

Cuando se realiza la llamada GET /api/stock/value a un servicio externo, necesita conocer la identidad de ese servidor para poder establecer el campo dependency.target correctamente. Si el servicio externo no admite la supervisión, target se establece en el nombre de host del servicio. Un ejemplo es stock-prices-api.com. Pero si ese servicio se identifica devolviendo un encabezado HTTP predefinido, target contiene la identidad de servicio que permite a Application Insights crear un seguimiento distribuido consultando la telemetría de ese servicio.

Encabezados de correlación mediante W3C Trace-Context

Application Insights está realizando la transición a W3C Trace-Context, que define:

  • traceparent: lleva el identificador único global de la operación y un identificador único de la llamada.
  • tracestate: lleva el contexto de seguimiento específico del sistema.

La versión más reciente del SDK de Application Insights es compatible con el protocolo de Trace-Context, pero es posible que tenga que usarlo. (Se mantiene la compatibilidad con el antiguo protocolo de correlación compatible con el SDK de Application Insights).

El protocolo HTTP de correlación , también denominado Request-Id, está entrando en desuso. Este protocolo define dos encabezados:

  • Request-Id: lleva el identificador único global de la llamada.
  • Correlation-Context: lleva la colección de pares nombre-valor de las propiedades del seguimiento distribuido.

Application Insights también define la extensión del protocolo HTTP de correlación. Usa pares nombre-valor Request-Context para propagar la colección de propiedades utilizadas por el autor o el destinatario de la llamada. El SDK de Application Insights usa este encabezado para establecer los campos dependency.target y request.source.

W3C Trace-Context y los modelos de datos de Application Insights se asignan de la siguiente manera:

Application Insights W3C TraceContext
Id de Request y Dependency parent-id
Operation_Id trace-id
Operation_ParentId parent-id del intervalo primario de este intervalo. Este campo debe estar vacío si es un intervalo raíz.

Para más información, consulte Modelo de datos de telemetría de Application Insights.

Habilitación de la compatibilidad con el seguimiento distribuido de W3C para aplicaciones .NET

El seguimiento distribuido basado en W3C Trace-Context está habilitado de forma predeterminada en todos los SDK de .NET Framework/.NET Core recientes, junto con la compatibilidad con versiones anteriores con el protocolo heredado de Request-Id.

Habilitar la compatibilidad con el seguimiento distribuido de W3C para aplicaciones de Java

Agente de Java 3.0

El agente de Java 3.0 es compatible con W3C (listo para usar) y no se necesita configuración adicional.

SDK de Java

  • Configuración de entrada

    En el caso de las aplicaciones de Java EE, agregue lo siguiente a la etiqueta <TelemetryModules> en el archivo ApplicationInsights.xml:

    <Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule>
       <Param name = "W3CEnabled" value ="true"/>
       <Param name ="enableW3CBackCompat" value = "true" />
    </Add>
    

    En el caso de las aplicaciones de Spring Boot, agregue estas propiedades:

    • azure.application-insights.web.enable-W3C=true
    • azure.application-insights.web.enable-W3C-backcompat-mode=true
  • Configuración de salida

    Agregue el código siguiente al archivo AI-Agent.xml:

    <Instrumentation>
      <BuiltIn enabled="true">
        <HTTP enabled="true" W3C="true" enableW3CBackCompat="true"/>
      </BuiltIn>
    </Instrumentation>
    

    Nota

    El modo de compatibilidad con versiones anteriores está habilitado de forma predeterminada, por lo que el enableW3CBackCompat parámetro es opcional. Solo debe utilizarlo cuando desee desactivar la compatibilidad con versiones anteriores.

    Lo ideal sería desactivar este modo cuando todos los servicios se hayan actualizado a la versión más reciente de los SDK compatibles con el protocolo W3C. Se recomienda encarecidamente que cambie a estos SDK más recientes lo antes posible.

Es importante asegurarse de que las configuraciones de entrada y salida sean exactamente iguales.

Habilitación de la compatibilidad con el seguimiento distribuido de W3C para aplicaciones web

Esta característica está habilitada de forma predeterminada para JavaScript y los encabezados se incluyen automáticamente cuando el dominio de la página de hospedaje es el mismo que el dominio al que se envían las solicitudes (por ejemplo, la página de hospedaje es example.com y las solicitudes de Ajax se envían a example.com). Para cambiar el modo de seguimiento distribuido, use el campo de configuración distributedTracingMode. AI_AND_W3C se proporciona de forma predeterminada para la compatibilidad con cualquier servicio heredado instrumentado por Application Insights.

Si las peticiones XMLHttpRequest o Fetch Ajax se envían a un host de dominio diferente, incluidos los subdominios, los encabezados de correlación no se incluyen por defecto. Para habilitar esta característica, establezca el campo de configuraciónenableCorsCorrelation en true. Si establece enableCorsCorrelation en true, todas las solicitudes XMLHttpRequest y Fetch Ajax incluyen los encabezados de correlación. Como resultado, si la aplicación en el servidor que está siendo llamada no admite el encabezado traceparent, la solicitud podría fallar, dependiendo de si el navegador / versión puede validar la solicitud basándose en qué encabezados acepta el servidor. Puede usar el correlationHeaderExcludedDomains campo de configuración para excluir el dominio del servidor de la inserción de encabezados de correlación entre componentes. Por ejemplo, puede usar correlationHeaderExcludedDomains: ['*.auth0.com'] para excluir los encabezados de correlación de las solicitudes enviadas al proveedor de identidades de Auth0.

Importante

Para ver todas las configuraciones necesarias para habilitar la correlación, consulte la documentación Correlación de JavaScript.

Correlación de los datos de telemetría en OpenCensus Python

OpenCensus Python admite W3C Trace-Context sin requerir configuración adicional.

Para obtener una referencia, puede encontrar el modelo de datos de OpenCensus en esta página de GitHub.

Correlación de las solicitudes entrantes

OpenCensus Python correlaciona los encabezados de Trace-Context de W3C de las solicitudes entrantes a los intervalos que se generan a partir de las solicitudes. OpenCensus lo hace automáticamente con integraciones para los marcos de aplicaciones web populares: Flask, Django y Pyramid. Solo tiene que rellenar los encabezados de Trace-Context de W3C con el formato correcto y enviarlos con la solicitud.

Vea esta aplicación de Flask de ejemplo. Instale Flask, OpenCensus y las extensiones de Flask y Azure.


pip install flask opencensus opencensus-ext-flask opencensus-ext-azure

Tiene que agregar la cadena de conexión de Application Insights a la variable de entorno.

APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>

Aplicación de Flask de ejemplo

from flask import Flask
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
from opencensus.trace.samplers import ProbabilitySampler

app = Flask(__name__)
middleware = FlaskMiddleware(
    app,
    exporter=AzureExporter(
        connection_string='<appinsights-connection-string>', # or set environment variable APPLICATION_INSIGHTS_CONNECTION_STRING
    ), 
    sampler=ProbabilitySampler(rate=1.0),
)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='localhost', port=8080, threaded=True)

Este código ejecuta una aplicación de Flask de ejemplo en la máquina local, escuchando el puerto 8080. Para correlacionar el contexto de seguimiento, se envía una solicitud al punto de conexión. En este ejemplo, se puede usar un comando curl:

curl --header "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" localhost:8080

Al examinar el formato de encabezado de Trace-Context, se deriva la información siguiente:

version: 00

trace-id: 4bf92f3577b34da6a3ce929d0e0e4736

parent-id/span-id: 00f067aa0ba902b7

trace-flags: 01

Si se echa un vistazo a la entrada de solicitud que se envió a Azure Monitor, se pueden ver los campos rellenados con la información de encabezado de seguimiento. Puede encontrar estos datos en Registros (Analytics) en el recurso Application Insights de Azure Monitor.

Screenshot that shows Request telemetry in Logs (Analytics).

El campo id está en formato <trace-id>.<span-id>, donde trace-id se toma del encabezado de seguimiento que se pasó en la solicitud y span-id es una matriz de 8 bytes generada para este intervalo.

El campo operation_ParentId tiene el formato <trace-id>.<parent-id>, donde tanto trace-id como parent-id se toman del encabezado de seguimiento que se pasó en la solicitud.

Correlación de registros

Python de OpenCensus permite correlacionar registros al agregar un identificador de seguimiento, un identificador de intervalo y una marca de muestreo para escribir registros. Estos atributos se agregan al instalar la integración de registro de OpenCensus. Los atributos siguientes se agregan a objetos de Python LogRecord: traceId, spanId y traceSampled (aplicables solo en los registradores que se crean después de la integración).

Instale la integración de registro de OpenCensus:

python -m pip install opencensus-ext-logging

Aplicación de ejemplo

import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['logging'])
logging.basicConfig(format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning('Before the span')
with tracer.span(name='hello'):
    logger.warning('In the span')
logger.warning('After the span')

Cuando se ejecuta este código, se imprime lo siguiente en la consola:

2019-10-17 11:25:59,382 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 Before the span
2019-10-17 11:25:59,384 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=70da28f5a4831014 In the span
2019-10-17 11:25:59,385 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 After the span

Observe que hay un spanId presente para el mensaje de registro que se encuentra dentro del intervalo. Es el mismo spanId perteneciente al intervalo denominado hello.

Puede exportar los datos de registro mediante AzureLogHandler. Para obtener más información, consulte Configuración de Azure Monitor para una aplicación Python.

También podemos pasar información de seguimiento de un componente a otro para una correlación adecuada. Por ejemplo, considere un escenario en el que hay dos componentes module1 y module2. El módulo 1 llama a funciones del módulo 2. Para obtener registros de module1 y module2 en un solo seguimiento, podemos usar el siguiente enfoque:

# module1.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer
from module_2 import function_1

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning("Before the span")

with tracer.span(name="hello"):
    logger.warning("In the span")
    function_1(logger, tracer)
logger.warning("After the span")
# module_2.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
logger = logging.getLogger(__name__)
tracer = Tracer(sampler=AlwaysOnSampler())


def function_1(logger=logger, parent_tracer=None):
    if parent_tracer is not None:
        tracer = Tracer(
            span_context=parent_tracer.span_context,
            sampler=AlwaysOnSampler(),
        )
    else:
        tracer = Tracer(sampler=AlwaysOnSampler())

    with tracer.span("function_1"):
        logger.info("In function_1")

Correlación de telemetría en .NET

La correlación se controla de forma predeterminada al incorporar una aplicación. No se requieren acciones especiales.

El runtime de .NET admite la distribución con la ayuda de Activity y DiagnosticSource.

El SDK de .NET de Application Insights usa DiagnosticSource y Activity para recopilar y correlacionar la telemetría.

Correlación de telemetría en Java

El agente de Java admite la correlación automática de telemetría. Rellena automáticamente el valor de operation_id en todos los elementos de telemetría (como seguimientos, excepciones y eventos personalizados) que se emiten en el ámbito de una solicitud. También propaga los encabezados de correlación (descritos anteriormente) de las llamadas de un servicio de a otro mediante HTTP si el agente del SDK de Java está configurado.

Nota

El agente de Java de Application Insights recopila automáticamente las solicitudes y dependencias de JMS, Kafka, Netty/Webflux, etc. En el caso del SDK de Java, la característica de correlación solamente admite las llamadas realizadas mediante Apache HttpClient. No se admite la propagación automática de contextos entre tecnologías de mensajería (como Kafka, RabbitMQ y Azure Service Bus) en el SDK.

Para recopilar la telemetría personalizada, debe instrumentar la aplicación con el SDK de Java 2.6.

Nombres de roles

Es posible que quiera personalizar el modo en que los nombres de los componentes aparecen en el mapa de aplicación. Para ello, puede establecer manualmente el valor de cloud_RoleName a través de una de las acciones siguientes:

  • Para Java de Application Insights, establezca el nombre del rol de nube de la siguiente manera:

    {
      "role": {
        "name": "my cloud role name"
      }
    }
    

    También puede establecer el nombre de rol en la nube mediante la variable de entorno APPLICATIONINSIGHTS_ROLE_NAME.

  • Con el SDK 2.5.0 de Java de Application Insights y versiones posteriores, puede especificar el cloud_RoleName si agrega <RoleName> al archivo ApplicationInsights.xml:

    Screenshot that shows Application Insights overview and connection string.

    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
       <ConnectionString>InstrumentationKey=00000000-0000-0000-0000-000000000000</ConnectionString>
       <RoleName>** Your role name **</RoleName>
       ...
    </ApplicationInsights>
    
  • Si usa Spring Boot con el código de inicio de Spring Boot de Application Insights, establezca el nombre personalizado de la aplicación en el archivo application.properties:

    spring.application.name=<name-of-app>

También puede establecer el nombre de rol en la nube mediante la variable de entorno o una propiedad del sistema. Consulte Configuración del nombre del rol en la nube para obtener más información.

Pasos siguientes