Skip to content

Express instrumentation: rpcMetadata.route overwritten by middlewares after request handler #2884

@Pratyush0812

Description

@Pratyush0812

What version of OpenTelemetry are you using?

"@opentelemetry/api": "1.9.0",
"@opentelemetry/auto-instrumentations-node": "0.58.0",
"@opentelemetry/sdk-node": "0.200.0",
"@opentelemetry/sdk-trace-base" : "2.0.0",
"@opentelemetry/sdk-trace-base" : "2.0.0",
"@opentelemetry/instrumentation-express": "0.48.1"

What version of Node are you using?

v20.18.1

What did you do?

I instrumented my Express application using @opentelemetry/instrumentation-express alongside @opentelemetry/instrumentation-http. While tracing incoming HTTP requests, I noticed an inconsistency in how the http.route attribute is set in spans, depending on the order and position of middleware layers relative to the request handler.

In some cases, middleware layers executed after the request handler were resetting the RPCMetadata.route value to '/', which caused the http.route attribute in the SERVER span to be incorrectly reported as '/' instead of the actual matched route.

What did you expect to see?

The route stored in RPCMetadata.route should remain unchanged once set by the request handler layer, and subsequent middleware layers should not overwrite it back to '/'.

What did you see instead?

In some cases, middleware layers that execute after the request handler are resetting the RPCMetadata.route value back to '/'.
As a result, the http.route attribute on the SERVER span incorrectly gets overwritten to '/' during these middleware executions, even though the correct route had already been set by the request handler.

Additional context

Suggested Fix

Suggested fix
Update the Express instrumentation’s _applyPatch logic to ensure that RPCMetadata.route is only set once per request, ideally during the first route handler layer (or when it’s not already set).
Subsequent middleware layers, especially those with layer paths like '/' or undefined, should not override the existing value in RPCMetadata.route if it’s already populated.

One possible way:

if (rpcMetadata?.type === RPCType.HTTP) {
  if (!rpcMetadata.route || rpcMetadata.route === '/') {
    rpcMetadata.route = route || '/';
  }
}

I am fairly new to this instrumentation code and my understanding or logic might be flawed. Please kindly help with a fix or guidance on how to properly handle setting the route in middleware and handler layers. I appreciate your support!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpkg:instrumentation-expresspriority:p2Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrect

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions