Elastic Observability vs OpenTelemetry: Are We Finally on the "Right" Path?

Context

Our Elastic journey has been interesting and filled with trial and error. Around every corner we discover a different (and often better) way of doing the same thing, but it usually means redoing large parts of our setup. We’re getting a bit tired of rebuilding everything, so I’m hoping to get some advice that helps us skip a few corners and rediscoveries.

Below I have included our observability journey, and the questions are at the bottom.

Our Journey

ELK

We wanted to introduce observability for our applications and already had some prior experience with the ELK stack. We already used Elasticsearch, but added Kibana and started to push logs via Logstash.

We added a custom log line that we sent to a separate index, which we used for our dashboards and statistics.

2026-01-01 12:00:00 thread-01 MyClass.java: LOGSTASH [status:200][ip:xx.xx.xx.xx][duration:12]

Agents, Integration, Custom Logs (Filestream) & Pipeline

After running into some issues with Logstash, we discovered that Fleet Agents could install the Custom Logs (Filestream) integration and use our own ingest pipelines, effectively replacing Logstash entirely. At the time this felt like a better and more modern solution.

Kibana Observability

Later, we discovered Kibana Observability and realized that our existing solution didn’t integrate well with it. We then installed the Elastic APM integration on our agents and started using the Elastic Java Agent.

OpenTelemetry standard

After seeing how many other tools and frameworks we use support OpenTelemetry out of the box, we wanted to move toward the OTEL standard. However, we couldn’t get the standard OTEL SDKs to work directly with the Elastic APM integration or Kibana's Observability solution, so we switched from the Elastic Java Agent to the Elastic OTEL Java Agent.

This is where we started noticing feature gaps.

When using the Elastic OTEL Java Agent together with the Elastic APM integration:

  • Metric attributes appear to be dropped
  • Unmapped attributes are rewritten as labels.xxxx
  • Multiple Kibana's Observability Metrics visualizations not working
  • Other expected OTEL behaviors don’t seem to be fully supported

For example:

// pseudo
meter.histogramBuilder("my.histogram.name")  
        .setUnit("ms")  
        .ofLongs()  
        .build();
histrogram.record(12, Attributes.of("some.attribute", "some.value"));

The recorded metric ends up looking like this, with the attribute missing:

"my.histogram.name": { "counts": [4], "values": [6250] }

The Future (Maybe?)

After more research, it seems that we should not be using the Elastic APM integration at all, but instead:

  • Use the OpenTelemetry integration / EDOT OTEL Collector
  • Install the System OpenTelemetry Assets integration
  • Use default and standard OTEL SDKs and tooling
  • Let Elastic/Kibana consume OTEL semantic conventions over ECS

If that understanding is correct, this would allow us to stick to standard OTEL tooling while still using Elastic Observability effectively.

My lingering questions

  • Will using the OpenTelemetry integration / EDOT OTEL Collector allow us to use standard OTEL tools without labels.xxx, retain all metric attributes, and still have Kibana Observability fully working?
  • If we move to the OpenTelemetry integration / EDOT OTEL Collector, are we finally on the “recommended” path, or are we likely to discover yet another better approach and end up rebuilding again?
  • Is it currently possible to use default OpenTelemetry tools end-to-end together with the Elastic Observability solution?
3 Likes

eager to know more about that

1 Like

We have similar concerns. Thanks for this post.

Hi Christoffer,

thank you for sharing your observability journey and the questions you have.

When using the EDOT Java agent or OTel vanilla you should ingest the data through an EDOT/OTel collector and/or Elastic Cloud Managed OTLP endpoint (reference architecture). The details depend on your environment. This ingestion path stores the telemetry data in Elasticsearch in the OTel-native format.

  • Is it currently possible to use default OpenTelemetry tools end-to-end together with the Elastic Observability solution?

You can use OTel vanilla SDKs/agents and an OTel collector to collect and ingest telemetry data. If you don't have the Elastic Cloud Managed OTLP endpoint on your ingest path you should tune the OTel contrib collector to have the right processing of data.

  • If we move to the OpenTelemetry integration / EDOT OTEL Collector, are we finally on the “recommended” path, or are we likely to discover yet another better approach and end up rebuilding again?

If you use an OTel-native ingestion path, that stores the telemetry in the OTel-native format in Elasticsearch, you should be on the right path. The APM server should not be part of this ingestion path because this would result in the telemetry data being stored in ECS format.

  • Will using the OpenTelemetry integration / EDOT OTEL Collector allow us to use standard OTEL tools without labels.xxx, retain all metric attributes, and still have Kibana Observability fully working?

If you use an OTel-native ingest path, you will have OTel's span, metrics and resource attributes. We have the Elastic's OTel demo environment available. It runs the OTel demo with a mix of EDOTs and OTel vanilla SDKs/agents. Maybe have a look and explore a bit. I recommend to use Discover to explore trace and metrics documents of the ingested data.

What kind of deployment of the Elastic Stack are you using and what version?

Thank you very much for the detailed answer.

We are running an on‑prem installation of Elasticsearch and Kibana. I believe most of our software is version 9.1.5. We are currently working on upgrading past 9.2+ as I believe the EDOT collector will be part of the 9.2+ Fleet Agents by default. Though haven't research if this means we don't need to install a separate collector or not. Ref.: Elastic Agent as an OpenTelemetry Collector

I have a few follow‑up questions to really hammer this home and make sure we’re aligning with the recommended architecture.

If I understand correctly, using an OTel‑native ingestion path (OTel SDKs/agents → OTel/EDOT Collector → Elasticsearch) will allow us to ingest all expected APM data.

What I’m still unsure about is whether Kibana’s Observability features will work out of the box in that scenario.

I believe I’ve seen references to installing specific content / assets packs (for example System OpenTelemetry Assets) to have Kibana correctly support OpenTelemetry semantic conventions, is that still required or recommended or needed?

You didn’t explicitly mention the EDOT Collector, which made me wonder:

  • Can we use the standard OpenTelemetry Collector instead of Elastic’s EDOT Collector?
  • If both are supported, what concrete benefits does the EDOT Collector provide over the vanilla collector?

If we fully move to an OTel Collector based ingestion path, am I correct in assuming that we can drop both:

  • the Elastic APM Agent, and
  • the elastic‑otel‑javaagent

…and instead rely on standard OpenTelemetry tooling such as:

  • native OTEL SDKs (io.opentelemetry:*)
  • framework integrations (for example Quarkus Micrometer OTEL, WildFly Micrometer OTEL bridge, etc.)

In other words: is the Elastic OTEL Java Agent optional if we are already instrumenting via SDKs/frameworks and exporting to a collector?

(Completely understandable if Java‑specific details are out of scope.)

Today we are attaching elastic-otel-javaagent-1.6.0.jar to the JVM and manually enriching traces using io.opentelemetry:opentelemetry-api. From your explanation, I understand that this results in data being converted and stored in ECS format, due to the Elastic APM integration.

If we introduce an OTel Collector and start ingesting OTEL‑native data in parallel during migration:

  • Will this cause issues for Kibana Observability, given that both ECS‑formatted and OTEL‑native telemetry would coexist temporarily?
  • Is there a recommended migration strategy to avoid breaking dashboards, correlations, or UI features while transitioning?