Skip to content

Commit d579630

Browse files
authored
fix(express): span name if middleware on nested router is used (#2682)
1 parent f637c87 commit d579630

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

plugins/node/opentelemetry-instrumentation-express/src/instrumentation.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class ExpressInstrumentation extends InstrumentationBase<ExpressInstrumen
171171
req: PatchedRequest,
172172
res: express.Response
173173
) {
174-
storeLayerPath(req, layerPath);
174+
const { isLayerPathStored } = storeLayerPath(req, layerPath);
175175
const route = (req[_LAYERS_STORE_PROPERTY] as string[])
176176
.filter(path => path !== '/' && path !== '/*')
177177
.join('')
@@ -280,7 +280,7 @@ export class ExpressInstrumentation extends InstrumentationBase<ExpressInstrumen
280280
req.res?.removeListener('finish', onResponseFinish);
281281
span.end();
282282
}
283-
if (!(req.route && isError)) {
283+
if (!(req.route && isError) && isLayerPathStored) {
284284
(req[_LAYERS_STORE_PROPERTY] as string[]).pop();
285285
}
286286
const callback = args[callbackIdx] as Function;

plugins/node/opentelemetry-instrumentation-express/src/utils.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,21 @@ import {
3333
* @param request The request where
3434
* @param [value] the value to push into the array
3535
*/
36-
export const storeLayerPath = (request: PatchedRequest, value?: string) => {
36+
export const storeLayerPath = (
37+
request: PatchedRequest,
38+
value?: string
39+
): { isLayerPathStored: boolean } => {
3740
if (Array.isArray(request[_LAYERS_STORE_PROPERTY]) === false) {
3841
Object.defineProperty(request, _LAYERS_STORE_PROPERTY, {
3942
enumerable: false,
4043
value: [],
4144
});
4245
}
43-
if (value === undefined) return;
46+
if (value === undefined) return { isLayerPathStored: false };
47+
4448
(request[_LAYERS_STORE_PROPERTY] as string[]).push(value);
49+
50+
return { isLayerPathStored: true };
4551
};
4652

4753
/**

plugins/node/opentelemetry-instrumentation-express/test/express.test.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -709,15 +709,18 @@ describe('ExpressInstrumentation', () => {
709709
assert.strictEqual(spans[5].name, 'router - /api/user/:id');
710710
assert.strictEqual(spans[5].kind, testUtils.OtlpSpanKind.INTERNAL);
711711
assert.strictEqual(spans[5].parentSpanId, spans[1].spanId);
712-
assert.strictEqual(spans[6].name, 'router - /:postId');
712+
assert.strictEqual(spans[6].name, 'router - /api/user/:id/posts');
713713
assert.strictEqual(spans[6].kind, testUtils.OtlpSpanKind.INTERNAL);
714714
assert.strictEqual(spans[6].parentSpanId, spans[1].spanId);
715+
assert.strictEqual(spans[7].name, 'middleware - simpleMiddleware2');
716+
assert.strictEqual(spans[7].kind, testUtils.OtlpSpanKind.INTERNAL);
717+
assert.strictEqual(spans[7].parentSpanId, spans[1].spanId);
715718
assert.strictEqual(
716-
spans[7].name,
719+
spans[8].name,
717720
'request handler - /api/user/:id/posts/:postId'
718721
);
719-
assert.strictEqual(spans[7].kind, testUtils.OtlpSpanKind.INTERNAL);
720-
assert.strictEqual(spans[7].parentSpanId, spans[1].spanId);
722+
assert.strictEqual(spans[8].kind, testUtils.OtlpSpanKind.INTERNAL);
723+
assert.strictEqual(spans[8].parentSpanId, spans[1].spanId);
721724
},
722725
});
723726
});

plugins/node/opentelemetry-instrumentation-express/test/fixtures/use-express-nested-router.mjs

+9-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ app.use(async function simpleMiddleware(req, res, next) {
4646

4747
const userRouter = express.Router();
4848
const postsRouter = express.Router();
49+
postsRouter.use(async function simpleMiddleware2(req, res, next) {
50+
// Wait a short delay to ensure this "middleware - ..." span clearly starts
51+
// before the "router - ..." span. The test rely on a start-time-based sort
52+
// of the produced spans. If they start in the same millisecond, then tests
53+
// can be flaky.
54+
await promisify(setTimeout)(10);
55+
next();
56+
});
4957

5058
postsRouter.get('/:postId', (req, res, next) => {
5159
res.json({ hello: 'yes' });
@@ -74,7 +82,7 @@ await new Promise(resolve => {
7482
res.on('end', data => {
7583
resolve(data);
7684
});
77-
})
85+
});
7886
});
7987

8088
await new Promise(resolve => server.close(resolve));

0 commit comments

Comments
 (0)