JavaScript Instrumentation in Containers
JavaScript Applications in Containers with the otel-agent-nodejs-v2 Agent
This documentation details how to instrument a containerized Node.js application using the Elven Observability agent (otel-agent-nodejs-v2
) to collect traces and metrics via OpenTelemetry (OTel).
Agent Installation in the Container
In your Dockerfile
, install the agent using the following commands:
# Using Yarn
RUN yarn add otel-agent-nodejs-v2
# Or using NPM
RUN npm install otel-agent-nodejs-v2 --save --ignore-scripts
Information: The --ignore-scripts flag is important to prevent the execution of automatic scripts during installation that are not necessary in this context.
Example Dockerfile:
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"]
Environment Variable Configuration
Include the following environment variables in your runtime (ECS, EC2, Kubernetes, Docker Compose, etc). They enable automatic instrumentation and define the destination of the data:
- 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://your_collector_endpoint.com:4318/v1/metrics"
- name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
value: "http://your_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"
Explanation of main variables:
NODE_OPTIONS
: Ensures that automatic instrumentation for Node.js is loaded at runtime.OTEL_SERVICE_NAME
: Name of the service for identification in the backend.RESOURCES_ATTRIBUTES
: Additional attributes that enrich spans and metrics (e.g., environment, version, etc).OTEL_EXPORTER_OTLP_*
: URLs where metrics and traces will be sent via OTLP (OpenTelemetry Protocol).OTEL_NODE_DISABLED_INSTRUMENTATIONS
: Instrumentations to be disabled (e.g., fs, which generates noise).OTEL_METRICS_EXEMPLAR_FILTER
: Defines how metric exemplars will be collected (ideally keep always_on).
Examples by Environment
Docker Compose
env_file:
- .env
environment:
- NODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register
- OTEL_SERVICE_NAME=eo-api
... # Other Variables
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"
... # Other Variables
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
Collector (Collector Endpoint)
The OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
e OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
variables must point to the HTTP collector on port 4318 (default OTLP HTTP). This collector can be in the same container, host, VPC, or cluster.
If you are using Elven Observability, ensure that your Collector is:
Listening on
0.0.0.0:4318.
Configured to receive OTLP via HTTP (traces and metrics).
Exporting to the backend (Grafana Tempo, Mimir, etc).
Validation
Verify if metrics and traces are being received:
In Grafana, go to Explore > Tempo or Explore > Metrics with filters by
service.name="eo-bff"
It is also possible to enable logs via OTEL for debugging using
OTEL_LOG_LEVEL=debug
Troubleshooting
Nothing appears in Grafana: check if the endpoint URLs are accessible from the container and if the Collector is listening properly.
Issues with
NODE_OPTIONS
: make sure it is set before running Node.jsIncomplete traces: check for libraries that are not manually instrumented or async/await blocks.
Ignored variables: some platforms (like ECS or Kubernetes) may override or not apply environment variables correctly, review the manifest/task definition.
Collector is down: check the collector logs to ensure it is accepting connections on port 4318
Best Practices
Use a
OTEL_SERVICE_NAME
that is descriptive and standardized (e.g., project-env-component).Use
RESOURCES_ATTRIBUTES
withenvironment
,version
,owner
etc, to enrich the data.Disable unused instrumentations with
OTEL_NODE_DISABLED_INSTRUMENTATIONS
.Avoid instrumenting development environments with too many unnecessary spans.
Enable exemplars with
OTEL_METRICS_EXEMPLAR_FILTER=always_on
to correlate traces with metrics.
Ready .env example
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
For questions or improvements to this process, contact the Elven Observability team.
This instrumentation is designed to work without code modification, with automatic support for popular libraries such as express
, http
, axios
, pg
, among others.
Done! Your Node.js app is now instrumented with Elven Observability using OpenTelemetry.
Last updated
Was this helpful?