OpenTracing Middleware for Express.js

raw JSON →
0.1.1 verified Thu Apr 23 auth: no javascript abandoned

express-opentracing provides middleware for Express.js applications to instrument incoming HTTP requests using the OpenTracing API. This allows developers to integrate distributed tracing into their Express routes, creating spans for requests and associating them with a configured OpenTracing-compatible tracer. The package is currently at version 0.1.1 and appears to be unmaintained, with its last commit occurring several years ago. Crucially, the underlying OpenTracing project itself has been officially deprecated and archived since 2019, having merged with OpenCensus to form OpenTelemetry. OpenTelemetry is now the recommended, actively developed standard for comprehensive observability, encompassing traces, metrics, and logs. Users are strongly advised to migrate from OpenTracing-based solutions to OpenTelemetry for ongoing support, features, and security.

error Error: Cannot find module 'opentracing'
cause The `opentracing` peer dependency is required by `express-opentracing` but was not installed in the project.
fix
Install the opentracing package: npm install opentracing or yarn add opentracing.
error TypeError: Cannot read properties of undefined (reading 'startSpan')
cause This error often occurs when the `tracer` option passed to the middleware is `undefined` or not a valid OpenTracing `Tracer` instance, leading to calls on an uninitialized object.
fix
Ensure a valid Tracer instance is passed in the middleware options: app.use(middleware({ tracer: myTracer }));. If using opentracing.initGlobalTracer(), ensure it's called before express-opentracing is initialized.
breaking The OpenTracing project, which this library depends on, has been officially deprecated and archived. It was superseded by OpenTelemetry, a unified and actively developed standard for distributed tracing, metrics, and logs. Continuing to use OpenTracing-based libraries is strongly discouraged.
fix Migrate your observability instrumentation to OpenTelemetry. This will require replacing `express-opentracing` with an OpenTelemetry Express instrumentation package (e.g., `@opentelemetry/instrumentation-express`) and adopting the OpenTelemetry SDK.
gotcha This package is unmaintained. The last release was in 2017 (version 0.1.1), and there has been no active development since. This means it will not receive bug fixes, new features, or security updates. Its compatibility with newer Node.js, Express.js, or `opentracing` versions is not guaranteed.
fix As with the OpenTracing deprecation, the primary fix is to migrate to OpenTelemetry-based solutions that are actively maintained and compatible with modern JavaScript ecosystems.
gotcha The peer dependency `opentracing` has a version requirement of `^0.14.0`. While this aligns with the last known stable version of `opentracing` before its deprecation, installing newer or incompatible versions of `opentracing` (or other tracing libraries) could lead to runtime errors or unexpected behavior if strict peer dependency checks are not in place.
fix Ensure `opentracing` is installed at a compatible version. However, given the project's status, the recommended long-term solution is migration to OpenTelemetry.
gotcha This middleware implicitly expects a global tracer to be initialized via `opentracing.initGlobalTracer()`, or it defaults to the OpenTracing NoopTracer if no tracer is explicitly passed in the options object. Failing to initialize a real tracer will result in no actual tracing data being collected without any explicit errors from the middleware itself.
fix Always explicitly pass an initialized tracer instance (e.g., from Jaeger, LightStep, or a MockTracer for testing) to the middleware options: `app.use(middleware({ tracer: myTracer }));`.
npm install express-opentracing
yarn add express-opentracing
pnpm add express-opentracing

This quickstart demonstrates how to integrate `express-opentracing` into an Express.js application using a basic `MockTracer` for logging. It shows how to initialize the middleware and access the request span within a route handler.

import * as express from "express";
import middleware from "express-opentracing";
import * as opentracing from 'opentracing';

// NOTE: In a real application, you'd replace the NoopTracer
// with a vendor-specific implementation like Jaeger, LightStep, or Zipkin.
// For demonstration, we use a basic console logger (MockTracer).
class MockTracer extends opentracing.Tracer {
  _startSpan(name, options) {
    console.log(`[MockTracer] Starting span: ${name}`);
    return new MockSpan(this, name, options.references);
  }
}

class MockSpan extends opentracing.Span {
  _finish() {
    console.log(`[MockTracer] Finishing span: ${this.operationName()}`);
  }
  _context() { return { traceId: 'mock-trace', spanId: 'mock-span' }; }
  _setOperationName(name) { return this; }
  _log(fields, timestamp) { console.log(`[MockTracer] Log for ${this.operationName()}:`, fields); return this; }
  _setTag(key, value) { console.log(`[MockTracer] Tag for ${this.operationName()}: ${key}=${value}`); return this; }
}

const myTracer = new MockTracer();
opentracing.initGlobalTracer(myTracer);

const app = express();

// Apply the express-opentracing middleware
app.use(middleware({ tracer: myTracer }));

app.get('/', (req, res) => {
  // The span is available on req.span if the middleware created one
  if (req.span) {
    req.span.log({ event: 'homepage_access', userId: 'test-user-123' });
    // Simulate some async work
    setTimeout(() => {
      res.send('Hello from Express with OpenTracing!');
      req.span.setTag(opentracing.Tags.HTTP_STATUS_CODE, 200);
    }, 100);
  } else {
    res.send('Hello from Express (no tracing)');
  }
});

app.get('/error', (req, res) => {
  if (req.span) {
    req.span.setTag(opentracing.Tags.ERROR, true);
    req.span.setTag(opentracing.Tags.HTTP_STATUS_CODE, 500);
    req.span.log({ event: 'error_occurred', message: 'Something went wrong' });
  }
  res.status(500).send('An error occurred!');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
  console.log('Try visiting / and /error');
});