Loading

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).

  1. 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
    		
  2. 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, the require('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 in NODE_OPTIONS environment variable, remove it there.

  3. (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.

  4. Replace configuration options

    Refer to the Configuration mapping. Refer to Configuration for details on EDOT Node.js configuration.

  5. 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 the NODE_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.

Warning

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 using OTEL_TRACES_EXPORTER=none turns off context-propagation. The ELASTIC_OTEL_CONTEXT_PROPAGATION_ONLY EDOT Node.js setting only impacts tracing, as opposed to the APM agent contextPropagationOnly which impacts both tracing and metric collection.
  • To turn off metrics sending and collection overhead, use the following settings:

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:

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".

Note

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:

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.

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:

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.