Ruby

Instrumentação para aplicações Ruby com as bibliotecas da Elven Observability.

Instrumentação Ruby on Rails com Elven Observability


Sumário

  • Visão geral

  • Pré-requisitos

  • Exemplo de referência

  • Configuração de variáveis de ambiente

  • Bootstrap OpenTelemetry

  • Instrumentações automáticas

  • Span manual no controller

  • Spans manuais por etapa no service object

  • Chamada HTTP de saída

  • Captura de erros em spans

  • Estrutura de código relevante

  • Como rodar localmente

  • Como validar no collector da Elven

  • Convenções recomendadas para spans manuais

  • Como adaptar para a sua aplicação

  • Testes

  • Troubleshooting

  • Checklist de deploy


Visão geral

A instrumentação Ruby on Rails da Elven usa o SDK oficial do OpenTelemetry para Ruby com exportação OTLP HTTP. Ela cobre instrumentação automática de HTTP server (Rails), banco de dados (ActiveRecord) e HTTP client (Net::HTTP), além de instrumentação manual de spans por etapa de negócio.

O Collector OTLP fica sempre no ambiente do cliente. A aplicação envia traces para esse Collector local/do cliente, e o Collector encaminha os dados para Tempo conforme a arquitetura contratada.

  • Grafana Tempo para traces

  • Grafana para consulta, correlação, painéis e alertas

Esta integração cobre somente traces. Métricas e logs ficam fora do escopo desta instrumentação.

Componente
O que faz

opentelemetry-api

API pública do OpenTelemetry para Ruby.

opentelemetry-sdk

SDK completo com TracerProvider e BatchSpanProcessor.

opentelemetry-exporter-otlp

Exporter OTLP HTTP para envio de traces ao collector.

opentelemetry-instrumentation-rails

Instrumentação automática do Rails (HTTP server, ActiveRecord).

opentelemetry-instrumentation-net_http

Instrumentação automática de chamadas HTTP de saída via Net::HTTP.


Pré-requisitos

  • Ruby 3.3.x instalado

  • Rails 8.1.2

  • Docker Desktop ou Docker Engine funcionando

  • Acesso de rede ao collector da Elven

  • Collector OTLP HTTP aceitando POST /v1/traces

Baseline técnico

Item
Versão

Ruby

3.3.x

Rails

8.1.2

pg

1.6.3

opentelemetry-api

1.7.0

opentelemetry-sdk

1.10.0

opentelemetry-exporter-otlp

0.31.1

opentelemetry-instrumentation-rails

0.39.1

opentelemetry-instrumentation-net_http

0.27.0

Checklist do collector

Antes de subir a aplicação, confirme:

  1. O endpoint de traces está correto

  2. O header de autenticação está definido (se necessário)

  3. O collector aceita http/protobuf

Atenção: se o collector exigir token, o valor em OTEL_EXPORTER_OTLP_HEADERS deve estar URL-encoded. Exemplo:


Exemplo de referência

A Elven disponibiliza uma aplicação demo completa em Ruby on Rails que demonstra todos os conceitos desta documentação:

👉 elven-observability/ruby-otel-app


Configuração de variáveis de ambiente

Copie o arquivo de exemplo e preencha com os dados do seu collector:

Configuração mínima funcional:

Variáveis de identidade do serviço

Variável
Descrição
Default

OTEL_SERVICE_NAME

Nome do serviço. Deve ser estável e único por aplicação.

ruby-rails-traces-demo

OTEL_RESOURCE_ATTRIBUTES

Atributos extras no formato key=value,key2=value2.

OTEL_DEPLOYMENT_ENVIRONMENT

Ambiente: local, staging, production. Lido diretamente no initializer.

Rails.env

Variáveis de export OTLP

Variável
Descrição
Default

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT

Endpoint específico de traces.

http://localhost:4318/v1/traces

OTEL_EXPORTER_OTLP_HEADERS

Headers em key=value. Para tokens, use URL-encoding.

Variáveis de sinais

Variável
Descrição
Default

OTEL_TRACES_EXPORTER

Exporter de traces: otlp ou none.

otlp

