Skip to main content
Onde uma requisição lenta realmente gasta seu tempo? Uma requisição leva quatro segundos, mas sua aplicação web parece normal e o banco de dados está tranquilo. Uma única requisição pode se autenticar em um serviço, carregar dados de uma API interna, enfileirar um job em background e chamar a API de pagamento de terceiros antes que a resposta volte. Quando ela fica lenta ou falha, a causa costuma estar em um serviço diferente daquele que apresentou o sintoma primeiro. O distributed tracing permite que você siga essa única requisição por essas fronteiras. O AppSignal reúne o trabalho de todos os serviços em um único trace, para que você veja o percurso completo antes de começar a comparar timestamps entre aplicações.

O que é distributed tracing?

Quando cada serviço reporta por conta própria, você consegue ver que uma web action está lenta, mas não que um serviço de estoque mais adiante na cadeia de chamadas causou isso. No AppSignal, esses serviços podem estar em aplicações ou namespaces separados, então seguir uma requisição significa abrir cada um deles e alinhar os timestamps. O distributed tracing mantém esses serviços conectados. Conforme uma requisição se move de um serviço para o próximo, cada serviço marca seu trabalho com o mesmo ID de trace e registra qual span o chamou. O AppSignal usa esses dados para reconstruir o caminho completo da requisição por todos os serviços que participaram. Com um trace distribuído, você pode:
  • Seguir uma requisição do seu ponto de entrada por todos os serviços alcançados.
  • Ver para onde o tempo foi, mesmo quando a parte lenta roda em um serviço ou aplicação diferente.
  • Descobrir em qual serviço um erro começou, não apenas onde ele apareceu.

Spans, traces e serviços

O AppSignal apresenta um trace distribuído como três blocos de construção.
  • Span: uma única unidade de trabalho, como uma requisição HTTP recebida, uma query de banco de dados, uma chamada a outro serviço, ou um bloco de código que você mesmo instrumenta. Um span tem um nome, uma duração e atributos, e registra o span que o iniciou. Spans são a menor coisa da qual um trace é feito.
  • Trace: todos os spans que pertencem a uma operação de ponta a ponta. Como cada span conhece seu span pai, os spans em um trace formam uma árvore que descreve a requisição do início ao fim.
  • Serviço: um componente nomeado que participa de um trace, como uma aplicação web, um worker em background ou uma API interna. Você nomeia um serviço com a opção service_name (ou a variável de ambiente APPSIGNAL_SERVICE_NAME), e o AppSignal usa esse nome para diferenciar serviços dentro de um trace. Um único trace geralmente atravessa vários serviços, e esses serviços podem reportar para aplicações AppSignal diferentes.
Os spans de um trace organizados como uma árvore, do span raiz até os spans pai e filho

Os spans de um trace formam uma árvore. Cada span registra o span que o iniciou, a partir do span raiz.

O AppSignal constrói traces sobre o OpenTelemetry, então esses termos seguem os do OpenTelemetry. O AppSignal agrupa cada trace em uma action e um namespace, com base no endpoint, job ou task ao qual o trace pertence.
Dentro do AppSignal, um trace é um tipo de sample: o registro detalhado de uma requisição, armazenado para que você possa abri-lo e lê-lo span por span. O AppSignal deriva suas métricas de performance, como tempo de resposta e throughput, a partir desses traces, então um gráfico de performance e um único trace são duas visões dos mesmos dados.

Disponibilidade e configuração

Antes de investigar uma requisição por vários serviços, cada aplicação precisa reportar para um collector hospedado e se identificar com um nome de serviço distinto. O distributed tracing está disponível pelas integrações do AppSignal para Python, Ruby e PHP, e pelo OpenTelemetry para Go e Java. Elixir e Node.js ainda não são suportados. Qualquer outra aplicação instrumentada com OpenTelemetry também pode reportar dados de trace para um collector hospedado. No navegador, o AppSignal para Browser inicia o trace para requisições à sua API.
Distributed tracing é uma funcionalidade em beta do AppSignal Labs, disponível apenas ao usar o collector hospedado do AppSignal.
O que você precisa configurar depende de como sua integração envia dados ao AppSignal. Python e Ruby podem reportar tanto pelo agente incluso quanto por um collector, então você precisa ativar o modo collector. PHP, Go, Java e configurações personalizadas do OpenTelemetry já reportam por um collector, então não há nada extra para ativar para o distributed tracing.
  • Python: defina a opção collector_endpoint para a URL do seu collector hospedado em vez de um self-hosted. Veja configuração do collector para Python.
  • Ruby: defina a opção collector_endpoint para a URL do seu collector hospedado em vez de um self-hosted. O modo collector chegou no AppSignal para Ruby 5.0 e precisa da gem appsignal-opentelemetry junto com ele, no Ruby 3.1 ou mais recente. Veja configuração do collector para Ruby para as versões a instalar, e distributed tracing para Ruby para as bibliotecas que carregam o trace para você.
  • PHP: nenhuma configuração extra de distributed tracing para ativar. O pacote PHP já reporta por um collector, então o distributed tracing funciona assim que seu app reporta ao AppSignal.
  • Go: instrumente sua aplicação com o SDK do OpenTelemetry e exporte para a URL do seu collector hospedado. Registre um propagator com otel.SetTextMapPropagator, como faz o guia de instalação do Go. Sem ele, o SDK do Go não propaga o contexto do trace. O AppSignal tem instruções de configuração para os frameworks Gorilla mux e Gin-gonic.
  • Java: instrumente com o SDK do OpenTelemetry ou o agente Java e exporte para a URL do seu collector hospedado. Veja o guia de instalação do Java para a configuração do agente.
  • Uma configuração personalizada do OpenTelemetry: nenhuma configuração específica do AppSignal para distributed tracing para ativar. Exportar para um collector hospedado já é como essas configurações reportam, então os traces se conectam sozinhos.
  • Browser: defina tracePropagationTargets para os hosts da sua API. Cada requisição correspondente carrega um header traceparent. O back-end que a recebe precisa de instrumentação de servidor HTTP para continuá-lo. Uma resposta 5xx ou um timeout é reportado como um erro de browser nesse trace. Veja distributed tracing para Browser.
