O que é rastreamento distribuído e correlação de telemetria?

Nota

A documentação a seguir depende da API clássica do Application Insights. O plano de longo prazo para o Application Insights é coletar dados usando OpenTelemetry. Para obter mais informações, consulte Habilitar o Azure Monitor OpenTelemetry para aplicativos .NET, Node.js, Python e Java.

As arquiteturas modernas de nuvem e microsserviços permitiram serviços simples e implantáveis de forma independente que reduzem custos e, ao mesmo tempo, aumentam a disponibilidade e a taxa de transferência. No entanto, tornou os sistemas gerais mais difíceis de raciocinar e depurar. O rastreamento distribuído resolve esse problema fornecendo um criador de perfil de desempenho que funciona como pilhas de chamadas para arquiteturas de nuvem e microsserviços.

O Azure Monitor fornece duas experiências para consumir dados de rastreamento distribuídos: a exibição de diagnóstico de transação para uma única transação/solicitação e a exibição de mapa do aplicativo para mostrar como os sistemas interagem.

O Application Insights pode monitorar cada componente separadamente e detetar qual componente é responsável por falhas ou degradação do desempenho usando a correlação de telemetria distribuída. Este artigo explica o modelo de dados, técnicas de propagação de contexto, protocolos e implementação de táticas de correlação em diferentes linguagens e plataformas usadas pelo Application Insights.

Habilitar rastreamento distribuído

Para habilitar o rastreamento distribuído para um aplicativo, adicione o agente, SDK ou biblioteca corretos a cada serviço com base em sua linguagem de programação.

Habilite por meio do Application Insights por meio de autoinstrumentação ou SDKs

Os agentes e SDKs do Application Insights para .NET, .NET Core, Java, Node.js e JavaScript suportam rastreamento distribuído nativamente. As instruções para instalar e configurar cada SDK do Application Insights estão disponíveis para:

Com o SDK adequado do Application Insights instalado e configurado, as informações de rastreamento são coletadas automaticamente para estruturas, bibliotecas e tecnologias populares pelos autocoletores de dependência do SDK. A lista completa de tecnologias suportadas está disponível na documentação de coleta automática de dependência.

Qualquer tecnologia também pode ser rastreada manualmente com uma chamada para TrackDependency no TelemetryClient.

Ativar via OpenTelemetry

O Application Insights agora oferece suporte ao rastreamento distribuído por meio do OpenTelemetry. O OpenTelemetry fornece uma instrumentação neutra do fornecedor para enviar rastreamentos, métricas e logs para o Application Insights. Inicialmente, a comunidade OpenTelemetry assumiu o rastreamento distribuído. Métricas e logs ainda estão em andamento.

Uma história completa de observabilidade inclui os três pilares. Verifique o status de nossas ofertas baseadas em OpenTelemetria do Azure Monitor para ver o status mais recente sobre o que está incluído, quais ofertas estão geralmente disponíveis e opções de suporte.

As páginas a seguir consistem em orientações de idioma por idioma para habilitar e configurar as ofertas baseadas em OpenTelemetry da Microsoft. É importante ressaltar que compartilhamos a funcionalidade disponível e as limitações de cada oferta para que você possa determinar se o OpenTelemetry é adequado para seu projeto.

Ativar via OpenCensus

Além dos SDKs do Application Insights, o Application Insights também oferece suporte ao rastreamento distribuído por meio do OpenCensus. O OpenCensus é uma distribuição única de bibliotecas de código aberto, independente do fornecedor, para fornecer coleta de métricas e rastreamento distribuído para serviços. Ele também permite que a comunidade de código aberto habilite o rastreamento distribuído com tecnologias populares como Redis, Memcached ou MongoDB. A Microsoft colabora no OpenCensus com vários outros parceiros de monitoramento e nuvem.

Para obter mais informações sobre o OpenCensus para Python, consulte Configurar o Azure Monitor para seu aplicativo Python.

O site OpenCensus mantém documentação de referência de API para Python, Go e vários guias para usar o OpenCensus.

Modelo de dados para correlação de telemetria

O Application Insights define um modelo de dados para correlação de telemetria distribuída. Para associar a telemetria a uma operação lógica, cada item de telemetria tem um campo de contexto chamado operation_Id. Cada item de telemetria no rastreamento distribuído compartilha esse identificador. Portanto, mesmo que você perca a telemetria de uma única camada, ainda poderá associar a telemetria relatada por outros componentes.

