OpenTelemetry Bridgeedit

This functionality is in technical preview and may be changed or removed in a future release. Elastic will apply best effort to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.

This feature was added in v1.13.0. It is supported on .NET 5 and newer versions.

The OpenTelemetry Bridge in the Elastic .NET APM Agent bridges OpenTelemetry spans into Elastic APM transactions and spans. The Elastic APM OpenTelemetry bridge allows you to use the vendor-neutral OpenTelemetry Tracing API to manually instrument your code and have the Elastic .NET APM agent handle those API calls. This means you can use the Elastic APM agent for tracing, without any vendor lock-in from adding manual tracing using the APM agent’s own Public API.

Getting startededit

The OpenTelemetry bridge is part of the core agent package (Elastic.Apm), so you don’t need to add an additional dependency.

Enable the OpenTelemetry Bridgeedit

Currently the bridge is opt-in, so you need to enable it.

If you configured the agent via environment variables, set the ELASTIC_APM_OPENTELEMETRY_BRIDGE_ENABLED ` environment variable to `true`.

If you configured the agent via the appsettings.json file, then set ElasticApm:EnableOpenTelemetryBridge to true.

      "ServerUrl":  "http://myapmserver:8200",
      "SecretToken":  "apm-server-secret-token",
      "EnableOpenTelemetryBridge": true

Create an ActivitySource and start spansedit

After enabling the bridge, you can create OpenTelemetry spans, or in .NET terminology, you can start creating new activities via the activity source, and the agent will bridge those spans automatically.

public static void Sample()
	var src = new ActivitySource("Test");
	using var activity1 = src.StartActivity(nameof(Sample), ActivityKind.Server);
	using var activity2 = src.StartActivity("foo");

The code snippet above creates a span named Sample and a child span on Sample named foo. The bridge will create a transaction from Sample and a child span named foo.

Mixing OpenTelemetry and the Elastic APM Public APIedit

You can also mix the Activity API with the Public API, the OpenTelemetry bridge will take care of putting the spans into the right place. The advantage of this is that if you already have some libraries that you instrumented via the Public API, but going forward, you’d like to use the vendor-independent OpenTelemetry API, you don’t need to replace all Public API calls in one go.

/// ElasticTransaction
/// -
/// ---> OTelSpan
///           -
///           ---> ElasticSpan

var src = new ActivitySource("Test");
tracer.CaptureTransaction( nameof(Sample4), "test", t =>
	using (var activity = src.StartActivity("foo"))
		tracer.CurrentSpan.CaptureSpan("ElasticApmSpan", "test", () => Thread.Sleep(50));

The code snippet above creates a transaction with the Elastic .NET APM Agent’s Public API. Then it creates an activity called foo; this activity will be a child of the previously created transaction. Finally, a span is created again using the Elastic .NET APM Agent’s Public API; this span will be a child span of the OpenTelemetry span.

Of course these calls don’t have to be in the same method. The concept described here works across different methods, types, or libraries.

Supported OpenTelemetry implementationsedit

OpenTelemetry in .NET is implemented via the Activity API and there is an OpenTelemetry shim which follows the OpenTelemetry specification more closer. This shim is built on top of the Activity API.

The OpenTelemetry bridge in the Elastic .NET APM Agent targets the Activity API. Since the OpenTelemetry .NET shim builds on top of the Activity API, the shim is implicitly supported as well, although we don’t directly test it, because the Activity API is the recommended OpenTelemetry API for .NET.


Not all features of the OpenTelemetry API are supported.


This bridge only supports the tracing API. The Metrics API is currently not supported.

Span Eventsedit

Span events (Span#addEvent()) are not currently supported. Events will be silently dropped.


Propagating baggage within or outside the process is not supported. Baggage items are silently dropped.