diff --git a/plugins/node/opentelemetry-instrumentation-koa/src/koa.ts b/plugins/node/opentelemetry-instrumentation-koa/src/koa.ts index 5b01a063a1..223223aece 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/src/koa.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/src/koa.ts @@ -28,6 +28,8 @@ import { KoaContext, KoaComponentName, kLayerPatched, + KoaLayerType, + AttributeNames, } from './types'; import { VERSION } from './version'; import { getMiddlewareMetadata } from './utils'; @@ -127,7 +129,8 @@ export class KoaInstrumentation extends InstrumentationBase { middlewareLayer[kLayerPatched] = true; api.diag.debug('patching Koa middleware layer'); return async (context: KoaContext, next: koa.Next) => { - if (api.getSpan(api.context.active()) === undefined) { + const parent = api.getSpan(api.context.active()); + if (parent === undefined) { return middlewareLayer(context, next); } const metadata = getMiddlewareMetadata( @@ -140,6 +143,28 @@ export class KoaInstrumentation extends InstrumentationBase { attributes: metadata.attributes, }); + if (!context.request.ctx.parentSpan) { + context.request.ctx.parentSpan = parent; + } + + if ( + metadata.attributes[AttributeNames.KOA_TYPE] === KoaLayerType.ROUTER + ) { + if (context.request.ctx.parentSpan.name) { + const parentRoute = context.request.ctx.parentSpan.name.split(' ')[1]; + if ( + context._matchedRoute && + !context._matchedRoute.toString().includes(parentRoute) + ) { + context.request.ctx.parentSpan.updateName( + `${context.method} ${context._matchedRoute}` + ); + + delete context.request.ctx.parentSpan; + } + } + } + return api.context.with( api.setSpan(api.context.active(), span), async () => { diff --git a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts index ba7db72aff..24633ff0df 100644 --- a/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts +++ b/plugins/node/opentelemetry-instrumentation-koa/test/koa.test.ts @@ -158,7 +158,7 @@ describe('Koa Instrumentation', () => { const exportedRootSpan = memoryExporter .getFinishedSpans() - .find(span => span.name === 'rootSpan'); + .find(span => span.name === 'GET /post/:id'); assert.notStrictEqual(exportedRootSpan, undefined); }); }); @@ -200,7 +200,7 @@ describe('Koa Instrumentation', () => { const exportedRootSpan = memoryExporter .getFinishedSpans() - .find(span => span.name === 'rootSpan'); + .find(span => span.name === 'GET /:first/post/:id'); assert.notStrictEqual(exportedRootSpan, undefined); }); }); @@ -240,7 +240,7 @@ describe('Koa Instrumentation', () => { const exportedRootSpan = memoryExporter .getFinishedSpans() - .find(span => span.name === 'rootSpan'); + .find(span => span.name === 'GET /:first/post/:id'); assert.notStrictEqual(exportedRootSpan, undefined); }); });