Uma operação lógica distribuída normalmente consiste em um conjunto de operações menores que são solicitações processadas por um dos componentes. A telemetria de solicitação define essas operações. Cada item de telemetria de solicitação tem seu próprio id que o identifica de forma única e global. E todos os itens de telemetria (como rastreamentos e exceções) associados à solicitação devem definir o operation_parentId valor da solicitação id.

A telemetria de dependência representa cada operação de saída, como uma chamada HTTP para outro componente. Ele também define o seu próprio id que é globalmente único. A telemetria de solicitação, iniciada por essa chamada de dependência, usa isso id como seu operation_parentIdarquivo .

Você pode criar uma exibição da operação lógica distribuída usando operation_Id, operation_parentIde request.id com dependency.id. Esses campos também definem a ordem de causalidade das chamadas de telemetria.

Em um ambiente de microsserviços, os rastreamentos de componentes podem ir para diferentes itens de armazenamento. Cada componente pode ter sua própria cadeia de conexão no Application Insights. Para obter telemetria para a operação lógica, o Application Insights consulta dados de cada item de armazenamento.

Quando o número de itens de armazenamento é grande, você precisa de uma dica sobre onde procurar em seguida. O modelo de dados do Application Insights define dois campos para resolver esse problema: request.source e dependency.target. O primeiro campo identifica o componente que iniciou a solicitação de dependência. O segundo campo identifica qual componente retornou a resposta da chamada de dependência.

Para obter informações sobre como consultar várias instâncias diferentes usando a app expressão de consulta, consulte expressão app() na consulta do Azure Monitor.

Exemplo

Vamos ver um exemplo. Um aplicativo chamado Stock Prices mostra o preço de mercado atual de uma ação usando uma API externa chamada Stock. O aplicativo Preços de Ações tem uma página chamada Página de Estoque que o navegador da Web do cliente abre usando GET /Home/Stock. O aplicativo consulta a API de estoque usando a chamada GET /api/stock/valueHTTP .

Você pode analisar a telemetria resultante executando uma consulta:

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

Nos resultados, todos os itens de telemetria compartilham a raiz operation_Id. Quando uma chamada Ajax é feita a partir da página, um novo ID exclusivo (qJSXU) é atribuído à telemetria de dependência e o ID do pageView é usado como operation_ParentId. Em seguida, a solicitação do servidor usa o ID do Ajax como operation_ParentId.

Tipo de item nome ID operation_ParentId operation_Id
visualização de página Página de stock STYz STYz
dependência GET /Home/Stock qJSXU STYz STYz
pedido GET Home/Stock KqKwlrSt9PA= qJSXU STYz
dependência GET /api/stock/valor bBrf2L7mm2g= KqKwlrSt9PA= STYz

Quando a chamada GET /api/stock/value é feita para um serviço externo, você precisa saber a identidade desse servidor para poder definir o dependency.target campo adequadamente. Quando o serviço externo não oferece suporte ao monitoramento, target é definido como o nome do host do serviço. Um exemplo é stock-prices-api.com. Mas se o serviço se identificar retornando um cabeçalho HTTP predefinido, target conterá a identidade do serviço que permite que o Application Insights crie um rastreamento distribuído consultando a telemetria desse serviço.

Cabeçalhos de correlação usando W3C TraceContext

O Application Insights está em transição para o W3C Trace-Context, que define:

  • traceparent: Carrega o ID de operação globalmente exclusivo e o identificador exclusivo da chamada.
  • tracestate: Carrega o contexto de rastreamento específico do sistema.

A versão mais recente do SDK do Application Insights suporta o protocolo Trace-Context, mas talvez seja necessário optar por ele. (A compatibilidade com versões anteriores do protocolo de correlação anterior suportado pelo SDK do Application Insights é mantida.)

O protocolo HTTP de correlação, também chamado de Request-Id, está sendo preterido. Este protocolo define dois cabeçalhos:

  • Request-Id: Carrega o ID globalmente exclusivo da chamada.
  • Correlation-Context: Carrega a coleção de pares nome-valor das propriedades de rastreamento distribuído.

O Application Insights também define a extensão para o protocolo HTTP de correlação. Ele usa Request-Context pares nome-valor para propagar a coleção de propriedades usadas pelo chamador ou destinatário imediato. O SDK do Application Insights usa esse cabeçalho para definir os dependency.target campos e request.source .

Os modelos de dados do W3C Trace-Context e Application Insights são mapeados da seguinte maneira:

Application Insights W3C TraceContext
Id de Request e Dependency identificação dos pais
Operation_Id Identificação-Rastreio
Operation_ParentId pai-id da extensão pai desta extensão. Este campo deve estar vazio se for uma extensão de raiz.

Para obter mais informações, consulte Modelo de dados de telemetria do Application Insights.

Habilitar o suporte de rastreamento distribuído W3C para aplicativos .NET

O rastreamento distribuído baseado em TraceContext do W3C é habilitado por padrão em todos os SDKs recentes do .NET Framework/.NET Core, juntamente com a compatibilidade com versões anteriores do protocolo Request-Id herdado.

Ativar o suporte de rastreamento distribuído W3C para aplicativos Java

Agente Java 3.0

O agente Java 3.0 suporta W3C pronto para uso e nenhuma configuração adicional é necessária.

SDK Java

  • Configuração de entrada

    Para aplicativos Java EE, adicione o seguinte código à <TelemetryModules> tag no ApplicationInsights.xml:

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

    Para aplicativos Spring Boot, adicione estas propriedades:

    • azure.application-insights.web.enable-W3C=true
    • azure.application-insights.web.enable-W3C-backcompat-mode=true
  • Configuração de saída

    Adicione o seguinte código a AI-Agent.xml:

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

    Nota

    O modo de compatibilidade com versões anteriores está habilitado por padrão e o enableW3CBackCompat parâmetro é opcional. Use-o somente quando quiser desativar a compatibilidade com versões anteriores.

    Idealmente, você desativará esse modo quando todos os seus serviços forem atualizados para versões mais recentes de SDKs que suportam o protocolo W3C. É altamente recomendável que você mude para esses SDKs mais recentes o mais rápido possível.

É importante certificar-se de que as configurações de entrada e saída são exatamente as mesmas.

Ativar o suporte de rastreamento distribuído W3C para aplicativos Web

Este recurso é ativado por padrão para JavaScript e os cabeçalhos são incluídos automaticamente quando o domínio da página de hospedagem é o mesmo que o domínio para o qual as solicitações são enviadas (por exemplo, a página de hospedagem é example.com e as solicitações Ajax são enviadas para example.com). Para alterar o modo de rastreamento distribuído, use o distributedTracingMode campo de configuração. AI_AND_W3C é fornecido por padrão para compatibilidade com versões anteriores com quaisquer serviços herdados instrumentados pelo Application Insights.

Se as solicitações XMLHttpRequest ou Fetch Ajax forem enviadas para um host de domínio diferente, incluindo subdomínios, os cabeçalhos de correlação não serão incluídos por padrão. Para habilitar esse recurso, defina o enableCorsCorrelation campo de configuração como true. Se você definir enableCorsCorrelation como true, todas as solicitações XMLHttpRequest e Fetch Ajax incluirão os cabeçalhos de correlação. Como resultado, se o aplicativo no servidor que está sendo chamado não suportar o traceparent cabeçalho, a solicitação pode falhar, dependendo se o navegador / versão pode validar a solicitação com base em quais cabeçalhos o servidor aceita. Você pode usar o correlationHeaderExcludedDomains campo de configuração para excluir o domínio do servidor da injeção de cabeçalho de correlação entre componentes. Por exemplo, você pode usar correlationHeaderExcludedDomains: ['*.auth0.com'] para excluir cabeçalhos de correlação de solicitações enviadas ao provedor de identidade Auth0.

Importante

Para ver todas as configurações necessárias para habilitar a correlação, consulte a documentação de correlação JavaScript.

Correlação de telemetria em OpenCensus Python

O OpenCensus Python suporta W3C Trace-Context sem exigir configuração extra.

Para uma referência, você pode encontrar o modelo de dados OpenCensus nesta página do GitHub.

Correlação de solicitações recebidas

O OpenCensus Python correlaciona cabeçalhos W3C Trace-Context de solicitações de entrada com as extensões geradas a partir das próprias solicitações. O OpenCensus se correlaciona automaticamente com integrações para essas estruturas populares de aplicações web: Flask, Django e Pyramid. Você só precisa preencher os cabeçalhos W3C Trace-Context com o formato correto e enviá-los com a solicitação.

Explore este exemplo de aplicação Flask. Instale Flask, OpenCensus e as extensões para Flask e Azure.


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

Você precisa adicionar sua cadeia de conexão do Application Insights à variável de ambiente.

APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>