OTEL_METRICS_EXPORTER

Desabilitado nesta integração.

none

OTEL_LOGS_EXPORTER

Desabilitado nesta integração.

none

Variáveis de banco

Variável
Descrição

POSTGRES_HOST

Host do PostgreSQL.

POSTGRES_PORT

Porta do PostgreSQL. Default: 5432.

POSTGRES_USER

Usuário do banco.

POSTGRES_PASSWORD

Senha do banco.

DATABASE_URL

URL completa de conexão para desenvolvimento.

DATABASE_TEST_URL

URL completa de conexão para testes.


Bootstrap OpenTelemetry

O initializer do OpenTelemetry deve ser criado em config/initializers/opentelemetry.rb. Ele é responsável por configurar o SDK, o exporter OTLP, o BatchSpanProcessor e ativar as instrumentações automáticas.

Com esse setup:

  • O SDK inicializa antes do primeiro request Rails

  • O BatchSpanProcessor envia spans em lote ao collector

  • As instrumentações automáticas de Rails e Net::HTTP são ativadas explicitamente


Instrumentações automáticas

Com o initializer configurado, as seguintes instrumentações passam a funcionar sem nenhuma alteração no código da aplicação:

Instrumentação
O que gera

OpenTelemetry::Instrumentation::Rails

Span inbound HTTP server para cada request Rails. Span de banco (ActiveRecord) para cada query.

OpenTelemetry::Instrumentation::Net::HTTP

Span outbound HTTP client para cada chamada via Net::HTTP.

Para adicionar outras instrumentações disponíveis no opentelemetry-ruby-contrib, basta incluir a gem correspondente e ativar com c.use no initializer. Exemplos:


Span manual no controller

Defina um tracer por arquivo e envolva o bloco de negócio principal com in_span. Sempre capture o trace_id para retornar na resposta.

O trace_id retornado na resposta é o caminho mais rápido para localizar o trace completo no backend da Elven.


Spans manuais por etapa no service object

Crie um helper with_span no service object para centralizar a criação de spans e o tratamento de erros:

Exemplos de spans manuais recomendados:

  • checkout.validate_input

  • checkout.persist_order

  • checkout.call_internal_service

  • checkout.finalize


Chamada HTTP de saída

Use Net::HTTP normalmente. Com a instrumentação Net::HTTP ativa no initializer, cada chamada gera automaticamente um span outbound correlacionado ao trace da request de origem:

O que isso gera automaticamente:

  • Span outbound HTTP com método, URL e status code

  • Correlação automática com o span pai via propagação de contexto


Captura de erros em spans

Em qualquer bloco de span, registre exceções e defina o status de erro explicitamente:

Isso garante que:

  • A exceção aparece como evento dentro do span no Tempo

  • O span é marcado com status ERROR, visível na árvore de traces

  • O trace_id da resposta pode ser usado para localizar o trace com erro


Estrutura de código relevante


Como rodar localmente

1. Preparar variáveis

2. Subir PostgreSQL

Se a porta 5432 já estiver em uso:

3. Instalar dependências

4. Exportar variáveis do .env

5. Preparar o banco

6. Subir a aplicação

7. Validar saúde

8. Gerar traces de demonstração

Fluxo saudável:

Fluxo com erro forçado:

Resposta esperada (fluxo saudável):

Use o trace_id retornado para localizar o trace completo no backend da Elven.


Como validar no collector da Elven

Após chamar o endpoint, valide no backend nesta ordem:

  1. Filtre por service.name = ruby-rails-traces-demo (ou o nome configurado em OTEL_SERVICE_NAME)

  2. Pesquise pelo trace_id retornado pela API

  3. Confirme a árvore de spans

  4. Confirme o status de erro nos fluxos com force_error=true

Árvore de spans esperada (fluxo saudável)

  1. Span inbound Rails POST /checkout

  2. Span manual checkout.request

  3. Span manual checkout.validate_input

  4. Span manual checkout.persist_order

  5. Span ActiveRecord do INSERT em orders

  6. Span manual checkout.call_internal_service

  7. Span Net::HTTP outbound para /internal/ping

  8. Span manual checkout.finalize

