Migrate to EDOT Java from the Elastic APM Java agent
Compared to the Elastic APM Java agent, the Elastic Distribution of OpenTelemetry Java presents a number of advantages:
- Fully automatic instrumentation with zero code changes. No need to modify application code.
- Capture, send, transform, and store data in an OpenTelemetry native way. This includes for example the ability to use all features of the OpenTelemetry SDK for manual tracing, data following semantic conventions, or ability to use intermediate collectors and processors.
- OpenTelemetry Java Instrumentation provides a broad coverage of libraries, frameworks, and applications.
- EDOT Java is built on top of OpenTelemetry SDK and conventions, ensuring compatibility with community tools, vendor-neutral backends, and so on.
Follow these steps to migrate from the legacy Elastic APM Java agent to the Elastic Distribution of OpenTelemetry Java.
-
(Optional) Migrate manual instrumentation API
Migrate usages of the Elastic APM Agent API to OpenTelemetry API:
- For Annotation API, refer to OpenTelemetry Annotations.
- For Transaction API, refer to OpenTelemetry API.
NoteMigration of application code using these APIs and annotations is not strictly required when deploying the EDOT agent. If not migrated, spans, transactions, and metrics that were previously created with those custom API calls and annotations will no longer be generated. OpenTelemetry instrumentation coverage might replace the need for some or all of these custom code changes.
-
Replace configuration options
Refer to the Configuration mapping. Refer to Configuration for ways to provide configuration settings.
-
Replace the agent binary
Remove the
-javaagent:argument that contains the Elastic APM Java agent from the JVM arguments. Then add the-javaagent:argument to the JVM arguments to use EDOT Java, and restart the application or follow Kubernetes instructions or Runtime attach instructions if applicable. Refer to Setup.
The following describes how Elastic APM Java agent configuration maps to EDOT Java. It includes how resource attributes are handled when using the EDOT Collector, followed by each agent setting and its EDOT equivalent.
Ingesting OpenTelemetry data directly through APM Server is no longer supported. Historically, when ingesting OpenTelemetry data through the Elastic APM Server, unmapped resource attributes were added under labels.*. This behavior does not apply when using the EDOT Collector and is not recommended for new deployments. Use the EDOT Collector or Managed OTLP for supported ingestion.
If you rely on specific attribute mappings for querying or filtering in Elastic Observability, configure explicit attribute processors in the EDOT Collector pipeline.
The Elastic server_url option corresponds to the OpenTelemetry OTEL_EXPORTER_OTLP_ENDPOINT option.
The Elastic server_urls option has no equivalent OpenTelemetry option. You can only specify one endpoint.
Use OTEL_EXPORTER_OTLP_ENDPOINT instead.
The Elastic secret_token option corresponds to the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS option.
For example: OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer an_apm_secret_token".
The Elastic api_key option corresponds to the OpenTelemetry OTEL_EXPORTER_OTLP_HEADERS option.
For example:OTEL_EXPORTER_OTLP_HEADERS="Authorization=ApiKey an_api_key".
The Elastic service_name option corresponds to the OpenTelemetry OTEL_SERVICE_NAME option.
The service name value can also be set using OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=service.name=myservice. If OTEL_SERVICE_NAME is set, it takes precedence over the resource attribute.
The Elastic enabled option corresponds to the OpenTelemetry OTEL_JAVAAGENT_ENABLED option.
The Elastic service_version option corresponds to setting the service.version key in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=service.version=1.2.3.
The Elastic 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 global_labels option corresponds to adding key=value comma separated pairs in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=alice=first,bob=second
The Elastic trace_methods option can be replaced by the OTEL_INSTRUMENTATION_METHODS_INCLUDE OpenTelemetry option, however the syntax is different and the ability to use wildcards is more limited.
The Elastic capture_jmx_metrics option can be replaced by
OpenTelemetry JMX Insight feature which is included in EDOT Java.
The JMX Insight feature provides the following benefits:
- Ability to define custom metrics using YAML.
- Capturing metrics with pre-defined metrics by using
OTEL_JMX_TARGET_SYSTEMconfiguration option.
Replace the Elastic capture_headers option with the following options:
otel.instrumentation.http.server.capture-request-headersfor HTTP server requestotel.instrumentation.http.server.capture-response-headersfor HTTP server responseotel.instrumentation.http.client.capture-request-headersfor HTTP client requestotel.instrumentation.http.client.capture-response-headersfor HTTP client responseotel.instrumentation.messaging.experimental.capture-headersfor messaging
The capture_headers option is dynamically adjustable, while the otel.* options are statically set by startup and cannot be subsequently adjusted.
Replace the Elastic span_stack_trace_min_duration option with OTEL_JAVA_EXPERIMENTAL_SPAN_STACKTRACE_MIN_DURATION.
Replace the disable_instrumentations option, which allows to selectively turn off instrumentation (opt-out), with OTEL_INSTRUMENTATION_<name>_ENABLED where <name> is the instrumentation name.
See OpenTelemetry documentation for reference and values.
The enable_instrumentations option allows to turn off all instrumentation enabled by default and selectively enable instrumentation (opt-in) can be replaced with:
OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED=falseto turn off instrumentations enabled by default.OTEL_INSTRUMENTATION_<name>_ENABLED=truewhere<name>is the name of the instrumentation to enable. Refer to OpenTelemetry documentation for reference and values.
The Elastic hostname option corresponds to setting the host.name key in OTEL_RESOURCE_ATTRIBUTES.
For example: OTEL_RESOURCE_ATTRIBUTES=host.name=myhost.
The Elastic service_node_name 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 JVM otherwise metric views cannot be correctly aggregated nor disambiguated
For example: OTEL_RESOURCE_ATTRIBUTES=service.instance.id=myserviceinstance001.
The Elastic cloud_provider option corresponds to the per-provider otel.resource.providers.{provider}.enabled configuration options.
By default, with EDOT otel.resource.providers.{provider}.enabled is set to true, this is equivalent to the cloud_provider default value which is auto, or automatically detect cloud providers. Notice that this behavior differs from the contrib OpenTelemetry distribution.
When the cloud provider is known, or there is none, turning off the non-relevant providers with otel.resource.providers.{provider}.enabled = false allows to minimize the application startup overhead.
The Elastic log_sending option allows capturing and
sending application logs directly to APM Server without storing them on disk and ingesting them with a separate tool.
With EDOT, application logs are automatically captured and sent by default.
This feature is controlled by otel.logs.exporter, which is set to otlp by default. You can turn it off by setting otel.logs.exporter to none.
The Elastic verify_server_cert option allows you to turn off server certificate validation.
With EDOT, the equivalent configuration option is ELASTIC_OTEL_VERIFY_SERVER_CERT (default true), see configuration for details.
The Elastic APM Java agent provided an application_packages setting with multiple purposes, including startup optimization and stack trace filtering. EDOT Java doesn't provide an equivalent configuration for the following reasons:
- EDOT Java does not support package-based scoping to reduce instrumentation overhead at startup. To reduce startup overhead, turn off unneeded instrumentations instead.
- Package-based stack trace filtering (as provided by
application_packages) is not currently supported in Kibana for EDOT data because EDOT stack traces are captured as flat strings rather than structured frames.
The OTEL_JAVA_EXPERIMENTAL_SPAN_STACKTRACE_MIN_DURATION setting controls when stack traces are captured, but it does not provide package-based filtering.
The following limitations apply to EDOT Java.
EDOT Java agent and OpenTelemetry Java instrumentation are only compatible with Java 8 and later.
Support for LDAP client instrumentation is not currently available in EDOT Java.
You can manage EDOT Java configurations through the central configuration feature in the Applications UI.
Refer to Central configuration for more information.
EDOT Java does not implement span compression.
EDOT Java is not sending metrics that power the Breakdown metrics.
There is currently no EDOT Java equivalent for starting the agent with the remote attach capability. The -javaagent: option is the preferred startup mechanism.
A migration path is available for starting the agent with self attach, which is to use runtime attachment. Some limitations apply, and the agent must be started early during application startup.
By default, Micrometer instrumentation is inactive and doesn't capture metrics. To turn it on, use the otel.instrumentation.micrometer.enabled=true setting.
If you're encountering issues during migration, refer to the EDOT Java troubleshooting guide.