evobits

evobits · guia · aplicações · opentelemetry

Python, Java, Go, .NET e PHP pelo OpenTelemetry oficial

Fora do Node.js, o evobits não tem pacote próprio: o serviço usa o SDK oficial do OpenTelemetry da linguagem, apontado para o evobits por variáveis de ambiente. Onde existe instrumentação automática (Python, Java, .NET e PHP), não é preciso mudar o código.

Linguagens
Python, Java, Go, .NET e PHP
Protocolo
http/protobuf (gRPC não)
Rede
Só saída para otlp.evobits.com.br:443
Onde no painel
Aplicações > Serviços > Novo serviço

Copia esta página inteira em Markdown, com o texto para IA, para colar no Claude Code, no ChatGPT, no Gemini ou no assistente que vocês usam.

Exemplo de prompt
Preciso ligar o nosso serviço no evobits pelo OpenTelemetry oficial (logs, traces e erros).
Siga o guia que vou colar abaixo.

Nossa stack: (descreva aqui: linguagem, framework, como o serviço é iniciado).

Leia o guia inteiro e execute a seção "Texto para IA".
O token nunca vai escrito em arquivo: só a variável EVOBITS_TOKEN.

<COLE AQUI O TEXTO COPIADO PELO BOTÃO "COPIAR PARA IA">

01O que é monitorado

Depende da instrumentação de cada linguagem. Em geral: requisições recebidas (rota, código, duração), chamadas HTTP de saída, banco e cache (quando a linguagem tem a instrumentação da biblioteca), logs do logger padrão e exceções (evento exception no span e, em várias linguagens, também no log).

O evobits recebe traces e logs. Métricas OTLP são recusadas com sucesso parcial ("métricas ainda não gravadas"); desligue a exportação de métricas para não gastar rede.

02Como funciona

  • Endereço https://otlp.evobits.com.br, OTLP por HTTP, protobuf (ou JSON), gzip aceito. gRPC não é aceito no endereço da internet (só na sonda coletora).
  • O SDK monta https://otlp.evobits.com.br/v1/traces e https://otlp.evobits.com.br/v1/logs sozinho a partir de OTEL_EXPORTER_OTLP_ENDPOINT.
  • Cabeçalho Authorization: Bearer <token>. Na variável OTEL_EXPORTER_OTLP_HEADERS, o valor vai com o espaço codificado como %20 (é o que a especificação pede; Python, Java, Go e .NET decodificam).
  • O token decide o serviço e o ambiente. service.name, service.version e deployment.environment.name vão como atributos de recurso: o nome não muda o destino; a versão aparece nas marcas de deploy e nas regressões de erro.
  • A instância vem de service.instance.id ou, sem ele, de host.name. Sem nenhum dos dois, o evobits cria um nome (a partir de host.id, k8s.pod.name ou do processo), então a aba Instâncias sempre tem uma instância. Para nomes estáveis, ponha service.instance.id na variável; Java e Go (com resource.WithHost()) já mandam host.name.
  • A rota vem do atributo http.route do span do servidor. As instrumentações automáticas de Python (Flask, Django, FastAPI), Java (Spring, servidor HTTP do JDK) e .NET (ASP.NET Core) informam. No Go, veja o passo próprio.
  • A máscara roda no evobits, antes de gravar. A amostragem guarda 100 % dos traces com erro e lentos, e 10 % dos outros (ajustável).

03As variáveis (todas as linguagens)

EVOBITS_TOKEN=eva_prd_...   # do painel; no ambiente do processo, nunca no código nem no git
OTEL_SERVICE_NAME=meu-servico
OTEL_RESOURCE_ATTRIBUTES=service.version=1.4.2,deployment.environment.name=producao,service.instance.id=<nome da máquina>
OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.evobits.com.br
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20${EVOBITS_TOKEN}
OTEL_TRACES_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_METRICS_EXPORTER=none

OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf é obrigatório no Python (o pacote opentelemetry-distro assume gRPC) e no .NET pelo SDK manual (que também assume gRPC). ${EVOBITS_TOKEN} é expandido pelo shell, pelo systemd (Environment=) ou pelo seu orquestrador; em Docker Compose, use OTEL_EXPORTER_OTLP_HEADERS: "Authorization=Bearer%20${EVOBITS_TOKEN}" com a variável vinda do ambiente ou do arquivo de segredos. Para a instância, service.instance.id=$(hostname) num script de início serve.

04Onde aparece

