OpenTelemetry bridgeedit

Added as experimental in v3.34.0. To enable it, set opentelemetryBridgeEnabled to true.

The Elastic APM OpenTelemetry bridge allows one to use the vendor-neutral OpenTelemetry Tracing API (@opentelemetry/api) to manually instrument your code, and have the Elastic Node.js APM agent handle those API calls. This allows one to 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 goal of the OpenTelemetry bridge is to allow using the OpenTelemetry API with the APM agent. ① First, you will need to add those dependencies to your project. The minimum required OpenTelemetry API version is 1.0.0. For example:

npm install --save elastic-apm-node @opentelemetry/api

② Second, you will need to configure and start the APM agent. This can be done completely with environment variables (so that there is no need to touch your application code):

export ELASTIC_APM_SERVER_URL='<url of your APM server>'
export ELASTIC_APM_SECRET_TOKEN='<secret token for your APM server>'  # or ELASTIC_APM_API_KEY=...
export ELASTIC_APM_OPENTELEMETRY_BRIDGE_ENABLED=true
export NODE_OPTIONS='-r elastic-apm-node/start.js'  # Tell node to preload and start the APM agent
node my-app.js

Or, alternatively, you can configure and start the APM agent at the top of your application code as follows. (Note: For automatic instrumentations to function properly, this must be executed before other require statements and application code.)

require('elastic-apm-node').start({
    serverUrl: '<url of your APM server>',
    secretToken: '<secret token for your APM server>', // or, apiKey: '<your API key>'
    opentelemetryBridgeEnabled: true
});

// Application code ...

These examples show the minimal configuration. See the full APM agent configuration reference for other configuration options.

③ Finally, you can use the OpenTelemetry API for any manual tracing in your code. For example, the following script uses Tracer#startActiveSpan() to trace an outgoing HTTPS request:

const https = require('https')
const otel = require('@opentelemetry/api')
const tracer = otel.trace.getTracer('trace-https-request')

tracer.startActiveSpan('makeRequest', span => {
  https.get('https://httpstat.us/200', (response) => {
    console.log('STATUS:', response.statusCode)
    const body = []
    response.on('data', (chunk) => body.push(chunk))
    response.on('end', () => {
      console.log('BODY:', body.toString())
      span.end()
    })
  })
})

The APM agent source code repository includes some examples using the OpenTelemetry bridge.

Bridge architectureedit

The OpenTelemetry bridge works similarly to the OpenTelemetry JS SDK. It registers Tracer and ContextManager providers with the OpenTelemetry API. Subsequent @opentelemetry/api calls in user code will call into those providers. The APM agent translates from OpenTelemetry to Elastic APM semantics and sends tracing data to your APM server for full support in Elastic Observability’s APM app.

Here are a couple examples of semantic translations: The first entry span of a service (e.g. an incoming HTTP request) will be converted to an Elasic APM Transaction, subsequent spans are mapped to Elastic APM Span. OpenTelemetry Span attributes are translated into the appropriate fields in Elastic APM’s data model.

The only difference, from the user’s point of view, is in the setup of tracing. Instead of setting up the OpenTelemetry JS SDK, one sets up the APM agent as described above.

Caveatsedit

Not all features of the OpenTelemetry API are supported.

Metricsedit

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

Span Linksedit

Adding links when starting a span are not currently supported. Any given links will be silently dropped.

Span Eventsedit

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

Baggageedit

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