O OpenTelemetry Collector no Node.js cria uma camada intermediária entre as aplicações e os backends de observabilidade. Em vez de cada serviço enviar traces, métricas e logs diretamente para Jaeger, Prometheus, Tempo, Loki ou uma plataforma comercial, o processo exporta OTLP para o Collector, que aplica batch, retry, filas, filtros, redaction e roteamento.
Essa arquitetura reduz acoplamento e remove lógica operacional do processo Node.js. A aplicação precisa produzir telemetria e enviá-la rapidamente; o Collector cuida da entrega, transformação e integração com múltiplos destinos. Porém, ele também se torna parte crítica da infraestrutura e precisa de limites, segurança, monitoramento e dimensionamento.
Neste guia, você aprenderá a executar o OpenTelemetry Collector, configurar receivers, processors, exporters e pipelines, integrar uma aplicação Node.js por OTLP, proteger dados sensíveis e escolher entre agent, gateway e agent-to-gateway.
O que é o OpenTelemetry Collector?
O OpenTelemetry Collector é uma implementação vendor-neutral para receber, processar e exportar telemetria. Ele trabalha com traces, métricas e logs e pode enviar os mesmos dados para backends diferentes.
A documentação recomenda o uso do Collector na maioria dos ambientes porque ele permite descarregar rapidamente dados da aplicação e aplicar recursos como:
- batch;
- retry;
- criptografia;
- filtros;
- redação de dados;
- sampling;
- roteamento;
- filas persistentes;
- transformações.
Componentes principais
Uma configuração do Collector é formada por quatro grupos:
- receivers: recebem OTLP, Prometheus, Jaeger e outros protocolos;
- processors: aplicam batch, filtros, atributos, sampling e limites;
- exporters: enviam os dados aos destinos;
- extensions: adicionam health check, autenticação, storage e administração.
Os componentes só são executados quando aparecem em uma pipeline dentro de service.pipelines.
Executando com Docker
docker run --rm \
-p 4317:4317 \
-p 4318:4318 \
-p 13133:13133 \
-v "$PWD/otel-collector.yaml:/etc/otelcol-contrib/config.yaml" \
otel/opentelemetry-collector-contrib:latestEm produção, fixe uma versão específica. A distribuição contrib inclui mais componentes que a distribuição core, aumentando compatibilidade e também a superfície de atualização.
Configuração mínima
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch: {}
exporters:
debug:
verbosity: basic
extensions:
health_check:
endpoint: 0.0.0.0:13133
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [debug]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [debug]
logs:
receivers: [otlp]
processors: [batch]
exporters: [debug]O exporter debug é útil localmente. Em produção, ele pode gerar volume excessivo e expor atributos.
Instalando OpenTelemetry no Node.js
npm install \
@opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-proto \
@opentelemetry/exporter-metrics-otlp-protoConsulte OpenTelemetry no Node.js para instrumentação automática, recursos e spans manuais.
Exportando traces por OTLP HTTP
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??
'http://localhost:4318/v1/traces'
}),
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start();Inicialize o SDK antes de importar frameworks e clientes instrumentados.
Configuração por ambiente
OTEL_SERVICE_NAME=orders-api
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,service.version=1.4.0Não inclua tokens ou dados pessoais em resource attributes.
Batch processor
processors:
batch:
timeout: 5s
send_batch_size: 1024
send_batch_max_size: 2048Batch reduz chamadas ao backend e melhora throughput. Valores grandes aumentam memória e atraso. Ajuste com métricas reais.
Memory limiter
processors:
memory_limiter:
check_interval: 1s
limit_mib: 512
spike_limit_mib: 128Coloque o memory limiter no início da lista de processors:
processors: [memory_limiter, batch]Ele reduz risco de OOM ao aplicar backpressure e rejeição controlada durante pressão de memória.
Enviando traces ao Jaeger
exporters:
otlp/jaeger:
endpoint: jaeger:4317
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/jaeger]Veja Jaeger no Node.js para análise de traces distribuídos.
Enviando traces ao Grafana Tempo
exporters:
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: trueUse TLS e autenticação quando o destino não estiver em rede totalmente confiável. O próximo artigo aprofunda Tempo.
Métricas para Prometheus
exporters:
prometheus:
endpoint: 0.0.0.0:9464
service:
pipelines:
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheus]Prometheus coleta o endpoint exposto. Consulte Métricas Prometheus no Node.js.
Logs para Loki
Em versões e distribuições compatíveis, use exporter OTLP ou um componente suportado pelo backend. Uma alternativa é enviar logs via OTLP para um gateway que encaminha ao Loki.
Veja Grafana Loki no Node.js para labels e LogQL.
Attributes processor
processors:
attributes/redact:
actions:
- key: http.request.header.authorization
action: delete
- key: user.email
action: delete
- key: payment.card_number
action: deleteRedija antes de exportar. O melhor local para impedir dados sensíveis ainda é a instrumentação da aplicação, mas o Collector oferece uma camada adicional.
Transform processor
processors:
transform:
trace_statements:
- context: span
statements:
- delete_key(attributes, "enduser.id")
- set(attributes["deployment.region"], "sa-east-1")
where attributes["deployment.region"] == nilTransformações usam uma linguagem específica. Teste configurações e trate erros como falha de deploy.
Filter processor
processors:
filter/drop-health:
traces:
span:
- 'attributes["http.route"] == "/health"'Remover health checks reduz volume, mas pode esconder sinais operacionais. Mantenha métricas separadas para disponibilidade.
Tail sampling
processors:
tail_sampling:
decision_wait: 10s
num_traces: 50000
policies:
- name: errors
type: status_code
status_code:
status_codes: [ERROR]
- name: slow
type: latency
latency:
threshold_ms: 1000
- name: baseline
type: probabilistic
probabilistic:
sampling_percentage: 5Tail sampling decide após observar o trace. Ele mantém erros e traces lentos, mas exige que todos os spans do mesmo trace cheguem à mesma instância ou sejam roteados de forma consistente.
Head sampling versus tail sampling
Head sampling acontece no SDK e reduz volume cedo. Tail sampling possui mais contexto, mas consome memória e adiciona atraso. Muitas arquiteturas combinam parent-based sampling no SDK com tail sampling no gateway.
Fila persistente
Exporters podem usar sending queue e storage:
extensions:
file_storage:
directory: /var/lib/otelcol
exporters:
otlp/backend:
endpoint: backend:4317
sending_queue:
enabled: true
storage: file_storage
queue_size: 10000
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 10mMonte volume persistente e monitore disco. Uma fila ilimitada apenas troca OOM por falta de espaço.
Agent pattern
Um Collector roda próximo de cada aplicação ou nó. Vantagens:
- endpoint local;
- menor latência;
- coleta de logs e métricas do host;
- isolamento por nó.
A desvantagem é administrar muitas instâncias.
Gateway pattern
Serviços enviam para um conjunto central de Collectors. Vantagens:
- configuração central;
- tail sampling;
- roteamento por tenant;
- menos conexões aos backends.
O gateway precisa de alta disponibilidade e balanceamento.
Agent-to-gateway
Agents recebem localmente, aplicam batch e encaminham aos gateways, que executam sampling e exportação. Esse padrão combina coleta próxima e processamento central.
Kubernetes
Em Kubernetes:
- DaemonSet para agent;
- Deployment para gateway;
- Service para OTLP;
- ConfigMap para configuração;
- Secret para credenciais;
- PersistentVolume quando houver fila em disco.
Configure readiness, liveness e recursos. Veja Probes Kubernetes em Node.js.
Balanceamento e traces
Tail sampling exige afinidade por trace ID. Use load balancing exporter ou arquitetura recomendada pela versão do Collector. Um balanceador L4 aleatório pode dividir spans entre instâncias.
Segurança de rede
- Não exponha portas OTLP publicamente.
- Use TLS.
- Autentique clientes.
- Restrinja egress.
- Separe tenants.
- Redija atributos.
- Proteja health e debug endpoints.
TLS no receiver
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
tls:
cert_file: /certs/server.crt
key_file: /certs/server.keyAutenticação
Extensions de autenticação podem validar headers ou credenciais. Use mecanismos suportados pela distribuição e política da organização. Não inclua segredos diretamente no YAML versionado.
Internal telemetry
Monitore o próprio Collector:
- dados recebidos;
- dados exportados;
- falhas;
- fila;
- retries;
- memória;
- CPU;
- spans descartados;
- latência do exporter.
Sem essa telemetria, o pipeline pode perder dados silenciosamente.
Health check
extensions:
health_check:
endpoint: 0.0.0.0:13133Health indica que o processo responde, não necessariamente que todos os backends estão saudáveis. Crie alertas a partir das métricas de exportação.
Dimensionamento
Faça teste de carga com volume representativo. A capacidade depende de:
- quantidade de spans;
- tamanho dos atributos;
- processors;
- sampling;
- número de exporters;
- latência dos backends;
- fila e batch.
Use Autocannon no Node.js para gerar carga na aplicação e observar o pipeline.
Atualizações
Componentes do Collector possuem níveis de estabilidade diferentes. Antes de atualizar:
- leia changelog;
- valide componentes usados;
- execute teste de configuração;
- implante em canary;
- compare perda e latência;
- tenha rollback.
Erros comuns
- Receiver sem pipeline: componente não inicia.
- Sem memory limiter: Collector sofre OOM.
- Batch enorme: memória e atraso crescem.
- Tail sampling sem afinidade: traces ficam incompletos.
- Fila sem limite: disco esgota.
- OTLP público: ingestão pode ser abusada.
- Dados sensíveis: atributos vazam.
- Sem métricas internas: perda não é detectada.
Configuração recomendada
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
memory_limiter:
check_interval: 1s
limit_mib: 512
spike_limit_mib: 128
attributes/redact:
actions:
- key: http.request.header.authorization
action: delete
batch:
timeout: 5s
send_batch_size: 1024
exporters:
otlp/backend:
endpoint: observability-backend:4317
tls:
insecure: false
sending_queue:
enabled: true
retry_on_failure:
enabled: true
extensions:
health_check: {}
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, attributes/redact, batch]
exporters: [otlp/backend]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/backend]
logs:
receivers: [otlp]
processors: [memory_limiter, attributes/redact, batch]
exporters: [otlp/backend]Conclusão
O OpenTelemetry Collector no Node.js desacopla a aplicação dos backends de observabilidade e centraliza batch, retry, filtros, sampling e roteamento. A aplicação exporta OTLP rapidamente, enquanto o Collector administra a entrega.
Use memory limiter, filas controladas, TLS, redaction e métricas internas. Com agent ou gateway bem dimensionado, o Collector torna a observabilidade mais resiliente sem colocar toda a complexidade dentro dos processos Node.js.