Aplicação do frasco de amostra

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 executa um aplicativo Flask de exemplo em sua máquina local, ouvindo a porta 8080. Para correlacionar o contexto de rastreamento, envie uma solicitação para o ponto de extremidade. Neste exemplo, você pode usar um curl comando:

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

Ao examinar o formato de cabeçalho Trace-Context, você pode obter as seguintes informações:

version: 00

trace-id: 4bf92f3577b34da6a3ce929d0e0e4736

parent-id/span-id: 00f067aa0ba902b7

trace-flags: 01

Se você examinar a entrada de solicitação que foi enviada ao Azure Monitor, poderá ver os campos preenchidos com as informações de cabeçalho de rastreamento. Você pode encontrar os dados em Logs (Analytics) no recurso Azure Monitor Application Insights.

Screenshot that shows Request telemetry in Logs (Analytics).

O id campo está no formato <trace-id>.<span-id>, onde trace-id é retirado do cabeçalho de rastreamento que foi passado na solicitação e span-id é uma matriz de 8 bytes gerada para essa extensão.

O operation_ParentId campo está no formato <trace-id>.<parent-id>, onde ambos trace-id e parent-id são retirados do cabeçalho de rastreamento que foi passado na solicitação.

Correlação de registos

O OpenCensus Python permite correlacionar logs adicionando um ID de rastreamento, um ID de span e um sinalizador de amostragem aos registros de log. Você adiciona esses atributos instalando a integração de log do OpenCensus. Os seguintes atributos são adicionados aos objetos Python LogRecord : traceId, spanIde traceSampled (aplicável somente para registradores criados após a integração).

Instale a integração de registro do OpenCensus:

python -m pip install opencensus-ext-logging

Aplicação de exemplo

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')

Quando esse código é executado, o seguinte é impresso no console:

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 há um spanId presente para a mensagem de log que está dentro da extensão. O spanId é o mesmo que pertence ao espaço chamado hello.

Você pode exportar os dados de log usando AzureLogHandler. Para obter mais informações, consulte Configurar o Azure Monitor para seu aplicativo Python.

Também podemos passar informações de rastreamento de um componente para outro para uma correlação adequada. Por exemplo, considere um cenário em que há dois componentes module1 e module2. O módulo 1 chama funções no módulo 2. Para obter logs de ambos module1 e module2 em um único rastreamento, podemos usar a seguinte abordagem:

# 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")

Correlação de telemetria no .NET

A correlação é tratada por padrão ao integrar um aplicativo. Não são necessárias ações especiais.

O tempo de execução do .NET oferece suporte distribuído com a ajuda de Activity e DiagnosticSource

O SDK do .NET do Application Insights usa DiagnosticSource e Activity para coletar e correlacionar telemetria.

Correlação de telemetria em Java

O agente Java suporta correlação automática de telemetria. Ele preenche automaticamente toda a telemetria operation_id (como rastreamentos, exceções e eventos personalizados) emitida dentro do escopo de uma solicitação. Ele também propaga os cabeçalhos de correlação descritos anteriormente para chamadas de serviço a serviço via HTTP, se o agente Java SDK estiver configurado.

Nota

O agente Java do Application Insights coleta automaticamente solicitações e dependências para JMS, Kafka, Netty/Webflux e muito mais. Para Java SDK, somente chamadas feitas via Apache HttpClient são suportadas para o recurso de correlação. A propagação automática de contexto entre tecnologias de mensagens como Kafka, RabbitMQ e Azure Service Bus não é suportada no SDK.

Para coletar telemetria personalizada, você precisa instrumentar o aplicativo com Java 2.6 SDK.

Nomes de funções

Talvez você queira personalizar a maneira como os nomes dos componentes são exibidos no Mapa do Aplicativo. Para fazer isso, você pode definir cloud_RoleName manualmente executando uma das seguintes ações:

  • Para Java do Application Insights, defina o nome da função de nuvem da seguinte maneira:

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

    Você também pode definir o nome da função de nuvem usando a variável APPLICATIONINSIGHTS_ROLE_NAMEde ambiente .

  • Com o Application Insights Java SDK 2.5.0 e posterior, você pode especificar cloud_RoleName adicionando ao seu arquivo ApplicationInsights.xml<RoleName>:

    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>
    
  • Se você usar o Spring Boot com o Application Insights Spring Boot Starter, defina seu nome personalizado para o aplicativo no arquivo application.properties :

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

Você também pode definir o nome da função de nuvem por meio da variável de ambiente ou da propriedade do sistema. Consulte Configurando o nome da função de nuvem para obter detalhes.

Próximos passos