OpenTelemetry Integration for Node.js Applications

The main approach for integrating with OpenTelemetry is to configure the default OTLP exporter of any application that is monitored by OpenTelemetry to send its data to the Instana agent. This is described on the OpenTelemetry page.

The OpenTelemetry integration can be further customized with additional componets. The available OpenTelemetry components for Node.js are described on this page.

Serverless OpenTelemetry Exporter

The package @instana/opentelemetry-exporter offers an OpenTelemetry exporter that converts and sends OpenTelemetry spans to the Instana back end.

The Instana Node.js OpenTelemetry exporter is designed primarily for usage in serverless environments, such as AWS Lambda or AWS Fargate. Instana already provides support for OpenTelemetry for SaaS and self hosted solutions through the host agent. However, if your Node.js applications run in a serverless environment, where the agent is not present, the serverless OpenTelemetry exporter is the way to go.

To use the exporter, install the package into your project, import the package into the tracing module, and create a new instance of InstanaExporter.

The exporter expects two Instana environment variables that must be provided to the application:

  • INSTANA_AGENT_KEY
  • INSTANA_ENDPOINT_URL

Alternatively, you can provide these values as arguments to the constructor, but this alternative is not recommended, because this is sensitive data that you might want to avoid exposing.

For example, you can configure the exporter into the tracing module as follows:

'use strict';

const process = require('process');
require('@opentelemetry/api');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');

// Require the Instana OpenTelemetry Exporter
const { InstanaExporter } = require('@instana/opentelemetry-exporter');

// Instantiate the Instana Exporter.
// Make sure to provide the agent key and the serverless endpoint URL via the following environment variables:
// * INSTANA_AGENT_KEY
// * INSTANA_ENDPOINT_URL
const instanaTraceExporter = new InstanaExporter();

/*
 * If you have not provided the agent key and the serverless endpoint URL via environment variables:
 * const instanaTraceExporter = new InstanaExporter({ agentKey: 'agent_key', endpointUrl: 'endpoint_url' });
 */

const nodeAutoInstrumentations = getNodeAutoInstrumentations();

const sdk = new opentelemetry.NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'my-service'
  }),
  // Configure OpenTelemetry to use the Instana Exporter
  traceExporter: instanaTraceExporter,
  instrumentations: [nodeAutoInstrumentations]
});

sdk.start()
...

When the application that is monitored by OpenTelemetry runs, the Instana exporter will convert the OpenTelemetry spans to Instana spans, and send them to the back end endpoint.

The OpenTelemetry trace visualization will be present in the Instana UI, like regular Instana tracing spans.

OpenTelemetry Propagator

The OpenTelemetry context propagator package @opentelemetry/propagator-instana translates the proprietary Instana trace correlation headers into an OpenTelemetry trace context and vice versa. See OpenTelemetry Propagators for general information on OpenTelemetry context propagators.

Install the package with npm install --save @opentelemetry/propagator-instana, and add the following code to the global tracer configuration file:

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { InstanaPropagator } = require('@opentelemetry/propagator-instana');
// ...

const provider = new NodeTracerProvider();

provider.register({
  propagator: new InstanaPropagator()
});

OpenTelemetry Sampler

The OpenTelemetry sampler package @instana/opentelemetry-sampler overrides the default OpenTelemetry sampling behavior so that any request will be sampled, unless the value of the sampled flag in the trace context is false. See OpenTelemetry Samplers for general information on OpenTelemetry samplers.

The sampler needs to be used in conjunction with the package `@opentelemetry/propagator-instana.

Install both packages with the command npm install --save @opentelemetry/propagator-instana @instana/opentelemetry-sampler, and add the following code to the global tracer configuration file:

const api = require('@opentelemetry/api');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const { Resource } = require('@opentelemetry/resources');
const { InstanaAlwaysOnSampler } = require('@instana/opentelemetry-sampler');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { InstanaPropagator } = require('@opentelemetry/propagator-instana');

const nodeAutoInstrumentations = getNodeAutoInstrumentations();
api.propagation.setGlobalPropagator(new InstanaPropagator());

const traceOtlpExporter = new OTLPTraceExporter({
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT
});

const sdk = new opentelemetry.NodeSDK({
  traceExporter: traceOtlpExporter,
  instrumentations: [nodeAutoInstrumentations],
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'my-service'
  }),
  sampler: new InstanaAlwaysOnSampler()
});

sdk
  .start()
  .then(() => console.log('Tracing initialized'))
  .catch(err => console.log('Error initializing tracing', err));

OpenTelemetry Resource Detector

An Instana OpenTelemetry resource detector always requires an Instana agent to be deployed and running on the same host.

The OpenTelemetry resource detector package @opentelemetry/resource-detector-instana enriches OpenTelemetry tracing information with additional resource attributes. See OpenTelemetry Resource Detectors for general information on OpenTelemetry resource detectors.

Install the package with the command npm install --save @opentelemetry/resource-detector-instana, and add the following code to the global tracer configuration file:

import {
  Resource,
  processDetector,
  envDetector,
} from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { instanaAgentDetector } from "@opentelemetry/resource-detector-instana";

const globalResource = new Resource({
   [SemanticResourceAttributes.SERVICE_NAME]: "TestService",
});

const sdk = new NodeSDK({
   resourceDetectors: [envDetector, processDetector, instanaAgentDetector]
   resource: globalResource,
});

sdk.start()

Additionally, the following environment variables can be provided:

  • INSTANA_AGENT_HOST: The Instana agent hostname (default: localhost)
  • INSTANA_AGENT_PORT: The Instana agent port (default: 42699)
  • INSTANA_RETRY_TIMEOUT_MS: The resource detector executes three retries to connect to the Instana agent. This is the timeout between the retries (default: 1000)
  • INSTANA_AGENT_TIMEOUT_MS: The client timeout when connecting to the Instana agent (default: 3000)