diff --git a/dev-packages/e2e-tests/test-applications/elysia-bun/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/elysia-bun/tests/transactions.test.ts index fd51305e733a..28ce37877f38 100644 --- a/dev-packages/e2e-tests/test-applications/elysia-bun/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/elysia-bun/tests/transactions.test.ts @@ -132,7 +132,7 @@ test('Creates lifecycle spans for Elysia hooks', async ({ baseURL, request }) => expect(spans).toContainEqual( expect.objectContaining({ description: 'Handle', - op: 'request_handler.elysia', + op: 'handler', origin: 'auto.http.elysia', }), ); diff --git a/dev-packages/e2e-tests/test-applications/elysia-node/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/elysia-node/tests/transactions.test.ts index a5949b507dfa..71cda9825466 100644 --- a/dev-packages/e2e-tests/test-applications/elysia-node/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/elysia-node/tests/transactions.test.ts @@ -132,7 +132,7 @@ test('Creates lifecycle spans for Elysia hooks', async ({ baseURL, request }) => expect(spans).toContainEqual( expect.objectContaining({ description: 'Handle', - op: 'request_handler.elysia', + op: 'handler', origin: 'auto.http.elysia', }), ); diff --git a/dev-packages/e2e-tests/test-applications/hono-4/tests/multi-fetch.test.ts b/dev-packages/e2e-tests/test-applications/hono-4/tests/multi-fetch.test.ts index da369c1c6c31..3904a02ebc30 100644 --- a/dev-packages/e2e-tests/test-applications/hono-4/tests/multi-fetch.test.ts +++ b/dev-packages/e2e-tests/test-applications/hono-4/tests/multi-fetch.test.ts @@ -185,7 +185,7 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { }); test.describe('trace propagation through internal .request() calls', () => { - test('single internal fetch produces a hono.request child span', async ({ baseURL }) => { + test('single internal fetch produces an internal-request child span', async ({ baseURL }) => { const transactionPromise = waitForTransaction(APP_NAME, event => { return ( event.contexts?.trace?.op === 'http.server' && event.transaction === `GET ${STOREFRONT}/product/:productId` @@ -198,12 +198,14 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { const traceId = transaction.contexts?.trace?.trace_id; const spans = transaction.spans || []; - const internalRequestSpans = spans.filter((s: { op?: string }) => s.op === 'hono.request'); + const internalRequestSpans = spans.filter( + (s: { origin?: string }) => s.origin === 'auto.http.hono.internal_request', + ); expect(internalRequestSpans).toHaveLength(1); expect(internalRequestSpans[0]).toEqual( expect.objectContaining({ - op: 'hono.request', + op: 'http.server', origin: 'auto.http.hono.internal_request', trace_id: traceId, }), @@ -211,7 +213,7 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { expect(internalRequestSpans[0]?.description).toContain('GET /item/self-watering-plant'); }); - test('parallel internal fetches produce two sibling hono.request spans', async ({ baseURL }) => { + test('parallel internal fetches produce two sibling internal-request spans', async ({ baseURL }) => { const transactionPromise = waitForTransaction(APP_NAME, event => { return ( event.contexts?.trace?.op === 'http.server' && @@ -225,7 +227,9 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { const traceId = transaction.contexts?.trace?.trace_id; const spans = transaction.spans || []; - const internalRequestSpans = spans.filter((s: { op?: string }) => s.op === 'hono.request'); + const internalRequestSpans = spans.filter( + (s: { origin?: string }) => s.origin === 'auto.http.hono.internal_request', + ); expect(internalRequestSpans).toHaveLength(2); @@ -238,7 +242,7 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { expect(internalRequestSpans[1]?.origin).toBe('auto.http.hono.internal_request'); }); - test('sequential chained fetches produce two ordered hono.request spans', async ({ baseURL }) => { + test('sequential chained fetches produce two ordered internal-request spans', async ({ baseURL }) => { const transactionPromise = waitForTransaction(APP_NAME, event => { return ( event.contexts?.trace?.op === 'http.server' && @@ -253,7 +257,7 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { const spans = transaction.spans || []; const internalRequestSpans = spans - .filter((s: { op?: string }) => s.op === 'hono.request') + .filter((s: { origin?: string }) => s.origin === 'auto.http.hono.internal_request') .sort( (a: { start_timestamp?: number }, b: { start_timestamp?: number }) => (a.start_timestamp ?? 0) - (b.start_timestamp ?? 0), @@ -270,7 +274,7 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { expect(internalRequestSpans[1]?.trace_id).toBe(traceId); }); - test('hono.request span has no error status for internal 4xx HTTPException', async ({ baseURL }) => { + test('internal-request span has no error status for internal 4xx HTTPException', async ({ baseURL }) => { const transactionPromise = waitForTransaction(APP_NAME, event => { return ( event.contexts?.trace?.op === 'http.server' && @@ -283,7 +287,9 @@ test.describe('multi-fetch: internal .request() calls between sub-apps', () => { const transaction = await transactionPromise; const spans = transaction.spans || []; - const internalRequestSpans = spans.filter((s: { op?: string }) => s.op === 'hono.request'); + const internalRequestSpans = spans.filter( + (s: { origin?: string }) => s.origin === 'auto.http.hono.internal_request', + ); expect(internalRequestSpans).toHaveLength(1); expect(internalRequestSpans[0]?.status).not.toBe('internal_error'); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts index 88dc03adecc8..b6eac56cc0a0 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts @@ -62,9 +62,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'express.type': 'request_handler', 'http.route': '/test-transaction', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/test-transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -105,7 +105,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -117,7 +117,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { timestamp: expect.any(Number), status: 'ok', origin: 'auto.http.nestjs', - op: 'handler.nestjs', + op: 'handler', }, ]), transaction: 'GET /test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts index b606ef7eed53..03593be28685 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts @@ -66,9 +66,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'express.type': 'request_handler', 'http.route': '/test-transaction', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/test-transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -109,7 +109,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -121,7 +121,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { timestamp: expect.any(Number), status: 'ok', origin: 'auto.http.nestjs', - op: 'handler.nestjs', + op: 'handler', }, ]), transaction: 'GET /test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts index 66e69b630304..2e040acb1772 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts @@ -88,9 +88,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'express.type': 'request_handler', 'http.route': '/test-transaction', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/test-transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -131,7 +131,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -143,7 +143,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { timestamp: expect.any(Number), status: 'ok', origin: 'auto.http.nestjs', - op: 'handler.nestjs', + op: 'handler', }, ]), transaction: 'GET /test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts index 70c272838a4d..c264e5cbfd7f 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts @@ -83,14 +83,14 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.fastify', - 'sentry.op': 'request_handler.fastify', + 'sentry.op': 'handler', 'hook.name': 'fastify -> @sentry/instrumentation-fastify -> @fastify/middie - route-handler', 'fastify.type': 'request-handler', 'http.route': '/test-transaction', 'hook.callback.name': 'anonymous', }, description: '@fastify/middie - route-handler', - op: 'request_handler.fastify', + op: 'handler', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), @@ -125,7 +125,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -136,7 +136,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', - op: 'handler.nestjs', + op: 'handler', origin: 'auto.http.nestjs', }, { @@ -799,7 +799,7 @@ test('Sets error status on nest spans when a handler throws', async ({ baseURL } expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ op: 'request_context.nestjs', status: 'internal_error' }), - expect.objectContaining({ op: 'handler.nestjs', status: 'internal_error' }), + expect.objectContaining({ op: 'handler', status: 'internal_error' }), ]), ); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-orchestrion/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-orchestrion/tests/transactions.test.ts index 41c6c93f4e75..a61e3727a669 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-orchestrion/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-orchestrion/tests/transactions.test.ts @@ -60,7 +60,7 @@ test('request_context + handler: a route transaction nests the nestjs spans', as // request_handler span: wraps the controller method itself. const handler = (transactionEvent.spans ?? []).find( - span => span.op === 'handler.nestjs' && span.description === 'testTransaction', + span => span.op === 'handler' && span.description === 'testTransaction', ); expect(handler).toBeDefined(); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts index c2cec87de93b..27a666af610c 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts @@ -62,9 +62,9 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'express.type': 'request_handler', 'http.route': '/example-module/transaction', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/example-module/transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -105,7 +105,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -117,7 +117,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { timestamp: expect.any(Number), status: 'ok', origin: 'auto.http.nestjs', - op: 'handler.nestjs', + op: 'handler', }, ]), transaction: 'GET /example-module/transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts index 1b6a02b747e2..1d29fdfad9a7 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts @@ -62,9 +62,9 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'express.type': 'request_handler', 'http.route': '/example-module/transaction', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/example-module/transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -105,7 +105,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.nestjs', - 'sentry.op': 'handler.nestjs', + 'sentry.op': 'handler', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -117,7 +117,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { timestamp: expect.any(Number), status: 'ok', origin: 'auto.http.nestjs', - op: 'handler.nestjs', + op: 'handler', }, ]), transaction: 'GET /example-module/transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts index 33468ad705c7..427c9f334910 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts @@ -102,9 +102,9 @@ test('Should record a transaction for route with parameters', async ({ request } 'express.type': 'request_handler', 'http.route': '/test-transaction/:param', 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', }, - op: 'request_handler.express', + op: 'handler', description: '/test-transaction/:param', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts index 9ed354830fc8..024b5efa126d 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts @@ -86,13 +86,13 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-transaction', 'express.name': '/test-transaction', 'express.type': 'request_handler', }, description: '/test-transaction', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts index 75b9ffe2f716..4a45adad7839 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts @@ -86,13 +86,13 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-transaction', 'express.name': '/test-transaction', 'express.type': 'request_handler', }, description: '/test-transaction', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts index dbe870bd4c16..e3a7944dc28a 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts @@ -86,13 +86,13 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-transaction', 'express.name': '/test-transaction', 'express.type': 'request_handler', }, description: '/test-transaction', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts index 717d049158a1..8629fefe2efb 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts @@ -122,13 +122,13 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-transaction', 'express.name': '/test-transaction', 'express.type': 'request_handler', }, description: '/test-transaction', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -198,14 +198,14 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-exception/:id', 'express.name': '/test-exception/:id', 'express.type': 'request_handler', 'error.type': 'Error', }, description: '/test-exception/:id', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts index 11b27509023d..281d1028678c 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts @@ -75,7 +75,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.otel.fastify', - 'sentry.op': 'request_handler.fastify', + 'sentry.op': 'handler', 'fastify.root': '@sentry/instrumentation-fastify', 'http.request.method': 'GET', 'url.path': '/test-transaction', @@ -83,7 +83,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'http.response.status_code': 200, }, description: 'GET /test-transaction', - op: 'request_handler.fastify', + op: 'handler', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), @@ -97,12 +97,12 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: expect.objectContaining({ 'sentry.origin': 'auto.http.otel.fastify', - 'sentry.op': 'request_handler.fastify', + 'sentry.op': 'handler', 'fastify.type': expect.stringMatching(/request[-_]handler/), 'http.route': '/test-transaction', }), description: expect.stringContaining('sentry-fastify-error-handler'), - op: 'request_handler.fastify', + op: 'handler', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-framework/tests/performance/trace-propagation.test.ts b/dev-packages/e2e-tests/test-applications/react-router-7-framework/tests/performance/trace-propagation.test.ts index e9b2c9409154..b62e784ff3e3 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-7-framework/tests/performance/trace-propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-7-framework/tests/performance/trace-propagation.test.ts @@ -32,7 +32,7 @@ test.describe('Trace propagation', () => { expect(clientTx.contexts?.trace?.trace_id).toEqual(serverTx.contexts?.trace?.trace_id); - const requestHandlerSpan = serverTx.spans?.find(span => span.op === 'request_handler.express'); + const requestHandlerSpan = serverTx.spans?.find(span => span.op === 'handler'); expect(requestHandlerSpan).toBeDefined(); expect(clientTx.contexts?.trace?.parent_span_id).toBe(requestHandlerSpan?.span_id); diff --git a/dev-packages/e2e-tests/test-applications/react-router-8-framework/tests/performance/trace-propagation.test.ts b/dev-packages/e2e-tests/test-applications/react-router-8-framework/tests/performance/trace-propagation.test.ts index 4ce133514ce3..2c888675429e 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-8-framework/tests/performance/trace-propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-8-framework/tests/performance/trace-propagation.test.ts @@ -32,7 +32,7 @@ test.describe('Trace propagation', () => { expect(clientTx.contexts?.trace?.trace_id).toEqual(serverTx.contexts?.trace?.trace_id); - const requestHandlerSpan = serverTx.spans?.find(span => span.op === 'request_handler.express'); + const requestHandlerSpan = serverTx.spans?.find(span => span.op === 'handler'); expect(requestHandlerSpan).toBeDefined(); expect(clientTx.contexts?.trace?.parent_span_id).toBe(requestHandlerSpan?.span_id); diff --git a/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts index b2408811daac..b86a86f6adc8 100644 --- a/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts @@ -108,13 +108,13 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-transaction', 'express.name': '/test-transaction', 'express.type': 'request_handler', }, description: '/test-transaction', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), @@ -184,14 +184,14 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) expect(spans).toContainEqual({ data: { 'sentry.origin': 'auto.http.express', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'http.route': '/test-exception/:id', 'express.name': '/test-exception/:id', 'express.type': 'request_handler', 'error.type': 'Error', }, description: '/test-exception/:id', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), span_id: expect.stringMatching(/[a-f0-9]{16}/), diff --git a/dev-packages/node-integration-tests/suites/express/tracing/test.ts b/dev-packages/node-integration-tests/suites/express/tracing/test.ts index 882732ff8d3b..9aac6f7518b3 100644 --- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts +++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts @@ -41,7 +41,7 @@ describe('express tracing', () => { 'express.type': 'request_handler', }), description: '/test/express', - op: 'request_handler.express', + op: 'handler', origin: 'auto.http.express', }), ]), diff --git a/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts b/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts index f20dc2ca767b..0806abf3de72 100644 --- a/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/fastify/test.ts @@ -26,10 +26,10 @@ describe('fastify auto-instrumentation', () => { }), }), expect.objectContaining({ - op: 'request_handler.fastify', + op: 'handler', origin: 'auto.http.otel.fastify', data: expect.objectContaining({ - 'sentry.op': 'request_handler.fastify', + 'sentry.op': 'handler', 'sentry.origin': 'auto.http.otel.fastify', }), }), diff --git a/dev-packages/node-integration-tests/suites/tracing/hapi/scenario.mjs b/dev-packages/node-integration-tests/suites/tracing/hapi/scenario.mjs index 1aa7e8846b9f..2b7589f0f345 100644 --- a/dev-packages/node-integration-tests/suites/tracing/hapi/scenario.mjs +++ b/dev-packages/node-integration-tests/suites/tracing/hapi/scenario.mjs @@ -51,7 +51,7 @@ const run = async () => { }, }); - // Route registered via a plugin produces a `plugin.hapi` span. + // Route registered via a plugin produces a `function` op span. await server.register({ name: 'testPlugin', version: '1.0.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts b/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts index 7999ff26d914..b908a5ed13fd 100644 --- a/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts @@ -58,13 +58,13 @@ describe('hapi auto-instrumentation', () => { spans: expect.arrayContaining([ expect.objectContaining({ description: 'GET /plugin-route', - op: 'plugin.hapi', + op: 'handler', origin, data: expect.objectContaining({ 'http.route': '/plugin-route', 'hapi.type': 'plugin', 'hapi.plugin.name': 'testPlugin', - 'sentry.op': 'plugin.hapi', + 'sentry.op': 'handler', 'sentry.origin': origin, }), }), diff --git a/dev-packages/node-integration-tests/suites/tracing/ignoreSpans-streamed/children/test.ts b/dev-packages/node-integration-tests/suites/tracing/ignoreSpans-streamed/children/test.ts index 9dc823fab5de..c1ac1f7fc4a6 100644 --- a/dev-packages/node-integration-tests/suites/tracing/ignoreSpans-streamed/children/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/ignoreSpans-streamed/children/test.ts @@ -33,7 +33,7 @@ describe('filtering child spans with ignoreSpans (streaming)', () => { ); const queryMiddlewareSpan = getSpan('query', 'middleware'); const corsMiddlewareSpan = getSpan('corsMiddleware', 'middleware'); - const requestHandlerSpan = getSpan('/test/express', 'request_handler.express'); + const requestHandlerSpan = getSpan('/test/express', 'handler'); const httpServerSpan = getSpan('GET /test/express', 'http.server'); const customSpan = getSpan('custom', 'custom'); const customGrandchildSpan = getSpan('custom-grandchild', 'custom'); diff --git a/packages/core/src/integrations/express/patch-layer.ts b/packages/core/src/integrations/express/patch-layer.ts index 059dbca039f7..f55554566a26 100644 --- a/packages/core/src/integrations/express/patch-layer.ts +++ b/packages/core/src/integrations/express/patch-layer.ts @@ -124,7 +124,13 @@ export function patchLayer( const type = metadata.attributes[ATTR_EXPRESS_TYPE]; const attributes: SpanAttributes = Object.assign(metadata.attributes, { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.express', - [SENTRY_OP]: type === 'middleware' ? WEB_SERVER_MIDDLEWARE_SPAN_OP : `${type}.express`, + [SENTRY_OP]: + type === 'middleware' + ? WEB_SERVER_MIDDLEWARE_SPAN_OP + : type === 'request_handler' + ? // TODO(conventions): Replace with the `handler` span op constant once it is released in `@sentry/conventions`. + 'handler' + : `${type}.express`, }); if (actualMatchedRoute) { attributes[ATTR_HTTP_ROUTE] = actualMatchedRoute; diff --git a/packages/core/test/lib/integrations/express/patch-layer.test.ts b/packages/core/test/lib/integrations/express/patch-layer.test.ts index aada88147215..5dfea7cce636 100644 --- a/packages/core/test/lib/integrations/express/patch-layer.test.ts +++ b/packages/core/test/lib/integrations/express/patch-layer.test.ts @@ -349,7 +349,7 @@ describe('patchLayer', () => { 'express.name': 'a/:boo/:car/layerPath', 'express.type': 'request_handler', 'http.route': '/a/:boo/:car/layerPath', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'sentry.origin': 'auto.http.express', }, description: 'a/:boo/:car/layerPath', @@ -403,7 +403,7 @@ describe('patchLayer', () => { 'express.name': 'a/:boo/:car', 'express.type': 'request_handler', 'http.route': '/a/:boo/:car', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'sentry.origin': 'auto.http.express', }, description: 'a/:boo/:car', @@ -414,7 +414,7 @@ describe('patchLayer', () => { 'express.name': 'a/:boo/:car', 'express.type': 'request_handler', 'http.route': '/a/:boo/:car', - 'sentry.op': 'request_handler.express', + 'sentry.op': 'handler', 'sentry.origin': 'auto.http.express', }, description: 'a/:boo/:car', diff --git a/packages/elysia/src/withElysia.ts b/packages/elysia/src/withElysia.ts index 30253e0caad6..fd1279275c33 100644 --- a/packages/elysia/src/withElysia.ts +++ b/packages/elysia/src/withElysia.ts @@ -34,7 +34,8 @@ const ELYSIA_LIFECYCLE_OP_MAP: Record = { Parse: WEB_SERVER_MIDDLEWARE_SPAN_OP, Transform: WEB_SERVER_MIDDLEWARE_SPAN_OP, BeforeHandle: WEB_SERVER_MIDDLEWARE_SPAN_OP, - Handle: 'request_handler.elysia', + // TODO(conventions): Replace with the `handler` span op constant once it is released in `@sentry/conventions`. + Handle: 'handler', AfterHandle: WEB_SERVER_MIDDLEWARE_SPAN_OP, MapResponse: WEB_SERVER_MIDDLEWARE_SPAN_OP, AfterResponse: WEB_SERVER_MIDDLEWARE_SPAN_OP, diff --git a/packages/hono/src/shared/patchAppRequest.ts b/packages/hono/src/shared/patchAppRequest.ts index d70b379eba1e..7f40c86aab12 100644 --- a/packages/hono/src/shared/patchAppRequest.ts +++ b/packages/hono/src/shared/patchAppRequest.ts @@ -1,8 +1,9 @@ +import { SENTRY_OP } from '@sentry/conventions/attributes'; +import { WEB_SERVER_HTTP_SERVER_SPAN_OP } from '@sentry/conventions/op'; import { debug, getActiveSpan, getOriginalFunction, - SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan, type WrappedFunction, @@ -10,7 +11,7 @@ import { import type { Env, Hono } from 'hono'; import { DEBUG_BUILD } from '../debug-build'; -const INTERNAL_REQUEST_OP = 'hono.request'; +const INTERNAL_REQUEST_OP = WEB_SERVER_HTTP_SERVER_SPAN_OP; const INTERNAL_REQUEST_ORIGIN = 'auto.http.hono.internal_request'; function extractPathname(input: string | Request | URL): string { @@ -23,7 +24,7 @@ function extractPathname(input: string | Request | URL): string { /** * Patches `app.request()` on a Hono instance so that each internal dispatch - * is traced as a `hono.request` span — child of whatever span is active at + * is traced as an `http.server` span — child of whatever span is active at * the call site. * * `.request()` is a class field (arrow function), so this must run per-instance. @@ -53,10 +54,9 @@ export function patchAppRequest(app: Hono): void { return startSpan( { name: `${method} ${path}`, - op: INTERNAL_REQUEST_OP, onlyIfParent: true, attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: INTERNAL_REQUEST_OP, + [SENTRY_OP]: INTERNAL_REQUEST_OP, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: INTERNAL_REQUEST_ORIGIN, }, }, diff --git a/packages/hono/test/shared/applyPatches.test.ts b/packages/hono/test/shared/applyPatches.test.ts index 51a68859e614..129e83d341d2 100644 --- a/packages/hono/test/shared/applyPatches.test.ts +++ b/packages/hono/test/shared/applyPatches.test.ts @@ -583,9 +583,8 @@ describe('applyPatches', () => { expect(startSpanMock).toHaveBeenCalledWith( expect.objectContaining({ name: 'GET /hello', - op: 'hono.request', attributes: expect.objectContaining({ - 'sentry.op': 'hono.request', + 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.hono.internal_request', }), }), diff --git a/packages/hono/test/shared/earlyPatchRoute.test.ts b/packages/hono/test/shared/earlyPatchRoute.test.ts index bd748fda978c..3e2eee6208a7 100644 --- a/packages/hono/test/shared/earlyPatchRoute.test.ts +++ b/packages/hono/test/shared/earlyPatchRoute.test.ts @@ -56,10 +56,7 @@ describe('earlyPatchHono (two-phase prototype hook)', () => { await subApp.request('/hello'); expect(startSpanMock).toHaveBeenCalledTimes(1); - expect(startSpanMock).toHaveBeenCalledWith( - expect.objectContaining({ name: 'GET /hello', op: 'hono.request' }), - expect.any(Function), - ); + expect(startSpanMock).toHaveBeenCalledWith(expect.objectContaining({ name: 'GET /hello' }), expect.any(Function)); }); it('emits a debug log and applies patchAppRequest when sub-app was mounted before applyPatches', async () => { @@ -82,10 +79,7 @@ describe('earlyPatchHono (two-phase prototype hook)', () => { // patchAppRequest is applied retroactively await subApp.request('/hello'); - expect(startSpanMock).toHaveBeenCalledWith( - expect.objectContaining({ name: 'GET /hello', op: 'hono.request' }), - expect.any(Function), - ); + expect(startSpanMock).toHaveBeenCalledWith(expect.objectContaining({ name: 'GET /hello' }), expect.any(Function)); }); it('preserves correct route behavior', async () => { diff --git a/packages/hono/test/shared/patchAppRequest.test.ts b/packages/hono/test/shared/patchAppRequest.test.ts index 81fef4c52ace..bcd5ccf3a863 100644 --- a/packages/hono/test/shared/patchAppRequest.test.ts +++ b/packages/hono/test/shared/patchAppRequest.test.ts @@ -32,10 +32,9 @@ describe('patchAppRequest', () => { expect(startSpanMock).toHaveBeenCalledWith( expect.objectContaining({ name: 'GET /hello', - op: 'hono.request', onlyIfParent: true, attributes: expect.objectContaining({ - 'sentry.op': 'hono.request', + 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.hono.internal_request', }), }), diff --git a/packages/nestjs/src/integrations/wrap-route.ts b/packages/nestjs/src/integrations/wrap-route.ts index 47a8d1b4909a..78cd6e6957eb 100644 --- a/packages/nestjs/src/integrations/wrap-route.ts +++ b/packages/nestjs/src/integrations/wrap-route.ts @@ -1,4 +1,4 @@ -import { HTTP_METHOD, HTTP_ROUTE, URL_FULL } from '@sentry/conventions/attributes'; +import { HTTP_METHOD, HTTP_ROUTE, SENTRY_OP, URL_FULL } from '@sentry/conventions/attributes'; import type { SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core'; import type { AnyFn } from './helpers'; @@ -42,8 +42,8 @@ export function getAppCreationSpanOptions( } /** - * Wrap the route-handler callback so each invocation opens the `handler.nestjs` - * span (REQUEST_HANDLER). Preserve the original `.name` and reflect-metadata so + * Wrap the route-handler callback so each invocation opens the request-handler + * (`handler` op) span. Preserve the original `.name` and reflect-metadata so * NestJS reflection is unaffected. */ export function wrapRouteHandler(callback: AnyFn, moduleVersion?: string): AnyFn { @@ -53,15 +53,15 @@ export function wrapRouteHandler(callback: AnyFn, moduleVersion?: string): AnyFn const spanName = callback.name || 'anonymous nest handler'; const attributes: SpanAttributes = { component: NESTJS_COMPONENT, + // TODO(conventions): Replace with the `handler` span op constant once it is released in `@sentry/conventions`. + [SENTRY_OP]: 'handler', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: HTTP_ORIGIN, [AttributeNames.TYPE]: NestType.REQUEST_HANDLER, [AttributeNames.CALLBACK]: callback.name, [AttributeNames.VERSION]: moduleVersion || undefined, }; const wrapped = function (this: unknown, ...args: unknown[]): unknown { - return startSpan({ name: spanName, op: `${NestType.REQUEST_HANDLER}.nestjs`, attributes }, () => - callback.apply(this, args), - ); + return startSpan({ name: spanName, attributes }, () => callback.apply(this, args)); }; if (callback.name) { Object.defineProperty(wrapped, 'name', { value: callback.name }); diff --git a/packages/nestjs/test/integrations/orchestrion-subscriber.test.ts b/packages/nestjs/test/integrations/orchestrion-subscriber.test.ts index 8764075efe63..44171b9fe028 100644 --- a/packages/nestjs/test/integrations/orchestrion-subscriber.test.ts +++ b/packages/nestjs/test/integrations/orchestrion-subscriber.test.ts @@ -278,7 +278,7 @@ describe('NestJS orchestrion subscriber: request_context / request_handler', () expect(handlerSpanJson).toBeDefined(); expect(handlerSpanJson!.description).toBe('getCats'); - expect(handlerSpanJson!.op).toBe('handler.nestjs'); + expect(handlerSpanJson!.op).toBe('handler'); expect(handlerSpanJson!.origin).toBe('auto.http.nestjs'); expect(handlerSpanJson!.data).toMatchObject({ component: '@nestjs/core', diff --git a/packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts b/packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts index ec3bec8df771..3e89c424424d 100644 --- a/packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts +++ b/packages/server-utils/src/integrations/tracing-channel/express/instrumentation.ts @@ -221,7 +221,13 @@ function getSpanForLayer(data: HandleChannelContext, options: ExpressIntegration name, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SENTRY_OP]: type === 'middleware' ? WEB_SERVER_MIDDLEWARE_SPAN_OP : `${type}.express`, + [SENTRY_OP]: + type === 'middleware' + ? WEB_SERVER_MIDDLEWARE_SPAN_OP + : type === 'request_handler' + ? // TODO(conventions): Replace with the `handler` span op constant once it is released in `@sentry/conventions`. + 'handler' + : `${type}.express`, [ATTR_EXPRESS_NAME]: name, [ATTR_EXPRESS_TYPE]: type, ...(matchedRoute ? { [HTTP_ROUTE]: matchedRoute } : {}), diff --git a/packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts b/packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts index f37abddc651e..cb3f64d6eca0 100644 --- a/packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts +++ b/packages/server-utils/src/integrations/tracing-channel/fastify/instrumentation.ts @@ -43,7 +43,8 @@ const SUPPORTED_VERSIONS = '>=3.21.0 <6'; const ORIGIN = 'auto.http.otel.fastify'; const HOOK_OP = WEB_SERVER_MIDDLEWARE_SPAN_OP; -const REQUEST_HANDLER_OP = 'request_handler.fastify'; +// TODO(conventions): Replace with the `handler` span op constant once it is released in `@sentry/conventions`. +const REQUEST_HANDLER_OP = 'handler'; const FASTIFY_HOOKS = [ 'onRequest', @@ -182,6 +183,7 @@ function startRequestSpanHook(this: any, request: any, _reply: any, hookDone: () const attributes: Record = { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, + [SENTRY_OP]: REQUEST_HANDLER_OP, [ATTRIBUTE_FASTIFY_ROOT]: PACKAGE_NAME, [HTTP_REQUEST_METHOD]: request.method, [URL_PATH]: request.url, @@ -196,7 +198,6 @@ function startRequestSpanHook(this: any, request: any, _reply: any, hookDone: () const requestSpan = startInactiveSpan({ name: route != null ? `${request.method} ${route}` : 'request', - op: REQUEST_HANDLER_OP, attributes, }); request[kRequestSpan] = requestSpan; diff --git a/packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts b/packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts index 7bb9b7944232..9737978f8095 100644 --- a/packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts +++ b/packages/server-utils/src/integrations/tracing-channel/hapi-utils.ts @@ -2,12 +2,14 @@ * OTel-free, `@hapi/*`-free port of the span-building helpers and handler/ext * wrap logic from the vendored `@opentelemetry/instrumentation-hapi` * (upstream @opentelemetry/instrumentation-hapi@0.64.0). Span output (names, - * ops, origins, attributes) is kept byte-identical to that instrumentation; + * origins, attributes) is kept close to that instrumentation — except the + * plugin-route op, which is normalized to the cross-framework `handler` op; * span creation goes through the `@sentry/core` API and the OTel active-span * guard is replaced with `getActiveSpan()`. */ import { getActiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core'; +import { SENTRY_OP } from '@sentry/conventions/attributes'; import type { LifecycleMethod, PatchableExtMethod, @@ -104,12 +106,15 @@ export const getExtMetadata = ( }; function startMetadataSpan(metadata: SpanMetadata, original: () => unknown): unknown { + const hapiType = metadata.attributes[AttributeNames.HAPI_TYPE]; + // TODO(conventions): Replace `'handler'` with the `handler` span op constant once it is released in `@sentry/conventions`. + const op = hapiType === HapiLayerType.PLUGIN ? 'handler' : `${hapiType}.hapi`; return startSpan( { name: metadata.name, - op: `${metadata.attributes[AttributeNames.HAPI_TYPE]}.hapi`, attributes: { ...metadata.attributes, + [SENTRY_OP]: op, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.hapi', }, },