Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 60

Automatic Telemetry in Aspire

Recommended resources

Olá! Bem-vindo de volta.

Nas últimas lições, exploramos os três pilares da observabilidade — logs, traces e métricas — e vimos como configurar health checks proativos. Você aprendeu a usar o Aspire Dashboard para analisar o comportamento da sua aplicação, diagnosticar problemas e monitorar a saúde dos serviços.

Até agora, muito do que vimos parece funcionar "magicamente". Requisições HTTP, chamadas a bancos de dados e interações com caches aparecem automaticamente como traces detalhados e métricas no dashboard. Nesta lição, vamos desmistificar essa mágica.

Nosso objetivo é: Descrever como o Aspire instrumenta automaticamente clientes HTTP, chamadas a bancos de dados e outros componentes para observabilidade.

Vamos mergulhar nos mecanismos internos que fazem do .NET Aspire uma plataforma tão poderosa para construir aplicações observáveis desde o início.

O Padrão da Indústria: OpenTelemetry

A automação da observabilidade no Aspire não é uma solução proprietária; ela é construída sobre um padrão aberto e robusto chamado OpenTelemetry (OTel). Entender o OTel é a chave para entender como o Aspire funciona.

Em essência, OpenTelemetry é um framework e um conjunto de ferramentas projetado para padronizar a forma como geramos, coletamos e exportamos dados de telemetria (logs, métricas e traces).

Para ter uma visão geral do que é o OpenTelemetry e por que ele é tão importante no desenvolvimento de software moderno, assista aos seguintes trechos de uma excelente palestra de Martin Thwaites na NDC London 2024.

Practical OpenTelemetry in .NET 8 - Martin Thwaites - NDC London 2024

Esta palestra, 'Practical OpenTelemetry in .NET 8', oferece uma introdução clara aos conceitos fundamentais do OpenTelemetry.

Assista ao trecho de 07:00 a 09:44. Foque em entender a definição do OpenTelemetry como um protocolo e a introdução aos seus três 'sinais' principais: traces, métricas e logs.

A principal vantagem do OTel é que ele separa a instrumentação do seu código da ferramenta de visualização (o backend). Você instrumenta sua aplicação uma vez com OTel, e pode enviar os dados para o Aspire Dashboard, Azure Monitor, Prometheus, Grafana ou qualquer outra ferramenta compatível, sem alterar seu código.


Instrumentação: Automática vs. Codificada

Existem duas abordagens principais para instrumentar uma aplicação com OpenTelemetry:

  1. Auto-instrumentação: Geralmente envolve anexar um agente ao processo da sua aplicação que "injeta" a instrumentação em tempo de execução, sem alterações no código. É rápido para começar, mas oferece menos controle e pode gerar muito "ruído".
  2. Instrumentação Codificada (Coded Instrumentation): Envolve adicionar pacotes NuGet e algumas linhas de código na inicialização da sua aplicação para configurar o pipeline do OTel e registrar as bibliotecas de instrumentação desejadas. Isso lhe dá controle total sobre o que é medido e como é medido.

O .NET Aspire utiliza uma abordagem de instrumentação codificada que é tão simplificada e bem integrada que parece automática.

Para entender melhor essa distinção e por que a abordagem codificada é mais poderosa, assista a outro trecho da mesma palestra.

Practical OpenTelemetry in .NET 8 - Martin Thwaites - NDC London 2024

Martin Thwaites compara as duas abordagens de instrumentação, o que nos ajudará a entender exatamente onde o Aspire se encaixa.

Assista de 14:09 a 17:31. Preste atenção na explicação sobre 'coded instrumentation' e como ela oferece mais intencionalidade e controle sobre o contexto da sua telemetria. É exatamente isso que o Aspire faz por nós de forma organizada.


O Mecanismo de Instrumentação do Aspire

Agora que entendemos os conceitos, vamos ver como o Aspire implementa essa instrumentação codificada de forma tão eficaz. O processo ocorre em duas camadas principais: o projeto ServiceDefaults e as integrações de componentes (Client Integrations).

1. A Base: O Projeto ServiceDefaults