As mesmas telas do Node.js: Serviços, Visão geral, Rotas, Erros, Traces, Dependências, Instâncias, Logs e Mapa. O subtítulo do serviço mostra a linguagem e o framework quando o evobits reconhece as instrumentações (por exemplo "Flask").

05Alertas

Sensor de rota, sensor de contagem de log, "Erro novo em produção" e "Regressão de erro", como em qualquer serviço.

06Limites e privacidade

  • Lote até 8 MB (32 MB descomprimido); linha acima de 256 kB é recusada sozinha; 20 pedidos por segundo por token.
  • Quando a linguagem grava a exceção no span e no log (Python com Flask faz isso), o evobits conta uma ocorrência só: ele junta as duas pelo mesmo trace e span.
  • Nome de pessoa, endereço, CEP e IP não estão na máscara fixa: crie uma regra extra na Configuração do serviço.
  • Corte da cota: o evobits responde 200 com sucesso parcial e o cabeçalho X-Evobits-Corte. Os SDKs padrão tratam como sucesso, não repetem e não acumulam memória; os dados enviados no corte são descartados.

07Como instalar

Python

Documentação oficial: https://opentelemetry.io/docs/zero-code/python/. Versão atual: SDK 1.45.2 e opentelemetry-distro 0.66b2, que pedem Python 3.10 ou mais novo; no Python 3.9 o pip instala a última compatível (1.41.1 e 0.62b1).

pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http
opentelemetry-bootstrap -a install      # instala as instrumentações das bibliotecas que o projeto já usa

Ponha as variáveis da seção acima e troque o comando de início:

opentelemetry-instrument python app.py
# ou: opentelemetry-instrument gunicorn app:app

Logs do módulo logging vão sozinhos nas versões atuais. Em versões antigas, ligue com OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true (nas novas essa variável está obsoleta e só gera um aviso). Com gunicorn, uwsgi ou outro servidor que cria processos depois de carregar o app, siga a seção "Working with fork process models" da documentação do OpenTelemetry Python.

Java

Documentação oficial: https://opentelemetry.io/docs/zero-code/java/agent/. Versão atual do agente: 2.33.1 (Java 8 ou mais novo). Logs (Logback, Log4j, java.util.logging) vão por padrão; o protocolo padrão já é http/protobuf.

curl -L -o opentelemetry-javaagent.jar \
  https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.33.1/opentelemetry-javaagent.jar
java -javaagent:./opentelemetry-javaagent.jar -jar app.jar

As variáveis da seção acima valem como estão. O agente manda host.name sozinho (a instância).

Go

Documentação oficial: https://opentelemetry.io/docs/languages/go/getting-started/. Versão atual: go.opentelemetry.io/otel 1.47.0, otelhttp 0.72.0 e a ponte otelslog 0.21.0, que pedem Go 1.26. No Go não há instrumentação automática por variável: o código liga o SDK uma vez, e os exportadores leem OTEL_EXPORTER_OTLP_ENDPOINT e OTEL_EXPORTER_OTLP_HEADERS sozinhos.

go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/log \
  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \
  go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp \
  go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp \
  go.opentelemetry.io/contrib/bridges/otelslog
// telemetria.go: traces e logs pelo OTLP/HTTP; endereço, cabeçalho e recurso vêm das variáveis OTEL_*.
func iniciarTelemetria(ctx context.Context) (func(context.Context) error, error) {
	res, err := resource.New(ctx, resource.WithFromEnv(), resource.WithHost(), resource.WithTelemetrySDK())
	if err != nil {
		return nil, err
	}
	te, err := otlptracehttp.New(ctx)
	if err != nil {
		return nil, err
	}
	tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(te), sdktrace.WithResource(res))
	otel.SetTracerProvider(tp)
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
	le, err := otlploghttp.New(ctx)
	if err != nil {
		return nil, err
	}
	lp := sdklog.NewLoggerProvider(sdklog.WithProcessor(sdklog.NewBatchProcessor(le)), sdklog.WithResource(res))
	global.SetLoggerProvider(lp)
	return func(ctx context.Context) error { return errors.Join(tp.Shutdown(ctx), lp.Shutdown(ctx)) }, nil
}

// comRota grava no span do servidor a rota do ServeMux ("/pedidos/{id}"), que o evobits usa na aba Rotas.
func comRota(h http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		rota := r.Pattern
		if i := strings.IndexByte(rota, ' '); i >= 0 {
			rota = rota[i+1:]
		}
		trace.SpanFromContext(r.Context()).SetAttributes(attribute.String("http.route", rota))
		h(w, r)
	}
}

