diff --git a/.changeset/ripe-parents-sing.md b/.changeset/ripe-parents-sing.md new file mode 100644 index 00000000..3cfc0281 --- /dev/null +++ b/.changeset/ripe-parents-sing.md @@ -0,0 +1,5 @@ +--- +'@hono/otel': patch +--- + +Use `req.routePath` to augment spans with the path that handled the request. diff --git a/packages/otel/src/index.test.ts b/packages/otel/src/index.test.ts index 7f73cbab..1908840c 100644 --- a/packages/otel/src/index.test.ts +++ b/packages/otel/src/index.test.ts @@ -26,6 +26,13 @@ describe('OpenTelemetry middleware', () => { throw new Error('error message') }) + const subapp = new Hono() + subapp.get('/hello', (c) => c.text('Hello from subapp!')) + subapp.get('*', (c) => c.text('Fallthrough')) + + // mount subapp + app.route('/subapp', subapp) + it('Should make a span', async () => { memoryExporter.reset() const response = await app.request('http://localhost/foo') @@ -71,4 +78,13 @@ describe('OpenTelemetry middleware', () => { expect(span.name).toBe('GET /foo') expect(span.attributes[ATTR_HTTP_ROUTE]).toBe('/foo') }) + + // Issue #1112 + it('Should set the correct span name for subapp', async () => { + memoryExporter.reset() + await app.request('http://localhost/subapp/hello') + const spans = memoryExporter.getFinishedSpans() + const [span] = spans + expect(span.name).toBe('GET /subapp/hello') + }) }) diff --git a/packages/otel/src/index.ts b/packages/otel/src/index.ts index 55bfe7a8..06c382d5 100644 --- a/packages/otel/src/index.ts +++ b/packages/otel/src/index.ts @@ -1,5 +1,5 @@ import type { TracerProvider } from '@opentelemetry/api' -import { SpanKind, SpanStatusCode, trace } from '@opentelemetry/api' +import { SpanKind, SpanStatusCode, trace } from '@opentelemetry/api' import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, @@ -10,17 +10,19 @@ import { } from '@opentelemetry/semantic-conventions' import type { Env, Input } from 'hono' import { createMiddleware } from 'hono/factory' -import metadata from '../package.json' with { type: 'json'} +import metadata from '../package.json' with { type: 'json' } const PACKAGE_NAME = metadata.name const PACKAGE_VERSION = metadata.version -export type OtelOptions = { - augmentSpan?: false; - tracerProvider?: TracerProvider -} | { - augmentSpan: true; -} +export type OtelOptions = + | { + augmentSpan?: false + tracerProvider?: TracerProvider + } + | { + augmentSpan: true + } export const otel = ( options: OtelOptions = {} @@ -30,9 +32,9 @@ export const otel = (async (c, next) => { - const route = c.req.matchedRoutes[c.req.matchedRoutes.length - 1] + const routePath = c.req.routePath await tracer.startActiveSpan( - `${c.req.method} ${route.path}`, + `${c.req.method} ${c.req.routePath}`, { kind: SpanKind.SERVER, attributes: { [ATTR_HTTP_REQUEST_METHOD]: c.req.method, [ATTR_URL_FULL]: c.req.url, - [ATTR_HTTP_ROUTE]: route.path, + [ATTR_HTTP_ROUTE]: routePath, }, }, async (span) => { @@ -57,6 +59,10 @@ export const otel =