Como vimos nas lições anteriores, o projeto ServiceDefaults é um projeto de biblioteca de classes que centraliza configurações comuns. Uma de suas funções mais importantes é configurar o pipeline do OpenTelemetry para todos os serviços que o referenciam.

Vamos analisar como isso é feito.

.NET Aspire Tutorial For Beginners

No tutorial de Julio Casal, há uma seção que explora o código dentro do projeto ServiceDefaults, mostrando exatamente como o OpenTelemetry é configurado.

Assista do trecho 58:36 a 01:03:00. Observe como o método ConfigureOpenTelemetry no arquivo Extensions.cs faz o seguinte: Chama AddOpenTelemetry() para iniciar a configuração. Adiciona os provedores de telemetria com WithMetrics() e WithTracing(). Dentro desses métodos, ele adiciona bibliotecas de instrumentação específicas, como AddAspNetCoreInstrumentation, AddHttpClientInstrumentation e AddRuntimeInstrumentation. Configura o exportador (AddOtlpExporter) que envia os dados para o Aspire Dashboard.

O que isso significa na prática?

  • AddAspNetCoreInstrumentation: Automaticamente cria spans para todas as requisições HTTP que chegam ao seu serviço ASP.NET Core.
  • AddHttpClientInstrumentation: Automaticamente cria spans para todas as requisições HTTP de saída feitas usando HttpClient.
  • AddRuntimeInstrumentation: Coleta métricas sobre o .NET runtime, como uso de memória e atividade do garbage collector.

Apenas por referenciar o projeto ServiceDefaults e chamar builder.AddServiceDefaults(), seus serviços já ganham uma base sólida de observabilidade para qualquer interação HTTP.

Aspire Dashboard: HTTP Server Request Duration Metrics
O resultado da instrumentação automática do ASP.NET Core e do HttpClient. O Aspire Dashboard pode exibir métricas detalhadas, como a duração das requisições do servidor HTTP (`http.server.request.duration`), divididas por percentis e filtráveis por rota, método e status, tudo isso configurado pelo `ServiceDefaults`.

2. A Especialização: Integrações de Componentes (Client Integrations)

A instrumentação HTTP é ótima, mas e quanto às chamadas a bancos de dados, caches e filas? É aqui que as integrações de componentes do Aspire brilham.

Quando você adiciona um pacote NuGet de um componente Aspire, como Aspire.Npgsql ou Aspire.StackExchange.Redis, você não está apenas obtendo a configuração da string de conexão. Você também está adicionando a biblioteca de instrumentação OpenTelemetry específica para esse componente.

O fluxo é o seguinte:

  1. Você adiciona Aspire.Npgsql ao seu projeto de API.
  2. Este pacote tem uma dependência do OpenTelemetry.Instrumentation.Npgsql.
  3. Quando você chama builder.AddNpgsqlDbContext(...) no seu Program.cs, o código de extensão do Aspire faz duas coisas:
    a. Configura o DbContext para usar a string de conexão fornecida pelo AppHost.
    b. Registra a instrumentação do Npgsql no pipeline do OpenTelemetry que foi previamente configurado pelo ServiceDefaults.

O resultado é que cada chamada ao banco de dados feita através do Entity Framework Core agora é automaticamente capturada como um span dentro do trace da sua requisição.

A documentação oficial da Microsoft e um artigo detalhado da comunidade confirmam este comportamento.

Documentação Oficial e Artigo da Comunidade

Vamos ler as seções relevantes da documentação da Microsoft e do blog Code with Mukesh para solidificar nosso entendimento.

No recurso '.NET Observability with OpenTelemetry' (ID: LINK), leia as seções 'OpenTelemetry packages' e 'OpenTelemetry in Aspire'. 'OpenTelemetry packages' lista as bibliotecas de instrumentação (como OpenTelemetry.Instrumentation.SqlClient), mostrando que existem pacotes dedicados para diferentes tecnologias. 'OpenTelemetry in Aspire' confirma que o projeto ServiceDefaults inclui esses pacotes e os configura, mencionando especificamente as instrumentações para ASP.NET, HttpClient e Runtime.

.NET Aspire Tutorial - Build Cloud-Ready Apps with . ...

Agora, no artigo '.NET Aspire Tutorial' (ID: LINK), leia a seção '.NET Aspire Observability: Logs, Traces & Metrics with OpenTelemetry'. Esta seção resume perfeitamente o resultado final, afirmando que o Aspire 'automaticamente instrumenta seus serviços para emitir traces distribuídos' e 'coleta métricas chave', mostrando exemplos visuais do dashboard.

A melhor maneira de ver isso é em ação. Quando adicionamos o Redis para cache na lição anterior sobre traces, o Aspire automaticamente incluiu as chamadas ao Redis no trace distribuído.

.NET Aspire Dashboard: Distributed Trace Detail
Este trace do Aspire Dashboard mostra perfeitamente a instrumentação automática em ação. Uma requisição (`POST`) é dividida em múltiplos spans, incluindo a execução de um componente principal e uma operação de banco de dados (`INSERT`). Cada etapa tem seu tempo medido e é visualmente correlacionada, permitindo a fácil identificação de gargalos.
Teste seu entendimento!

Você adiciona um novo projeto de worker service à sua solução Aspire que se comunica com uma API de terceiros usando HttpClient e publica mensagens em uma fila RabbitMQ. Para garantir que ambas as interações sejam visíveis como spans nos seus traces distribuídos no Aspire Dashboard, o que você precisa fazer?

  1. No worker service, referenciar o projeto ServiceDefaults e chamar builder.AddServiceDefaults().
  2. No AppHost, adicionar a integração do RabbitMQ com builder.AddRabbitMQ("my-rabbit");.
  3. No worker service, adicionar o pacote Aspire.RabbitMQ.Client e injetar a conexão usando a configuração do Aspire.

Analisando esses passos, qual deles é responsável por instrumentar as chamadas HttpClient e qual é responsável por instrumentar as chamadas ao RabbitMQ?

Show answer
  • Chamadas HttpClient: O Passo 1 é o responsável. Ao adicionar ServiceDefaults, você automaticamente habilita AddHttpClientInstrumentation(), que intercepta todas as chamadas feitas pelo HttpClient no seu worker service.
  • Chamadas RabbitMQ: Os Passos 2 e 3 são responsáveis em conjunto. builder.AddRabbitMQ no AppHost provisiona o recurso. Adicionar o pacote Aspire.RabbitMQ.Client no worker e usá-lo para se conectar garante que a biblioteca de instrumentação OpenTelemetry.Instrumentation.RabbitMQ (uma dependência do pacote Aspire) seja registrada no pipeline do OTel, capturando assim as operações de publicação como spans.

Conclusão

Nesta lição, desvendamos a "mágica" por trás da observabilidade no .NET Aspire. Vimos que não se trata de mágica, mas sim de uma aplicação inteligente e bem arquitetada do padrão industrial OpenTelemetry.

Principais Pontos:

  • .NET Aspire utiliza OpenTelemetry para fornecer observabilidade de primeira classe.
  • A abordagem do Aspire é de instrumentação codificada, oferecendo controle e contexto, mas de forma tão simplificada que parece automática.
  • O projeto ServiceDefaults estabelece um pipeline de OpenTelemetry centralizado, configurando instrumentações genéricas para ASP.NET Core e HttpClient.
  • As integrações de componentes do Aspire (como para PostgreSQL, Redis, RabbitMQ) adicionam automaticamente bibliotecas de instrumentação específicas para essas tecnologias ao pipeline do OTel.
  • O resultado é uma telemetria rica e correlacionada (logs, traces, métricas) que flui para o Aspire Dashboard com configuração mínima, cobrindo todo o fluxo de uma requisição através de múltiplos serviços e dependências.

Próxima Lição:
Com esta lição, concluímos nossa profunda imersão no .NET Aspire. Você agora tem uma base sólida sobre como construir, conteinerizar e monitorar aplicações distribuídas prontas para a nuvem.

A partir do próximo módulo, mudaremos nosso foco da orquestração de desenvolvimento local para a orquestração em escala de produção. Começaremos a explorar o Kubernetes, o sistema que se tornou o padrão de fato para gerenciar contêineres em produção. Você verá como os conceitos que aprendemos, como health checks e a exportação de telemetria, são fundamentais para operar aplicações de forma robusta no Kubernetes.