No main: chame iniciarTelemetria, guarde a função de parada para o fim (defer), crie o logger com otelslog.NewLogger("meu-servico"), registre cada rota com mux.HandleFunc("GET /pedidos/{id}", comRota(...)) e sirva com otelhttp.NewHandler(mux, "servidor"). Sem o comRota, o otelhttp atual põe a rota só no nome do span, e o evobits mostra o span sem rota na lista de traces.

.NET

Documentação oficial: https://opentelemetry.io/docs/zero-code/dotnet/. Versão atual da instrumentação automática: 1.18.0 (.NET suportado pela Microsoft e .NET Framework 4.6.2 ou mais novo); SDK OpenTelemetry 1.20.1. Na instrumentação automática o protocolo padrão já é http/protobuf, e logs vão por padrão.

Linux e macOS (o instalador oficial confere a assinatura com o GitHub CLI, gh):

version="v1.18.0"
repository="open-telemetry/opentelemetry-dotnet-instrumentation"
curl -sSfL "https://github.com/$repository/releases/download/$version/otel-dotnet-auto-install.sh" -o otel-dotnet-auto-install.sh
VERSION="$version" sh ./otel-dotnet-auto-install.sh
chmod +x $HOME/.otel-dotnet-auto/instrument.sh
. $HOME/.otel-dotnet-auto/instrument.sh
./MeuServico      # com as variáveis da seção acima no mesmo ambiente

Windows (PowerShell como administrador): Import-Module "OpenTelemetry.DotNet.Auto.psm1", Install-OpenTelemetryCore e Register-OpenTelemetryForCurrentSession -OTelServiceName "meu-servico"; para IIS, Register-OpenTelemetryForIIS. A documentação oficial traz a verificação completa do instalador.

Pelo SDK no código (OpenTelemetry.Exporter.OpenTelemetryProtocol), ponha OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf: o padrão do SDK é gRPC.

PHP

Documentação oficial: https://opentelemetry.io/docs/zero-code/php/auto/. Pacotes atuais: open-telemetry/sdk 1.15.0 e open-telemetry/exporter-otlp 1.4.0 (PHP 8.1 ou mais novo); instrumentações como open-telemetry/opentelemetry-auto-laravel 1.10.0 (Laravel 10 a 13), -auto-slim, -auto-psr18 e -auto-pdo. A instrumentação automática precisa da extensão opentelemetry.

pecl install opentelemetry
# no php.ini:  extension=opentelemetry.so      conferir: php -m | grep opentelemetry
composer require open-telemetry/sdk open-telemetry/exporter-otlp guzzlehttp/guzzle \
  open-telemetry/opentelemetry-auto-laravel     # ou a instrumentação do seu framework

Variáveis: as da seção acima, mais OTEL_PHP_AUTOLOAD_ENABLED=true e OTEL_PROPAGATORS=baggage,tracecontext. Em PHP-FPM, ponha as variáveis no pool (env[...]) ou no php.ini. Para logs do Monolog, open-telemetry/opentelemetry-logger-monolog.

08Como conferir

  1. 1Faça algumas requisições ao serviço.
  2. 2O cartão Primeiro dado do serviço mostra "está mandando dados", com a instância e a versão.
  3. 3Em Rotas, a rota aparece com o caminho do framework (por exemplo GET /pedidos/<int:id> no Flask, GET /pedidos/{id} no Go).
  4. 4Em Aplicações > Logs, filtre pelo serviço: as linhas aparecem com o nível certo e a máscara aplicada.
  5. 5Provoque um erro numa rota de teste: ele aparece em Erros com tipo e mensagem.

09Problemas comuns

SintomaO que fazer
Python não sobe com "Configuration of configurator failed"falta OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf (o distro assume gRPC)
Exportador registra 401cabeçalho sem Bearer, token errado ou revogado; confira Authorization=Bearer%20...
Exportador registra 404 ou "unimplemented"protocolo gRPC no endereço da internet; use http/protobuf
403módulo Aplicações desligado ou sem aceite
Instância com nome estranhofalta service.instance.id em OTEL_RESOURCE_ATTRIBUTES; o evobits cria um nome sozinho
Rota sem caminhoa instrumentação do framework não está ligada (Python: rode opentelemetry-bootstrap -a install de novo) ou, no Go, falta o comRota
Avisos de métricas recusadasOTEL_METRICS_EXPORTER=none

10Texto para IA

Para pedir a instalação a um assistente de código (Claude Code ou afins) aberto no projeto do serviço. Troque os marcadores entre < >; o token fica só na variável EVOBITS_TOKEN.

