Instrumentar uma API costuma começar com um middleware, crescer para uma combinação de bibliotecas e terminar com alguém tentando descobrir por que o trace da requisição não conversa com o log da exceção. O FastAPI 0.142 tenta encurtar esse caminho ao adicionar suporte nativo a OpenTelemetry para requisições HTTP, conexões WebSocket, métricas e logs.
A mudança entrou na versão 0.142.0, publicada em 29 de setembro. No mesmo dia, a 0.142.1 corrigiu endpoints envolvidos repetidamente ao incluir routers. Em 30 de setembro, a 0.142.2 passou a permitir que a aplicação inicie mesmo quando a configuração automática do OpenTelemetry falha. Para quem pretende testar o recurso, esse histórico curto já dá uma orientação: use a versão corrigida e confirme que a telemetria está chegando ao destino, em vez de assumir que um servidor no ar significa observabilidade funcionando.
Nativo não significa que o dashboard aparece sozinho
O FastAPI agora produz sinais usando as APIs do OpenTelemetry e conhece as etapas internas de uma requisição. Ainda é necessário instalar o SDK e um exportador, além de apontar os dados para um collector ou serviço de observabilidade. A instalação com o extra standard já inclui os pacotes usados para exportação via OTLP.
uv add "fastapi[standard]"
Com um destino compatível com OTLP, a configuração inicial pode ficar em variáveis de ambiente. O endpoint informado é a base usada para enviar traces, métricas e logs aos caminhos correspondentes.
export OTEL_SERVICE_NAME=orders-api
export OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.example.com
export OTEL_EXPORTER_OTLP_HEADERS="api-key=SEU_TOKEN"
A aplicação continua parecendo uma aplicação FastAPI comum. Não é necessário decorar cada endpoint ou adicionar manualmente um middleware para obter o primeiro trace.
from fastapi import FastAPI
app = FastAPI()
@app.get("/orders/{order_id}")
async def read_order(order_id: int):
return {"order_id": order_id}
Em FastAPI Cloud, a documentação informa que as métricas aparecem automaticamente quando a aplicação usa fastapi[standard]. Em outros ambientes, o mesmo modelo não obriga o uso de um fornecedor específico: qualquer backend que receba OTLP pode entrar no pipeline.
O trace enxerga mais do que a duração do endpoint
Como a instrumentação está dentro do framework, o FastAPI consegue dividir a requisição em operações que uma camada ASGI genérica não conhece com a mesma precisão. Por padrão, um trace pode incluir a resolução de dependências, a execução da função da rota, a serialização da resposta e as tarefas registradas em BackgroundTasks.
As tarefas em segundo plano permanecem ligadas ao trace da requisição, mas seus spans rodam depois que o span HTTP termina. Isso preserva a relação entre o pedido e o trabalho disparado sem somar a duração da tarefa ao tempo de resposta apresentado ao cliente.
Conexões WebSocket também recebem traces e logs. Cada conexão pode gerar um span como WS /ws/{room}, cobrindo o handler e a limpeza das dependências. As métricas de requisição HTTP, por outro lado, continuam restritas a HTTP. Não faz sentido interpretar uma conexão longa de WebSocket como se fosse uma requisição comum.
Logs de erro chegam correlacionados, mas podem carregar dados sensíveis
Exceções não tratadas são registradas como logs do OpenTelemetry e ligadas ao trace da requisição ou da conexão. O framework também registra falhas de validação como avisos, com a rota e a quantidade de erros, sem incluir o conteúdo inválido enviado pelo cliente.
Essa correlação é útil porque permite sair de uma taxa de erro, abrir um trace específico e chegar ao stack trace correspondente. Também cria uma responsabilidade nova. Mensagens de exceção e stacks podem conter parâmetros, caminhos, trechos de consultas e outros dados que não deveriam sair do ambiente. A documentação recomenda filtrar ou remover essas informações nos processadores de log, ou desligar os logs nativos quando o pipeline não puder garantir esse tratamento.
app = FastAPI(
telemetry={
"logs": False,
}
)
Health check não precisa virar o trace mais popular do sistema
Coletar tudo é um começo conveniente, mas dificilmente é uma configuração final. Rotas de saúde e probes podem produzir mais volume do que as operações que realmente ajudam a investigar o produto. O dicionário telemetry permite excluir requisições a partir do scope ASGI, desligar sinais específicos ou remover os spans internos das operações.
from fastapi import FastAPI
app = FastAPI(
telemetry={
"exclude": lambda scope: scope["path"] == "/health",
"operation_spans": True,
}
)
Também é possível manter apenas métricas, desligando tracing, ou desabilitar operation_spans para registrar somente o span HTTP. Essas escolhas afetam custo e capacidade de diagnóstico. Um trace mais detalhado ajuda a descobrir se a lentidão veio de uma dependência ou da serialização, mas produz mais spans por requisição.
Projetos já instrumentados devem evitar configuração duplicada
Aplicações maduras talvez já criem seus próprios providers, usem um agente de auto-instrumentação ou adicionem OpenTelemetryMiddleware. Ligar outra configuração automática por cima pode duplicar spans e exportadores, além de tornar o encerramento da aplicação mais confuso.
Quando o projeto já controla o pipeline, auto_configure: False impede o FastAPI de adicionar exportadores com base nas variáveis de ambiente. Providers de trace, métricas e logs também podem ser entregues explicitamente ao framework.
app = FastAPI(
telemetry={
"auto_configure": False,
"tracer_provider": tracer_provider,
}
)
Há ainda uma limitação documentada: providers do OpenTelemetry são globais por padrão. Configurações independentes para subaplicações montadas não são garantidas. Quem usa várias aplicações ASGI no mesmo processo precisa revisar essa arquitetura antes de esperar isolamento de telemetria entre elas.
O patch 0.142.2 melhora disponibilidade, não corrige uma configuração errada
Permitir que o servidor inicie quando a configuração automática falha é uma escolha razoável de disponibilidade. Uma indisponibilidade do collector não deveria necessariamente impedir a API de atender usuários. O risco é transformar essa tolerância em silêncio operacional: a aplicação funciona, mas deixa de emitir justamente os sinais que avisariam sobre um problema.
O rollout merece um teste simples: subir a versão corrigida em um ambiente controlado, fazer uma requisição conhecida, provocar um erro não sensível e confirmar traces, métricas e logs no destino. Depois, desligar temporariamente o endpoint de exportação para observar os logs e o comportamento da aplicação. Observabilidade que nunca teve a falha simulada ainda é uma hipótese bem configurada.
O suporte nativo reduz bastante a cola necessária para começar e dá ao framework contexto para produzir spans melhores. Ele não escolhe política de retenção, amostragem, custo, mascaramento de dados ou alertas pelo time. Essas decisões continuam sendo a diferença entre acumular telemetria e conseguir usá-la quando uma requisição resolve levar três segundos às duas da manhã.