Defina também um nome de serviço para cada aplicação. Python, Ruby e PHP o recebem pela opção service_name ou pela variável de ambiente APPSIGNAL_SERVICE_NAME; Go, Java e configurações personalizadas do OpenTelemetry definem o atributo de recurso service.name. Defina-o explicitamente para cada serviço. Sem ele, o AppSignal não consegue distinguir os serviços em um trace de forma confiável, e o OpenTelemetry personalizado espera que o atributo de recurso service.name esteja presente. O distributed tracing é construído sobre o OpenTelemetry, então não se limita às integrações acima. Qualquer aplicação instrumentada com OpenTelemetry pode reportar dados de distributed tracing para um collector hospedado. Você pode fazer isso por uma integração do AppSignal como o pacote PHP, ou por uma configuração personalizada de SDK do OpenTelemetry. Saiba mais nas documentações de configuração do collector para Python, configuração do collector para Ruby, configuração do PHP, configuração do Go, configuração do Java, e opção de nome de serviço do OpenTelemetry.

Como isso funciona no AppSignal?

O AppSignal constrói traces distribuídos sobre o OpenTelemetry. A parte que torna isso possível é a propagação de contexto. Quando um serviço instrumentado chama outro serviço, o OpenTelemetry anexa o ID de trace e o span de origem à chamada de saída. Ele viaja como headers em uma requisição HTTP, ou como metadados em um job enfileirado, e o serviço que o recebe o lê e continua o mesmo trace. Cada serviço reporta a porção do trace que ele tratou, chamada de seu subtrace. O AppSignal recebe esses subtraces de forma independente, muitas vezes de processos ou hosts diferentes, e os remonta em um único trace usando o ID de trace compartilhado e os vínculos pai e filho entre os spans. Você não conecta serviços manualmente no AppSignal. Se uma biblioteca está instrumentada, suas chamadas se juntam ao trace automaticamente.
Um trace por três serviços, cada um reportando seu próprio subtrace e os spans dentro dele

Um trace abrange vários serviços. Cada serviço reporta um subtrace, e o AppSignal monta os subtraces em um único trace.

O AppSignal faz sampling de traces em vez de manter todos eles, e toma essa decisão entre serviços: quando um trace é mantido, o trabalho de cada serviço nele também é mantido, então o trace chega inteiro em vez de em fragmentos espalhados. O sampling favorece os traces que você mais quer ver, os com erros e as requisições mais lentas. Lacunas ainda podem aparecer nas bordas, quando um serviço não reporta ou seus dados chegam tarde demais. Depois que os traces começarem a chegar, abra a página do trace para inspecioná-los de duas formas: o service map, que mostra os serviços no trace e as chamadas entre eles, e a linha do tempo do trace, que dispõe cada span ao longo do tempo. A página do trace explica como ler os dois.

Suporte entre aplicações

Um serviço no AppSignal não é a mesma coisa que uma aplicação. Vários serviços podem reportar para uma aplicação AppSignal, e um único trace também pode atravessar serviços que pertencem a aplicações totalmente separadas. Por exemplo, uma aplicação web, um serviço de estoque e um serviço de auditoria podem todos reportar para uma aplicação AppSignal, cada um com seu próprio nome de serviço, enquanto um serviço separado reporta como sua própria aplicação. Uma única ação do usuário, como um checkout, pode produzir um trace que inclui serviços de ambas as aplicações. O service map do AppSignal trata isso como um único trace, independentemente de onde cada subtrace foi reportado. Ele identifica a aplicação dona de cada serviço e vincula cada um à visão dessa aplicação sobre o mesmo trace. Para seguir uma requisição por uma fronteira entre aplicações, selecione o próximo serviço no mapa. Você passa de uma aplicação para a próxima ao longo do mesmo trace. Isso funciona porque o contexto se propaga por fronteiras de processo e de aplicação da mesma forma que entre serviços, e o AppSignal corresponde subtraces pelo seu ID de trace compartilhado, não pela aplicação ou host de onde vieram. Depois que cada serviço reporta por um collector hospedado com seu próprio nome de serviço, você pode seguir uma requisição por serviços e aplicações a partir de um único trace.

Página do trace

Abra um trace armazenado e leia seu service map, linha do tempo, detalhes dos spans, logs relacionados e triggers.

Tracing distribuído para Ruby

Veja quais integrações HTTP e de jobs em background do Ruby carregam o trace automaticamente.

Tracing distribuído para Browser

Inicie o trace no navegador, e veja uma requisição de API com falha como um erro no trace do back-end.

OpenTelemetry

Configure um SDK OpenTelemetry personalizado para reportar por um collector do AppSignal.

Instrumentação personalizada

Adicione seus próprios spans e atributos quando a instrumentação padrão não for suficiente.

Vincular traces com logs

Conecte um trace aos seus logs relacionados para navegar entre eles durante a depuração.

Labs

Experimente distributed tracing e outros recursos experimentais.