Observabilidade
O pacote fornece uma camada completa de observabilidade para aplicações, integrando métricas, rastreamento (tracing) e logs. A implementação encapsula o OpenTelemetry, oferecendo recursos para monitoramento de transações, segmentos, erros e métricas personalizadas.
Configuração
A configuração é realizada automaticamente ao iniciar o colibri-sdk-go. Para exportar os dados para um coletor OpenTelemetry, utilize as seguintes variáveis de ambiente:
| Variável | Obrigatória | Descrição |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | Sim | Endpoint do coletor OTLP — aceita host:porta ou URL completa (ex: http://localhost:4318) |
OTEL_EXPORTER_OTLP_HEADERS | Não | Cabeçalhos no formato chave=valor separados por vírgula (ex: api-key=secret,x-env=prod) |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | Não | Substitui o endpoint apenas para o sinal de métricas. Usa OTEL_EXPORTER_OTLP_ENDPOINT por padrão |
OTEL_SERVICE_NAME | Não | Nome do serviço reportado ao backend. Usa APP_NAME por padrão |
Inicialização
Ao inicializar o Colibri, os seguintes componentes são configurados automaticamente:
- Conexão OpenTelemetry.
- Métricas padrão da aplicação.
- Coleta de métricas de runtime do Go.
Métricas Automáticas
Quando OTEL_EXPORTER_OTLP_ENDPOINT está configurado, o SDK emite automaticamente as seguintes métricas:
- HTTP Server/Client: duração das requisições via
otelfibereotelhttp - Banco de Dados: duração das operações via
otelsql - Go Runtime: heap, GC e goroutines
Componentes Principais
1. Transações de Monitoramento
// Iniciando uma nova transação de monitoramento
txn, ctx := monitoring.StartTransaction(ctx, "MinhaOperacao")
defer monitoring.EndTransaction(txn)
2. Segmentos
// Criando um segmento de transação
segment := monitoring.StartTransactionSegment(ctx, "MinhaOperacao", map[string]string{
"operacao": "consulta",
"tipo": "banco",
})
defer monitoring.EndTransactionSegment(segment)
Atenção: Para que o segmento possa ser relacionado corretamente com a transação, devemos passar o atributo
ctxcriado na transação principal.
3. Rastreamento de Erros
// Notificando erros
if err != nil {
monitoring.NoticeError(txn, err)
return err
}
4. Métricas Personalizadas
O SDK expõe três tipos de instrumentos de métricas via o pacote monitoring:
Counter
Contador monotonicamente crescente para medir ocorrências de eventos.
import "github.com/colibriproject-dev/colibri-sdk-go/pkg/base/monitoring"
requests := monitoring.Counter("app.requests", "Total de requisições HTTP", "1")
requests.Add(ctx, 1, map[string]string{"route": "/api/users"})
Histogram
Registra a distribuição de valores, ideal para medir durações e tamanhos.
duration := monitoring.Histogram("app.request.duration", "Duração das requisições", "ms")
duration.Record(ctx, elapsed.Milliseconds(), map[string]string{"status": "200"})
Gauge
Captura o valor atual de uma medida em um instante de tempo.
activeConns := monitoring.Gauge("app.connections.active", "Conexões ativas", "1")
activeConns.Record(ctx, float64(count), nil)
Exemplos de Uso
1. Monitoramento de Serviços Externos
func (s *Service) ChamarAPIExterna(ctx context.Context) error {
segment := monitoring.StartTransactionSegment(ctx, "API_Pagamento")
defer monitoring.EndTransactionSegment(segment)
resp, err := http.Get("https://api.externa.com/recurso")
if err != nil {
monitoring.NoticeError(monitoring.GetTransactionInContext(ctx), err)
return err
}
defer resp.Body.Close()
return nil
}
2. Métricas Personalizadas em um Serviço
var (
pedidosProcessados = monitoring.Counter("orders.processed", "Pedidos processados", "1")
tempoDeProcesamento = monitoring.Histogram("orders.processing_time", "Tempo de processamento", "ms")
tamanhoDaFila = monitoring.Gauge("orders.queue_size", "Tamanho da fila", "1")
)
func (s *Service) ProcessarPedido(ctx context.Context, order Order) error {
start := time.Now()
if err := s.process(ctx, order); err != nil {
return err
}
pedidosProcessados.Add(ctx, 1, map[string]string{"status": "success"})
tempoDeProcesamento.Record(ctx, float64(time.Since(start).Milliseconds()), nil)
tamanhoDaFila.Record(ctx, float64(s.queue.Len()), nil)
return nil
}
Boas Práticas
-
Nomeação de Transações:
- Use nomes descritivos e consistentes
- Siga um padrão de nomenclatura
- Evite nomes dinâmicos
-
Gestão de Contexto:
- Sempre propague o contexto
- Use defer para finalizar transações
- Mantenha o ciclo de vida correto
-
Atributos:
- Adicione atributos relevantes
- Não adicione dados sensíveis
- Use chaves consistentes
-
Erros:
- Notifique erros relevantes
- Adicione contexto aos erros
- Evite notificar erros esperados
-
Métricas:
- Declare instrumentos como variáveis globais (evita recriação a cada chamada)
- Prefira nomes no padrão
dominio.objeto.acao(ex:app.requests.total) - Use unidades padronizadas:
1para contadores adimensionais,mspara milissegundos,Bypara bytes
-
Performance:
- Monitore tempos de resposta
- Observe uso de recursos
- Identifique gargalos
-
Segurança:
- Não registre dados sensíveis nos logs ou atributos
- Respeite as leis de proteção de dados