OpenTelemetry instrumentation for Express.js web applications enabling automatic distributed tracing and observability
npx @tessl/cli install tessl/npm-opentelemetry--instrumentation-express@0.52.0OpenTelemetry Express Instrumentation provides automatic tracing and observability for Express.js web applications. It automatically captures HTTP request spans, route information, middleware execution, and request handler performance metrics without requiring code changes to existing applications.
npm install @opentelemetry/instrumentation-expressimport { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";For additional types and enums:
import {
ExpressInstrumentation,
ExpressLayerType,
AttributeNames,
type ExpressInstrumentationConfig,
type ExpressRequestInfo,
type ExpressRequestCustomAttributeFunction,
type IgnoreMatcher,
type LayerPathSegment,
type SpanNameHook,
} from "@opentelemetry/instrumentation-express";For CommonJS:
const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
const provider = new NodeTracerProvider();
provider.register();
registerInstrumentations({
instrumentations: [
// Express instrumentation requires HTTP layer to be instrumented
new HttpInstrumentation(),
new ExpressInstrumentation(),
],
});The Express instrumentation works by patching Express Router methods (route, use) and Application methods (use) to automatically create spans for middleware, routers, and request handlers. It uses a layered approach where:
Main instrumentation class that extends OpenTelemetry's InstrumentationBase to provide automatic Express.js tracing.
/**
* Express instrumentation for OpenTelemetry
* Automatically instruments Express.js applications for distributed tracing
*/
class ExpressInstrumentation extends InstrumentationBase<ExpressInstrumentationConfig> {
/**
* Creates a new Express instrumentation instance
* @param config - Optional configuration for the instrumentation
*/
constructor(config?: ExpressInstrumentationConfig);
/**
* Initializes the instrumentation by returning module definitions
* @returns Array of InstrumentationNodeModuleDefinition for express module
*/
init(): InstrumentationNodeModuleDefinition[];
}Enumeration defining the types of Express layers that can be instrumented.
/**
* Types of Express layers that can be instrumented
*/
enum ExpressLayerType {
ROUTER = 'router',
MIDDLEWARE = 'middleware',
REQUEST_HANDLER = 'request_handler',
}Standard attribute names used by the Express instrumentation for OpenTelemetry spans.
/**
* OpenTelemetry attribute names used by Express instrumentation
*/
enum AttributeNames {
EXPRESS_TYPE = 'express.type',
EXPRESS_NAME = 'express.name',
}Configuration options for customizing Express instrumentation behavior.
/**
* Configuration options for Express Instrumentation
*/
interface ExpressInstrumentationConfig extends InstrumentationConfig {
/** Ignore specific layers based on their name using matchers */
ignoreLayers?: IgnoreMatcher[];
/** Ignore specific layers based on their type */
ignoreLayersType?: ExpressLayerType[];
/** Custom function for span naming */
spanNameHook?: SpanNameHook;
/** Function for adding custom attributes on Express request */
requestHook?: ExpressRequestCustomAttributeFunction;
}Information about Express requests passed to hooks and callbacks.
/**
* Information about Express request for hooks and callbacks
*/
interface ExpressRequestInfo<T = any> {
/** An express request object */
request: T;
/** The matched route path */
route: string;
/** Type of the Express layer handling the request */
layerType: ExpressLayerType;
}Function type for adding custom attributes to spans based on Express request information.
/**
* Function that can be used to add custom attributes to the current span
* @param span - The Express middleware layer span
* @param info - Express request information including route and layer type
*/
interface ExpressRequestCustomAttributeFunction {
(span: Span, info: ExpressRequestInfo): void;
}Function type for customizing span names based on Express request information.
/**
* Function for customizing span names
* @param info - Express request information
* @param defaultName - Default name supplied by the instrumentation
* @returns Custom span name
*/
type SpanNameHook = (
info: ExpressRequestInfo,
defaultName: string
) => string;Type for matching patterns to ignore specific layers during instrumentation.
/**
* Pattern matching for ignoring layers during instrumentation
*/
type IgnoreMatcher = string | RegExp | ((name: string) => boolean);Type representing individual segments of Express layer paths.
/**
* Individual segment of Express layer path
*/
type LayerPathSegment = string | RegExp | number;import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
registerInstrumentations({
instrumentations: [
new ExpressInstrumentation(),
],
});import { ExpressInstrumentation, ExpressLayerType } from "@opentelemetry/instrumentation-express";
const expressInstrumentation = new ExpressInstrumentation({
ignoreLayers: [
// Ignore health check endpoints
'/health',
/^\/static\//,
// Ignore specific middleware by name
(name) => name === 'helmet',
],
ignoreLayersType: [
// Ignore all router spans
ExpressLayerType.ROUTER,
],
});import { ExpressInstrumentation, ExpressLayerType } from "@opentelemetry/instrumentation-express";
const expressInstrumentation = new ExpressInstrumentation({
requestHook: (span, info) => {
// Add custom attributes for request handlers only
if (info.layerType === ExpressLayerType.REQUEST_HANDLER) {
span.setAttribute('http.method', info.request.method);
span.setAttribute('express.base_url', info.request.baseUrl);
span.setAttribute('user.id', info.request.user?.id || 'anonymous');
}
},
});import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
const expressInstrumentation = new ExpressInstrumentation({
spanNameHook: (info, defaultName) => {
// Customize span names for request handlers
if (info.layerType === 'request_handler') {
return `${info.request.method} ${info.route}`;
}
return defaultName;
},
});@opentelemetry/instrumentation-httphttp.route attributeThe instrumentation automatically captures and records exceptions that occur in Express middleware and request handlers. Errors are recorded as span exceptions with proper error status codes.
Express instrumentation is designed to work alongside other OpenTelemetry instrumentations, particularly: