Skip to content

Using a chained express.Router() for reusable middleware causes OpenTelemetry to lose route context #2820

@DannyTh1

Description

@DannyTh1

What version of OpenTelemetry are you using?

"@opentelemetry/auto-instrumentations-node": "^0.56.0"

What version of Node are you using?

v22.14.0

What did you do?

When middleware is structured using a chained express.Router()—commonly done to compose and reuse multiple middleware functions—the route context is lost when it's applied at the route level. This leads to OpenTelemetry incorrectly naming parent spans with just the base path (e.g., POST /) instead of the full route (e.g., POST /account/get).

Example:

const reusableMiddleware = () => {
  return Router()
    .use(async (req, res, next) => {
      // Some shared async logic
      next();
    })
    .use((req, res, next) => {
      // Additional logging or authorization
      next();
    });
};

router.post('/account/get', reusableMiddleware(), (req, res) => {
  res.send('done');
});

Notably, if the same Router()-based middleware is applied at the app level (e.g., app.use('/api', reusableMiddleware(), testRouter)), the OpenTelemetry span names are correct and reflect the full route path.

What did you expect to see?

Spans name recorded as "POST /account/get"

What did you see instead?

Span is recorded as "POST /"

Is this the correct behaviour or is this a bug? What are some possible workarounds to this?

  • This only affects the JavaScript OpenTelemetry library
  • [] This may affect other libraries, but I would like to get opinions here first

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions