opentelemetry-js
opentelemetry-js copied to clipboard
Missing http_route attribute on the http_server_duration metric when traces export is disabled
What happened?
Steps to Reproduce
Set up NodeSDK with HttpInstrumentation, ExpressInstrumentation and metricReader. Run app with OTEL_TRACES_EXPORTER: none.
Expected Result
http_route attribute is present on the http_server_duration metric.
Actual Result
http_route attribute is missing on the http_server_duration metric.
Additional Details
If NodeSDK is set up with some traceExporter e.g. ConsoleSpanExporter then http_route attribute is present on the http_server_duration metric.
Sharing my investigation results - the http_route attribute is added to the metric attributes by HttpInstrumentation from the rpc metadata which in turn is added to the propagation context by ExpressInstrumentation only when tracing is enabled. Apparently at the moment there is no way to workaround it using instrumentation hooks as inside the hooks you have no means to manipulate the propagation context.
Also e.g. OTel Java instrumentation adds http_route to the http_server_duration metric even if OTEL_TRACES_EXPORTER: none.
There is a feature request that could help to workaround this https://github.com/open-telemetry/opentelemetry-js/issues/3694 but ideally this bug should be fixed.
OpenTelemetry Setup Code
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
import * as process from 'process';
function startOTelNodeSDK() {
const otelSDK = new NodeSDK({
instrumentations: [
new HttpInstrumentation(),
new ExpressInstrumentation(),
],
metricReader: new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter(),
}),
});
process.on('SIGTERM', () => {
otelSDK
.shutdown()
.then(
() => console.log('SDK shut down successfully'),
(err) => console.log('Error shutting down SDK', err),
)
.finally(() => process.exit(0));
});
console.log('Starting OTel NodeSDK...');
otelSDK.start();
}
startOTelNodeSDK();
package.json
{
"name": "otel-instrumentation",
"version": "0.0.1",
"private": true,
"scripts": {
"clean": "rimraf build/*",
"prepare": "npm run compile",
"compile": "tsc -p .",
"postcompile": "copyfiles -f 'build/src/**' build/workspace/ && copyfiles 'node_modules/**' build/workspace/"
},
"devDependencies": {
"copyfiles": "^2.4.1",
"rimraf": "^5.0.0",
"typescript": "^5.0.4"
},
"dependencies": {
"@opentelemetry/api": "^1.4.1",
"@opentelemetry/auto-instrumentations-node": "^0.37.0",
"@opentelemetry/core": "^1.13.0",
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.39.1",
"@opentelemetry/instrumentation-express": "^0.32.3",
"@opentelemetry/instrumentation-http": "^0.39.1",
"@opentelemetry/sdk-metrics": "^1.13.0",
"@opentelemetry/sdk-node": "^0.39.1",
}
}
Relevant log output
No response