# Tarefa: ligar o evobits (logs, traces e erros) no serviço <nome do serviço> pelo OpenTelemetry oficial

## Objetivo
Fazer este serviço mandar traces e logs ao evobits pelo OpenTelemetry oficial da linguagem dele (Python, Java, Go,
.NET ou PHP), no ambiente <ambiente>, mudando o mínimo possível.

## Contexto
- Destino: https://otlp.evobits.com.br, OTLP por HTTP com protobuf (gRPC NÃO é aceito). O SDK acrescenta /v1/traces e /v1/logs.
- Autenticação: cabeçalho `Authorization: Bearer <token>`. O token fica só na variável de ambiente EVOBITS_TOKEN.
- Variáveis padrão a configurar no ambiente do processo (não no código):
    OTEL_SERVICE_NAME=<nome do serviço>
    OTEL_RESOURCE_ATTRIBUTES=service.version=<versão do deploy>,deployment.environment.name=<ambiente>,service.instance.id=<nome da máquina>
    OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.evobits.com.br
    OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20${EVOBITS_TOKEN}
    OTEL_TRACES_EXPORTER=otlp
    OTEL_LOGS_EXPORTER=otlp
    OTEL_METRICS_EXPORTER=none
- O evobits usa o atributo `http.route` do span do servidor como rota, e `service.instance.id` (ou `host.name`)
  como instância.
- Por linguagem (documentação oficial em opentelemetry.io):
  - Python 3.10+: `pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http`,
    `opentelemetry-bootstrap -a install`, e iniciar com `opentelemetry-instrument <comando de hoje>`.
  - Java 8+: agente `opentelemetry-javaagent.jar` 2.33.1 (GitHub open-telemetry/opentelemetry-java-instrumentation),
    iniciar com `java -javaagent:<caminho>/opentelemetry-javaagent.jar ...`.
  - Go 1.26+: SDK `go.opentelemetry.io/otel` 1.47.0 com `otlptracehttp`, `otlploghttp`, `otelhttp` e a ponte
    `otelslog`; resource com `resource.WithFromEnv()` e `resource.WithHost()`; gravar `http.route` no span do
    servidor com `r.Pattern` sem o método (o otelhttp atual não grava).
  - .NET: instrumentação automática 1.18.0 (`otel-dotnet-auto-install.sh` e `instrument.sh`, ou o módulo PowerShell).
  - PHP 8.1+: extensão `opentelemetry` (pecl), `composer require open-telemetry/sdk open-telemetry/exporter-otlp
    guzzlehttp/guzzle` e a instrumentação do framework (por exemplo `open-telemetry/opentelemetry-auto-laravel`),
    com `OTEL_PHP_AUTOLOAD_ENABLED=true`.

## Passos
1. Descubra a linguagem, a versão do runtime, o framework, o gerenciador de pacotes e onde o serviço é iniciado
   (Dockerfile, systemd, Procfile, compose, Kubernetes, script).
2. Confira se o runtime atende a versão mínima acima. Se não atender, pare e me avise antes de mudar qualquer coisa.
3. Acrescente as dependências da linguagem (só as listadas) e, no Go, o código de inicialização e a rota.
4. Acrescente as variáveis OTEL_* no lugar onde o serviço já recebe configuração, com o token SEMPRE por referência
   a ${EVOBITS_TOKEN}. No `.env.example` ou na documentação, deixe `EVOBITS_TOKEN=` sem valor.
5. Ajuste o comando de início só no necessário (`opentelemetry-instrument`, `-javaagent`, `instrument.sh`).
6. Liste os logs do projeto que gravam nome de pessoa, endereço, CEP ou IP: a máscara fixa do evobits não cobre.

## Regras
- Nunca escreva o valor do token em arquivo versionado, em log, em imagem de contêiner ou na resposta.
- Não mude nada além do pedido: sem atualizar outras dependências, sem refatorar, sem trocar o logger.
- Não ligue métricas OTLP (o evobits recusa). Não use gRPC no endereço https://otlp.evobits.com.br.
- Rode os testes do projeto depois da mudança; sem EVOBITS_TOKEN o serviço tem de subir normal.

## Como saber que deu certo
1. Com EVOBITS_TOKEN exportado, suba o serviço e faça requisições a uma rota com parâmetro.
2. O log do processo não mostra erro de exportação (401, 403, 404 ou falha de conexão).
3. No painel do evobits, o cartão "Primeiro dado" do serviço <nome do serviço> mostra a instância e a versão, e a aba
   Rotas mostra a rota com o caminho do framework.