Aplicativos JavaScript em Containers com o Agent otel-agent-nodejs-v2
Esta documentação detalha como instrumentar um aplicativo Node.js contêinerizado utilizando o agente Elven Observability (otel-agent-nodejs-v2
) para coletar traces e métricas via OpenTelemetry (OTel).
1. Instalação do Agent no Container
No seu Dockerfile
, instale o agente com os seguintes comandos:
# Usando Yarn
RUN yarn add otel-agent-nodejs-v2
# Ou usando NPM
RUN npm install otel-agent-nodejs-v2 --save --ignore-scripts
O –ignore-scripts é importante para evitar a execução de scripts automáticos durante a instalação que não são necessários neste contexto.
Dockerfile de exemplo:
FROM node:20-alpine as build
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
# Intall OpenTelemetry
RUN yarn add otel-agent-nodejs-v2
RUN yarn build
RUN yarn prisma generate
FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./
COPY --from=build /app/prisma ./prisma
RUN apk add --no-cache openssl
CMD ["node", "dist/index.js"]
2. Configuração das Variáveis de Ambiente
Inclua as seguintes variáveis de ambiente no seu runtime (ECS, EC2, Kubernetes, Docker Compose, etc). Elas ativam a instrumentação automática e definem o destino dos dados:
- name: NODE_OPTIONS
value: "--require @opentelemetry/auto-instrumentations-node/register"
- name: OTEL_SERVICE_NAME
value: "eo-bff"
- name: RESOURCES_ATTRIBUTES
value: "service=eo-bff,environment=production"
- name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
value: "http://seu_collector_endpoint.com:4318/v1/metrics"
- name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
value: "http://seu_collector_endpoint.com:4318/v1/traces"
- name: OTEL_NODE_DISABLED_INSTRUMENTATIONS
value: "fs"
- name: OTEL_METRICS_EXPORTER
value: "otlp"
- name: OTEL_TRACES_EXPORTER
value: "otlp"
- name: OTEL_METRICS_EXEMPLAR_FILTER
value: "always_on"
Explicação das variáveis principais:
NODE_OPTIONS
: Garante que a instrumentação automática do Node.js seja carregada em runtime.OTEL_SERVICE_NAME
: Nome do serviço para identificação no backend.RESOURCES_ATTRIBUTES
: Atributos adicionais que enriquecem as spans e métricas (por exemplo: ambiente, versão, etc).OTEL_EXPORTER_OTLP_*
: URLs para onde as métricas e traces serão enviadas via OTLP (OpenTelemetry Protocol).OTEL_NODE_DISABLED_INSTRUMENTATIONS
: Instrumentações a serem desabilitadas (por exemplo:fs
, que gera ruído).OTEL_METRICS_EXEMPLAR_FILTER
: Define como os exemplares de métricas serão coletados (ideal manteralways_on
).
3. Exemplos por Ambiente
Docker Compose
env_file:
- .env
environment:
- NODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register
- OTEL_SERVICE_NAME=eo-api
... # demais variáveis
Kubernetes
spec:
containers:
- name: node-app
image: node-app:latest
env:
- name: NODE_OPTIONS
value: "--require @opentelemetry/auto-instrumentations-node/register"
- name: OTEL_SERVICE_NAME
value: "eo-api"
... # demais variáveis
ECS (Fargate ou EC2)
"environment": [
{ "name": "NODE_OPTIONS", "value": "--require @opentelemetry/auto-instrumentations-node/register" },
{ "name": "OTEL_SERVICE_NAME", "value": "eo-api" },
...
]
Execução Local
NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" \\
OTEL_SERVICE_NAME=eo-api \\
RESOURCES_ATTRIBUTES="service=eo-api,environment=local" \\
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces \\
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://localhost:4318/v1/metrics \\
npm run start
4. Coletor (Collector Endpoint)
As variáveis OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
e OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
devem apontar para o collector HTTP na porta 4318 (padrão OTLP HTTP). Este collector pode estar no mesmo container, host, VPC ou cluster.
Se você estiver usando o Elven Observability, garanta que seu Collector esteja:
- Escutando em
0.0.0.0:4318
- Configurado para receber OTLP via HTTP (traces e metrics)
- Exportando para o backend (Grafana Tempo, Mimir, etc)
5. Validação
Verifique se as métricas e traces estão chegando:
- No Grafana, veja em Explore > Tempo ou Explore > Metrics com os filtros por
service.name="eo-bff"
- Também é possível ativar logs via OTEL para debug com
OTEL_LOG_LEVEL=debug
6. Troubleshooting
- Nada aparece no Grafana: verifique se as URLs dos endpoints estão acessíveis do container e se o Collector está escutando corretamente.
- Problemas com
NODE_OPTIONS
: certifique-se de que está setado antes da execução do Node.js. - Traces incompletos: verifique se há bibliotecas não instrumentadas manualmente ou bloqueios async/await.
- Variáveis ignoradas: algumas plataformas (como ECS ou Kubernetes) podem sobrescrever ou não aplicar corretamente as variáveis, revise o manifest/tarefa.
- Collector fora do ar: verifique logs do collector para garantir que ele está aceitando conexões na porta 4318.
7. Boas Práticas
- Use
OTEL_SERVICE_NAME
descritivo e padronizado (ex:project-env-component
). - Utilize
RESOURCES_ATTRIBUTES
comenvironment
,version
,owner
etc, para enriquecer os dados. - Desabilite instrumentações não utilizadas com
OTEL_NODE_DISABLED_INSTRUMENTATIONS
. - Evite instrumentar ambientes de desenvolvimento com muitos spans desnecessários.
- Ative exemplares com
OTEL_METRICS_EXEMPLAR_FILTER=always_on
para correlacionar traces com métricas.
8. Exemplo de .env pronto
NODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register
OTEL_SERVICE_NAME=eo-bff
RESOURCES_ATTRIBUTES=service=eo-bff,environment=production
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://seu_collector_endpoint.com:4318/v1/metrics
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://seu_collector_endpoint.com:4318/v1/traces
OTEL_NODE_DISABLED_INSTRUMENTATIONS=fs
OTEL_METRICS_EXPORTER=otlp
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXEMPLAR_FILTER=always_on
Para dúvidas ou melhorias neste processo, entre em contato com o time do Elven Observability. Esta instrumentação é pensada para funcionar sem modificação no código, com suporte automático a bibliotecas populares como express
, http
, axios
, pg
, entre outras.
Pronto! Seu app Node.js agora está instrumentado com o Elven Observability usando OpenTelemetry. 🌟