Migrate to EDOT Node.js from the Elastic APM Node.js agent
Stack Serverless Observability EDOT Node.js
Compared to the Elastic APM Node.js agent, the Elastic Distribution of OpenTelemetry Node.js presents a number of advantages:
- Fully automatic instrumentation with zero code changes. No need to modify application code.
- EDOT Node.js is built on top of OpenTelemetry SDK and conventions, ensuring compatibility with community tools, vendor-neutral backends, and so on.
- Modular, extensible architecture based on the OpenTelemetry SDK. You can add custom exporters, processors, and samplers.
- You can use EDOT Node.js in environments where both tracing and metrics are collected using OpenTelemetry.
Follow these steps to migrate from the legacy Elastic APM PHP agent (elastic-apm-node
) to the Elastic Distribution of OpenTelemetry PHP (@elastic/opentelemetry-node
).
-
Replace the Node.js package
Remove the Elastic APM Node.js Agent package and install EDOT Node.js:
npm uninstall elastic-apm-node npm install --save @elastic/opentelemetry-node
-
Remove APM Node.js start method
For services starting the APM Node.js Agent by using
require()
with the require and start or require start module methods, therequire('elastic-apm-node')
, remove the code.For services starting with the
--require
Node.js CLI option, remove the option. If the--require
option is defined inNODE_OPTIONS
environment variable, remove it there. -
(Optional) Migrate manual instrumentation API
If you're using the Elastic APM Node.js Agent API to create manual transactions and spans you should refactor the code to use
@opentelemetry/api
methods. OpenTelemetry documentation has several examples of how to create spans manually. -
Replace configuration options
Refer to the Configuration mapping. Refer to Configuration for details on EDOT Node.js configuration.
-
Add EDOT Node.js start method
Use the Node.js
--import
option to start EDOT Node.js with your service.Set it on the command-line using
node --import @elastic/opentelemetry-node service.js
or in theNODE_OPTIONS
environment variable:NODE_OPTIONS="--import @elastic/opentelemetry-node" node service.js
.
This list contains Elastic APM Node.js agent configuration options that can be migrated to EDOT Node.js SDK configuration because they have an equivalent in OpenTelemetry.
The Elastic APM Node.js agent active
option corresponds to the OpenTelemetry OTEL_SDK_DISABLED option but it has the opposite meaning.
Set the OTEL_SDK_DISABLED
to true
if you want to deactivate the agent. For example: OTEL_SDK_DISABLED=true
.
The Elastic APM Node.js agent apiKey
option corresponds to setting the Authorization
header in the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS option.
For example:OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey an_api_key"
.
The Elastic APM Node.js agent apmClientHeaders
option corresponds to the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS
option.
For example: OTEL_EXPORTER_OTLP_HEADERS=foo=bar,baz=quux
.
The Elastic APM Node.js agent centralConfig
option corresponds to the EDOT Node.js ELASTIC_OTEL_OPAMP_ENDPOINT
option.
For example: export ELASTIC_OTEL_OPAMP_ENDPOINT=http://localhost:4320/v1/opamp
.
To use central configuration for EDOT Node.js it is necessary to enable it by following the configuration guide. Also there is a difference in which options can be configured. You can find a list in central configuration settings.
The Elastic APM Node.js agent cloudProvider
option does not correspond directly to an OpenTelemetry option but you can get similar behavior by properly setting OTEL_NODE_RESOURCE_DETECTORS
option. If you set this option make sure you add along with the cloud detector the non-cloud detectors that apply to your service. For a full list of detectors check OTEL_NODE_RESOURCE_DETECTORS details. Not setting this option is the equivalent of auto
.
For example: OTEL_NODE_RESOURCE_DETECTORS=os,env,host,serviceinstance,process,aws
will make the agent query for AWS metadata only and use other non-cloud detectors to enrich that metadata.
The equivalent of the Elastic APM Node.js agent contextPropagationOnly
option can be accomplished with the following EDOT Node.js settings:
ELASTIC_OTEL_CONTEXT_PROPAGATION_ONLY=true
to configure trace-context propagation. This turns off sending spans and the overhead from doing so. Note that usingOTEL_TRACES_EXPORTER=none
turns off context-propagation. TheELASTIC_OTEL_CONTEXT_PROPAGATION_ONLY
EDOT Node.js setting only impacts tracing, as opposed to the APM agentcontextPropagationOnly
which impacts both tracing and metric collection.- To turn off metrics sending and collection overhead, use the following settings:
OTEL_METRICS_EXPORTER=none
to turn off the sending of any metrics.ELASTIC_OTEL_HOST_METRICS_DISABLED=true
to remove the overhead from metrics collection by the@opentelemetry/host-metrics
package.OTEL_NODE_DISABLED_INSTRUMENTATIONS=runtime-node
to remove metrics collection overhead from the@opentelemetry/instrumentation-runtime-node
instrumentation
For example:
ELASTIC_OTEL_CONTEXT_PROPAGATION_ONLY=true
OTEL_METRICS_EXPORTER=none
ELASTIC_OTEL_HOST_METRICS_DISABLED=true
OTEL_NODE_DISABLED_INSTRUMENTATIONS=runtime-node
The Elastic APM Node.js agent disableInstrumentations
option corresponds to the EDOT Node.js OTEL_NODE_DISABLED_INSTRUMENTATIONS
option.
For example: OTEL_NODE_DISABLED_INSTRUMENTATIONS=express,mysql
.
The Elastic APM Node.js agent disableMetrics
option does not correspond to any OpenTelemetry option.
However if you want to disable all metrics (equivalent to disableMetrics='*'
) you can use OTEL_METRICS_EXPORTER
option. Set it to none
to disable the collection of all metrics.
For example: OTEL_METRICS_EXPORTER=none
.
The Elastic APM Node.js agent disableSend
does not correspond to a single OpenTelemetry option. You can get the same behavior by setting to the value none
on the following environment vars dedicated to exporter selection. Note that you have control per signal.
OTEL_TRACES_EXPORTER
for traces.OTEL_METRICS_EXPORTER
for metrics.OTEL_LOGS_EXPORTER
for logs.
For example OTEL_TRACES_EXPORTER=none OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=none
will completely disable sending but OTEL_TRACES_EXPORTER=none
will disable only the sending of traces.
The Elastic APM Node.js agent environment
option corresponds to setting the deployment.environment.name
key in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=testing
.
The Elastic APM Node.js agent globalLabels
option corresponds to adding key=value
comma separated pairs in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=alice=first,bob=second
. Such labels will result in labels.key=value attributes on the server. For example, labels.alice=first
.
The Elastic APM Node.js agent hostname
option corresponds to setting the host.name
key in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=host.name=myhost
.
The Elastic APM Node.js agent instrument
option can be achieved with OTEL_NODE_ENABLED_INSTRUMENTATIONS
option.
For example: OTEL_NODE_ENABLED_INSTRUMENTATIONS=none
will make EDOT Node.js instrument no packages. It is equivalent to instrument=false
.
Because "none" is not an instrumentation name EDOT Node.js will log a message saying so. The message will have the following format.
{"name":"elastic-otel-node","level":40,"msg":"Unknown instrumentation \"none\" specified in environment variable \"OTEL_NODE_ENABLED_INSTRUMENTATIONS\"","time":"2025-09-01T11:12:30.949Z"}
The Elastic APM Node.js agent logLevel
option corresponds to the OpenTelemetry OTEL_LOG_LEVEL
option.
The following table shows the equivalent values of log levels between elastic-apm-node
and EDOT Node.js.
ELASTIC_APM_LOG_LEVEL | OTEL_LOG_LEVEL |
---|---|
off |
none |
error |
error |
warn |
warn |
info |
info |
debug |
debug |
trace |
verbose |
trace |
all |
The Elastic APM Node.js agent longFieldMaxLength
option does not correspond directly to an OpenTelemetry option but you can get similar behavior by properly setting OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT
option. This limit can also be set for specific signals.
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
for traces.OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT
for logs.
For example: OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=1000
will limit attribute string values to a thousand characters.
The Elastic APM Node.js agent maxQueueSize
option corresponds to a couple of OpenTelemetry options:
OTEL_BSP_MAX_QUEUE_SIZE
option to set the queue size for spans.OTEL_BLRP_MAX_QUEUE_SIZE
option to set the queue size for logs.
For example: OTEL_BSP_MAX_QUEUE_SIZE=2048 OTEL_BLRP_MAX_QUEUE_SIZE=4096
.
The Elastic APM Node.js agent metricsInterval
option corresponds to the OpenTelemetry OTEL_METRIC_EXPORT_INTERVAL
option.
For example: OTEL_METRIC_EXPORT_INTERVAL=30000
.
The Elastic APM Node.js agent secretToken
option corresponds to setting the Authorization
header in the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS option.
For example: OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer an_apm_secret_token"
.
Secret token usage is discouraged. Use API keys for authentication.
The Elastic APM Node.js agent serverTimeout
option corresponds to a OpenTelemetry options per signal:
OTEL_BLRP_EXPORT_TIMEOUT
option for logs.OTEL_BSP_EXPORT_TIMEOUT
option for spans.OTEL_METRIC_EXPORT_TIMEOUT
option for metrics.
For example: OTEL_BSP_EXPORT_TIMEOUT=50000 OTEL_BLRP_EXPORT_TIMEOUT=50000 OTEL_METRIC_EXPORT_TIMEOUT=50000
.
The Elastic APM Node.js agent serverUrl
option corresponds to the OpenTelemetry OTEL_EXPORTER_OTLP_ENDPOINT
option.
If using Elastic Cloud Serverless, set
OTEL_EXPORTER_OTLP_ENDPOINT
to the Elastic Cloud Managed OTLP Endpoint URL for your Serverless project. For example,OTEL_EXPORTER_OTLP_ENDPOINT=https://my-prj-a1b2c3.ingest.eu-west-1.aws.elastic.cloud
. Refer to the Quickstart for Elastic Cloud Serverless.If using Elastic Cloud Hosted or Self-managed, set
OTEL_EXPORTER_OTLP_ENDPOINT
to the endpoint URL of your EDOT Collector. Refer to the Quickstart for Elastic Cloud Hosted or the Quickstart for Self-managed.
The Elastic APM Node.js agent serviceName
option corresponds to the OpenTelemetry OTEL_SERVICE_NAME option.
You can also set the service name using OTEL_RESOURCE_ATTRIBUTES. For example: OTEL_RESOURCE_ATTRIBUTES=service.name=myservice
. A value in OTEL_SERVICE_NAME
takes precedence over a service.name
value in OTEL_RESOURCE_ATTRIBUTES
.
The Elastic APM Node.js agent serviceNodeName
option corresponds to setting the service.instance.id
key in OTEL_RESOURCE_ATTRIBUTES. Warning: by default this is a generated unique ID; if you set this it must be a unique value for each service instance otherwise metric views cannot be correctly aggregated or disambiguated.
For example: OTEL_RESOURCE_ATTRIBUTES=service.instance.id=myserviceinstance001
.
The Elastic APM Node.js agent serviceVersion
option corresponds to setting the service.version
key in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=service.version=1.2.3
.
The Elastic APM Node.js agent transactionSampleRate
corresponds to the OpenTelemetry OTEL_TRACES_SAMPLER
and OTEL_TRACES_SAMPLER_ARG
options.
For example, for the equivalent of transactionSampleRate: '0.25'
use OTEL_TRACES_SAMPLER=parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG=0.25
.
The following limitations apply to EDOT Node.js.
EDOT Node.js and OpenTelemetry SDK support Node.js versions in the range ^18.19.0 || >=20.6.0
. Elastic APM Node.js works with Node.js versions >=14.17.0
, though with limited support for Node.js 14 and 16 given that those major versions of Node.js are out of long-term support.
EDOT Node.js doesn't currently support instrumentation for AWS Lambda and Azure Functions. However, there are contrib and third-party options based on OpenTelemetry:
- For AWS Lambda use OpenTelemetry Lambda layers.
- For Azure Functions you can configure OpenTelemetry.
You can manage EDOT Node.js configurations through the central configuration feature in the Applications UI.
Refer to Central configuration for more information.
EDOT Node.js does not implement span compression.
If you're encountering issues during migration, refer to the EDOT Node.js troubleshooting guide.