No fluxo com erro

  • Span checkout.finalize com status ERROR

  • Exceção registrada como evento dentro do span

  • Mesmo trace_id disponível na resposta da API


Convenções recomendadas para spans manuais

  1. Nomeie spans com domínio e verbo no formato dominio.acao — ex.: checkout.persist_order, payment.authorize

  2. Evite spans excessivos: instrumente apenas etapas que agregam diagnóstico real

  3. Adicione atributos úteis para investigação, sem expor dados sensíveis

  4. Não coloque PII (CPF, e-mail, token, senha) em atributos de span

  5. Em blocos de erro, sempre use record_exception + status=error

  6. Retorne trace_id em respostas de erro e sucesso para acelerar troubleshooting


Como adaptar para a sua aplicação

Se a aplicação já é Rails

  1. Adicione as gems ao Gemfile e rode bundle install

  2. Crie o initializer em config/initializers/opentelemetry.rb

  3. Ative as instrumentações da sua stack com c.use

  4. Defina as variáveis de ambiente do collector

  5. Envolva etapas críticas de negócio em spans manuais com TRACER.in_span

Se a aplicação usa outros HTTP clients

Substitua opentelemetry-instrumentation-net_http pela gem correspondente:

Se a aplicação usa workers assíncronos

Se a aplicação usa Redis


Testes

Cobrem:

  • Health check (GET /health)

  • Endpoint interno (GET /internal/ping)

  • Checkout com sucesso (persistência + chamada HTTP de saída)

  • Checkout com erro forçado (500 + trace_id na resposta)


Troubleshooting

Não aparecem traces no collector

  1. Confirme OTEL_EXPORTER_OTLP_TRACES_ENDPOINT está correto e acessível

  2. Confirme que OTEL_EXPORTER_OTLP_HEADERS contém o token correto com URL-encoding

  3. Confirme OTEL_TRACES_EXPORTER=otlp

  4. Verifique os logs da app ao subir — as instrumentações devem aparecer como instaladas

  5. Gere uma requisição nova e procure pelo trace_id retornado no JSON

O initializer não é carregado

Confirme que o arquivo está em config/initializers/opentelemetry.rb. O Rails carrega todos os arquivos desse diretório automaticamente no boot.

Spans de banco não aparecem

Confirme que OpenTelemetry::Instrumentation::Rails está ativado no initializer. A instrumentação do Rails já inclui ActiveRecord automaticamente.

Spans de HTTP client não aparecem

Confirme que OpenTelemetry::Instrumentation::Net::HTTP está ativado no initializer e que a chamada HTTP usa Net::HTTP (ou a gem instrumentada correspondente).

Token com caracteres especiais não funciona

Use URL-encoding no valor do header:


Referências


Checklist de deploy

  • [ ] Ruby 3.3.x instalado no ambiente de build

  • [ ] Gems opentelemetry-api, opentelemetry-sdk, opentelemetry-exporter-otlp e instrumentações adicionadas ao Gemfile

  • [ ] Initializer criado em config/initializers/opentelemetry.rb

  • [ ] OTEL_SERVICE_NAME definido

  • [ ] OTEL_RESOURCE_ATTRIBUTES com deployment.environment e service.version

  • [ ] OTEL_EXPORTER_OTLP_TRACES_ENDPOINT apontando para o collector correto

  • [ ] OTEL_EXPORTER_OTLP_HEADERS com token URL-encoded (se necessário)

  • [ ] OTEL_TRACES_EXPORTER=otlp

  • [ ] OTEL_METRICS_EXPORTER=none

  • [ ] OTEL_LOGS_EXPORTER=none

  • [ ] Instrumentações automáticas ativadas com c.use para toda a stack usada

  • [ ] Spans manuais criados para etapas críticas de negócio

  • [ ] record_exception e status=error usados em todos os blocos de rescue

  • [ ] trace_id retornado nas respostas da API

  • [ ] Traces aparecem no Tempo com service.name correto

  • [ ] Árvore de spans reflete o fluxo real da aplicação

Last updated

Was this helpful?