diff --git a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/fetch/test.ts b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/fetch/test.ts index 1d91e558afc8..f4708e8b336d 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/fetch/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/fetch/test.ts @@ -49,9 +49,7 @@ sentryTest('should update spans for GraphQL fetch requests', async ({ getLocalTe data: expect.objectContaining({ type: 'fetch', 'http.method': 'POST', - 'http.url': 'http://sentry-test.io/foo', 'url.full': 'http://sentry-test.io/foo', - url: 'http://sentry-test.io/foo', 'server.address': 'sentry-test.io', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-fetch/test.ts b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-fetch/test.ts index 48571bab503f..31ee18e6f6d4 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-fetch/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-fetch/test.ts @@ -43,9 +43,7 @@ sentryTest('should update spans for GraphQL persisted query fetch requests', asy data: expect.objectContaining({ type: 'fetch', 'http.method': 'POST', - 'http.url': 'http://sentry-test.io/graphql', 'url.full': 'http://sentry-test.io/graphql', - url: 'http://sentry-test.io/graphql', 'server.address': 'sentry-test.io', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-xhr/test.ts b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-xhr/test.ts index c7eda0d5bb00..bf5aeaa40393 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/persistedQuery-xhr/test.ts @@ -43,9 +43,7 @@ sentryTest('should update spans for GraphQL persisted query XHR requests', async data: { type: 'xhr', 'http.method': 'POST', - 'http.url': 'http://sentry-test.io/graphql', 'url.full': 'http://sentry-test.io/graphql', - url: 'http://sentry-test.io/graphql', 'server.address': 'sentry-test.io', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/xhr/test.ts b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/xhr/test.ts index 5d49fff05a05..c254d82c3e7d 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/graphqlClient/xhr/test.ts @@ -49,9 +49,7 @@ sentryTest('should update spans for GraphQL XHR requests', async ({ getLocalTest data: { type: 'xhr', 'http.method': 'POST', - 'http.url': 'http://sentry-test.io/foo', 'url.full': 'http://sentry-test.io/foo', - url: 'http://sentry-test.io/foo', 'server.address': 'sentry-test.io', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-data-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-data-url/test.ts index a763e21f3919..35b4950ed00c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-data-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-data-url/test.ts @@ -27,10 +27,8 @@ sentryTest('sanitizes data URLs in fetch span name and attributes', async ({ get expect(span?.data).toMatchObject({ 'http.method': 'GET', - url: sanitizedUrl, type: 'fetch', }); - expect(span?.data?.['http.url']).toBe(sanitizedUrl); expect(span?.data?.['url.full']).toBe(sanitizedUrl); }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-immediate/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-immediate/test.ts index ca594b323223..432b4188c359 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-immediate/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-immediate/test.ts @@ -31,9 +31,7 @@ sentryTest('should create spans for fetch requests called directly after init', trace_id: tracingEvent.contexts?.trace?.trace_id, data: { 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/0', 'url.full': 'http://sentry-test-site.example/0', - url: 'http://sentry-test-site.example/0', 'server.address': 'sentry-test-site.example', type: 'fetch', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts index 3033a1edc729..221b457a18e2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts @@ -29,9 +29,7 @@ sentryTest('should create spans for fetch requests', async ({ getLocalTestUrl, p trace_id: tracingEvent.contexts?.trace?.trace_id, data: { 'http.method': 'GET', - 'http.url': `${TEST_HOST}/test-req/${index}`, 'url.full': `${TEST_HOST}/test-req/${index}`, - url: `/test-req/${index}`, 'server.address': 'sentry-test.io', type: 'fetch', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed-track-stream-performance/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed-track-stream-performance/test.ts index 115dbff69881..c8261692dbfa 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed-track-stream-performance/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed-track-stream-performance/test.ts @@ -53,7 +53,7 @@ sentryTest( name: 'GET http://sentry-test-site.example/delayed', attributes: expect.objectContaining({ 'http.method': { type: 'string', value: 'GET' }, - url: { type: 'string', value: 'http://sentry-test-site.example/delayed' }, + 'url.full': { type: 'string', value: 'http://sentry-test-site.example/delayed' }, type: { type: 'string', value: 'fetch' }, }), }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed/test.ts index 6e93d04c9b85..1568115bb908 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-streamed/test.ts @@ -22,7 +22,7 @@ sentryTest('creates spans for fetch requests', async ({ getLocalTestUrl, page }) const requestSpans = allSpans .filter(s => getSpanOp(s) === 'http.client') .sort((a, b) => - (a.attributes!['http.url']!.value as string).localeCompare(b.attributes!['http.url']!.value as string), + (a.attributes!['url.full']!.value as string).localeCompare(b.attributes!['url.full']!.value as string), ); expect(requestSpans).toHaveLength(3); @@ -37,9 +37,7 @@ sentryTest('creates spans for fetch requests', async ({ getLocalTestUrl, page }) trace_id: pageloadSpan?.trace_id, attributes: expect.objectContaining({ 'http.method': { type: 'string', value: 'GET' }, - 'http.url': { type: 'string', value: `http://sentry-test-site.example/${index}` }, 'url.full': { type: 'string', value: `http://sentry-test-site.example/${index}` }, - url: { type: 'string', value: `http://sentry-test-site.example/${index}` }, 'server.address': { type: 'string', value: 'sentry-test-site.example' }, type: { type: 'string', value: 'fetch' }, }), diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-strip-query-and-fragment/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-strip-query-and-fragment/test.ts index e2b3e346a214..cbac553aa21a 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-strip-query-and-fragment/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-strip-query-and-fragment/test.ts @@ -30,20 +30,18 @@ sentryTest('strips query params in fetch request spans', async ({ getLocalTestUr trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/0?id=123;page=5', 'url.full': 'http://sentry-test-site.example/0?id=123;page=5', - 'http.query': '?id=123;page=5', + 'url.query': 'id=123;page=5', 'http.response.status_code': 200, 'http.response_content_length': 2, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'fetch', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/0?id=123;page=5', }), }); - expect(requestSpan?.data).not.toHaveProperty('http.fragment'); + expect(requestSpan?.data).not.toHaveProperty('url.fragment'); }); sentryTest('strips hash fragment in fetch request spans', async ({ getLocalTestUrl, page }) => { @@ -74,20 +72,18 @@ sentryTest('strips hash fragment in fetch request spans', async ({ getLocalTestU trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/1#fragment', 'url.full': 'http://sentry-test-site.example/1#fragment', - 'http.fragment': '#fragment', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'http.response_content_length': 2, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'fetch', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/1#fragment', }), }); - expect(requestSpan?.data).not.toHaveProperty('http.query'); + expect(requestSpan?.data).not.toHaveProperty('url.query'); }); sentryTest('strips hash fragment and query params in fetch request spans', async ({ getLocalTestUrl, page }) => { @@ -118,17 +114,15 @@ sentryTest('strips hash fragment and query params in fetch request spans', async trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/2?id=1#fragment', 'url.full': 'http://sentry-test-site.example/2?id=1#fragment', - 'http.query': '?id=1', - 'http.fragment': '#fragment', + 'url.query': 'id=1', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'http.response_content_length': 2, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'fetch', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/2?id=1#fragment', }), }); }); @@ -163,17 +157,15 @@ sentryTest( trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test.io/api/users?id=1#fragment', 'url.full': 'http://sentry-test.io/api/users?id=1#fragment', - 'http.query': '?id=1', - 'http.fragment': '#fragment', + 'url.query': 'id=1', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'http.response_content_length': 2, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'fetch', 'server.address': 'sentry-test.io', - url: '/api/users?id=1#fragment', }), }); }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts index f208e2c6e620..5b62a5752c63 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts @@ -32,9 +32,7 @@ sentryTest('should create spans for fetch requests', async ({ getLocalTestUrl, p trace_id: tracingEvent.contexts?.trace?.trace_id, data: { 'http.method': 'GET', - 'http.url': `http://sentry-test-site.example/${index}`, 'url.full': `http://sentry-test-site.example/${index}`, - url: `http://sentry-test-site.example/${index}`, 'server.address': 'sentry-test-site.example', type: 'fetch', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-data-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-data-url/test.ts index f115b687e05f..ebf06272e1c2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-data-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-data-url/test.ts @@ -22,10 +22,8 @@ sentryTest('sanitizes data URLs in XHR span name and attributes', async ({ getLo expect(span?.data).toMatchObject({ 'http.method': 'GET', - url: sanitizedUrl, type: 'xhr', }); - expect(span?.data?.['http.url']).toBe(sanitizedUrl); expect(span?.data?.['url.full']).toBe(sanitizedUrl); }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts index 0970c762ba3c..c01f4ce5b04c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts @@ -29,9 +29,7 @@ sentryTest('should create spans for xhr requests', async ({ getLocalTestUrl, pag trace_id: tracingEvent.contexts?.trace?.trace_id, data: { 'http.method': 'GET', - 'http.url': `${TEST_HOST}/test-req/${index}`, 'url.full': `${TEST_HOST}/test-req/${index}`, - url: `/test-req/${index}`, 'server.address': 'sentry-test.io', type: 'xhr', }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-streamed/test.ts index a04daec4dc2f..4e40cc6829c3 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-streamed/test.ts @@ -22,7 +22,7 @@ sentryTest('creates spans for XHR requests', async ({ getLocalTestUrl, page }) = const requestSpans = allSpans .filter(s => getSpanOp(s) === 'http.client') .sort((a, b) => - (a.attributes!['http.url']!.value as string).localeCompare(b.attributes!['http.url']!.value as string), + (a.attributes!['url.full']!.value as string).localeCompare(b.attributes!['url.full']!.value as string), ); expect(requestSpans).toHaveLength(3); @@ -37,9 +37,7 @@ sentryTest('creates spans for XHR requests', async ({ getLocalTestUrl, page }) = trace_id: pageloadSpan?.trace_id, attributes: expect.objectContaining({ 'http.method': { type: 'string', value: 'GET' }, - 'http.url': { type: 'string', value: `http://sentry-test-site.example/${index}` }, 'url.full': { type: 'string', value: `http://sentry-test-site.example/${index}` }, - url: { type: 'string', value: `http://sentry-test-site.example/${index}` }, 'server.address': { type: 'string', value: 'sentry-test-site.example' }, type: { type: 'string', value: 'xhr' }, }), diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-strip-query-and-fragment/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-strip-query-and-fragment/test.ts index 30c08c5cb61b..67d41160e659 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-strip-query-and-fragment/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-strip-query-and-fragment/test.ts @@ -30,19 +30,17 @@ sentryTest('strips query params in XHR request spans', async ({ getLocalTestUrl, trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/0?id=123;page=5', 'url.full': 'http://sentry-test-site.example/0?id=123;page=5', - 'http.query': '?id=123;page=5', + 'url.query': 'id=123;page=5', 'http.response.status_code': 200, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'xhr', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/0?id=123;page=5', }), }); - expect(requestSpan?.data).not.toHaveProperty('http.fragment'); + expect(requestSpan?.data).not.toHaveProperty('url.fragment'); }); sentryTest('strips hash fragment in XHR request spans', async ({ getLocalTestUrl, page }) => { @@ -73,19 +71,17 @@ sentryTest('strips hash fragment in XHR request spans', async ({ getLocalTestUrl trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/1#fragment', 'url.full': 'http://sentry-test-site.example/1#fragment', - 'http.fragment': '#fragment', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'xhr', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/1#fragment', }), }); - expect(requestSpan?.data).not.toHaveProperty('http.query'); + expect(requestSpan?.data).not.toHaveProperty('url.query'); }); sentryTest('strips hash fragment and query params in XHR request spans', async ({ getLocalTestUrl, page }) => { @@ -116,16 +112,14 @@ sentryTest('strips hash fragment and query params in XHR request spans', async ( trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test-site.example/2?id=1#fragment', 'url.full': 'http://sentry-test-site.example/2?id=1#fragment', - 'http.query': '?id=1', - 'http.fragment': '#fragment', + 'url.query': 'id=1', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'xhr', 'server.address': 'sentry-test-site.example', - url: 'http://sentry-test-site.example/2?id=1#fragment', }), }); }); @@ -160,16 +154,14 @@ sentryTest( trace_id: transactionEvent.contexts?.trace?.trace_id, data: expect.objectContaining({ 'http.method': 'GET', - 'http.url': 'http://sentry-test.io/api/users?id=1#fragment', 'url.full': 'http://sentry-test.io/api/users?id=1#fragment', - 'http.query': '?id=1', - 'http.fragment': '#fragment', + 'url.query': 'id=1', + 'url.fragment': 'fragment', 'http.response.status_code': 200, 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', type: 'xhr', 'server.address': 'sentry-test.io', - url: '/api/users?id=1#fragment', }), }); }, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts index 400e0395eaf8..ed9832dee74e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts @@ -27,9 +27,7 @@ sentryTest('should create spans for XHR requests', async ({ getLocalTestUrl, pag trace_id: eventData.contexts?.trace?.trace_id, data: { 'http.method': 'GET', - 'http.url': `http://sentry-test-site.example/${index}`, 'url.full': `http://sentry-test-site.example/${index}`, - url: `http://sentry-test-site.example/${index}`, 'server.address': 'sentry-test-site.example', type: 'xhr', }, diff --git a/dev-packages/e2e-tests/test-applications/astro-4/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-4/tests/tracing.dynamic.test.ts index e9d7c87eb5ac..6eff51ea9829 100644 --- a/dev-packages/e2e-tests/test-applications/astro-4/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-4/tests/tracing.dynamic.test.ts @@ -80,7 +80,7 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => { 'sentry.origin': 'auto.http.astro', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: expect.stringContaining('/test-ssr'), + 'url.full': expect.stringContaining('/test-ssr'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -230,7 +230,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/myUsername123'), + 'url.full': expect.stringContaining('/user-page/myUsername123'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -252,7 +252,6 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.origin': 'auto.http.otel.node_fetch', 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'url.path': '/api/user/myUsername123.json', - url: expect.stringContaining('/api/user/myUsername123.json'), }, }); @@ -268,7 +267,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate', 'http.request.header.accept_language': '*', @@ -325,7 +324,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/catchAll/hell0/whatever-do'), + 'url.full': expect.stringContaining('/catchAll/hell0/whatever-do'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -382,7 +381,7 @@ test.describe('parametrized vs static paths', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/settings'), + 'url.full': expect.stringContaining('/user-page/settings'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', diff --git a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts index 9a6ab99afbec..2b9d7b27750f 100644 --- a/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-5/tests/tracing.dynamic.test.ts @@ -81,7 +81,7 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => { 'sentry.origin': 'auto.http.astro', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: expect.stringContaining('/test-ssr'), + 'url.full': expect.stringContaining('/test-ssr'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -236,7 +236,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/myUsername123'), + 'url.full': expect.stringContaining('/user-page/myUsername123'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -258,7 +258,6 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.origin': 'auto.http.otel.node_fetch', 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'url.path': '/api/user/myUsername123.json', - url: expect.stringContaining('/api/user/myUsername123.json'), }, }); @@ -274,7 +273,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate', 'http.request.header.accept_language': '*', @@ -334,7 +333,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/catchAll/hell0/whatever-do'), + 'url.full': expect.stringContaining('/catchAll/hell0/whatever-do'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -394,7 +393,7 @@ test.describe('parametrized vs static paths', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/settings'), + 'url.full': expect.stringContaining('/user-page/settings'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', diff --git a/dev-packages/e2e-tests/test-applications/astro-6-cf-workers/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-6-cf-workers/tests/tracing.dynamic.test.ts index 548b709fdbcf..e94dcc2957d8 100644 --- a/dev-packages/e2e-tests/test-applications/astro-6-cf-workers/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-6-cf-workers/tests/tracing.dynamic.test.ts @@ -241,8 +241,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { data: { 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.fetch', - url: expect.stringContaining('/api/user/myUsername123.json'), - 'http.url': 'http://localhost:3030/api/user/myUsername123.json', + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'url.full': 'http://localhost:3030/api/user/myUsername123.json', }, }); diff --git a/dev-packages/e2e-tests/test-applications/astro-6/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-6/tests/tracing.dynamic.test.ts index 83f6db0fae4f..f0bf78387f78 100644 --- a/dev-packages/e2e-tests/test-applications/astro-6/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-6/tests/tracing.dynamic.test.ts @@ -81,7 +81,7 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => { 'sentry.origin': 'auto.http.astro', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: expect.stringContaining('/test-ssr'), + 'url.full': expect.stringContaining('/test-ssr'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -236,7 +236,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/myUsername123'), + 'url.full': expect.stringContaining('/user-page/myUsername123'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -258,7 +258,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.origin': 'auto.http.otel.node_fetch', 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'url.path': '/api/user/myUsername123.json', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), }, }); @@ -274,7 +274,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate', 'http.request.header.accept_language': '*', @@ -334,7 +334,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/catchAll/hell0/whatever-do'), + 'url.full': expect.stringContaining('/catchAll/hell0/whatever-do'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -394,7 +394,7 @@ test.describe('parametrized vs static paths', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/settings'), + 'url.full': expect.stringContaining('/user-page/settings'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', diff --git a/dev-packages/e2e-tests/test-applications/astro-7/tests/advanced-routing.test.ts b/dev-packages/e2e-tests/test-applications/astro-7/tests/advanced-routing.test.ts index 0b94323e233e..6f16d9105f51 100644 --- a/dev-packages/e2e-tests/test-applications/astro-7/tests/advanced-routing.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-7/tests/advanced-routing.test.ts @@ -37,7 +37,7 @@ test.describe('astro 7 advanced routing (src/fetch.ts)', () => { origin: 'auto.http.astro', data: expect.objectContaining({ 'sentry.source': 'route', - url: expect.stringContaining('/user-page/myUsername123'), + 'url.full': expect.stringContaining('/user-page/myUsername123'), }), }); }); diff --git a/dev-packages/e2e-tests/test-applications/astro-7/tests/tracing.dynamic.test.ts b/dev-packages/e2e-tests/test-applications/astro-7/tests/tracing.dynamic.test.ts index 0806d939b529..97a451094932 100644 --- a/dev-packages/e2e-tests/test-applications/astro-7/tests/tracing.dynamic.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-7/tests/tracing.dynamic.test.ts @@ -78,7 +78,7 @@ test.describe('tracing in dynamically rendered (ssr) routes', () => { 'sentry.origin': 'auto.http.astro', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: expect.stringContaining('/test-ssr'), + 'url.full': expect.stringContaining('/test-ssr'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -230,7 +230,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/myUsername123'), + 'url.full': expect.stringContaining('/user-page/myUsername123'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -252,7 +252,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.origin': 'auto.http.otel.node_fetch', 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'url.path': '/api/user/myUsername123.json', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), }, }); @@ -268,7 +268,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/api/user/myUsername123.json'), + 'url.full': expect.stringContaining('/api/user/myUsername123.json'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate', 'http.request.header.accept_language': '*', @@ -325,7 +325,7 @@ test.describe('nested SSR routes (client, server, server request)', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/catchAll/hell0/whatever-do'), + 'url.full': expect.stringContaining('/catchAll/hell0/whatever-do'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', @@ -382,7 +382,7 @@ test.describe('parametrized vs static paths', () => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.astro', 'sentry.source': 'route', - url: expect.stringContaining('/user-page/settings'), + 'url.full': expect.stringContaining('/user-page/settings'), 'http.request.header.accept': expect.any(String), 'http.request.header.accept_encoding': 'gzip, deflate, br, zstd', 'http.request.header.accept_language': 'en-US', diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts index 63b167e819fb..dbe6829d41b1 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts @@ -60,7 +60,7 @@ test.describe('Lambda layer', () => { data: expect.objectContaining({ 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', - url: 'http://example.com/', + 'url.full': 'http://example.com/', }), description: 'GET http://example.com/', op: 'http.client', @@ -128,7 +128,7 @@ test.describe('Lambda layer', () => { data: expect.objectContaining({ 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', - url: 'http://example.com/', + 'url.full': 'http://example.com/', }), description: 'GET http://example.com/', op: 'http.client', diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts index 2faed1e5bd52..76edf8a934b2 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts @@ -46,7 +46,7 @@ test.describe('NPM package', () => { data: expect.objectContaining({ 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', - url: 'http://example.com/', + 'url.full': 'http://example.com/', }), description: 'GET http://example.com/', op: 'http.client', @@ -114,7 +114,7 @@ test.describe('NPM package', () => { data: expect.objectContaining({ 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', - url: 'http://example.com/', + 'url.full': 'http://example.com/', }), description: 'GET http://example.com/', op: 'http.client', 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 2c27dc0cea0a..a74974887857 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 d35693a7bea2..ba552bee7b89 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 ecc6b8829b58..575fc85c62d0 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 @@ -45,10 +45,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts index 46795aaaf527..fba209a9b966 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts @@ -60,10 +60,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-http/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, 'url.path': `/test-outgoing-http/${id}`, 'http.host': 'localhost:3030', @@ -101,10 +99,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', @@ -193,10 +189,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-fetch/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.path': `/test-outgoing-fetch/${id}`, 'http.host': 'localhost:3030', @@ -234,10 +228,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', 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 818756943c5e..da61b73d3b1b 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 @@ -24,10 +24,9 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', + 'url.full': 'http://localhost:3030/test-transaction', 'http.host': 'localhost:3030', 'net.host.name': 'localhost', 'http.method': 'GET', @@ -108,11 +107,10 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'nestjs.version': expect.any(String), 'nestjs.type': 'request_context', 'http.method': 'GET', - 'http.url': '/test-transaction', + 'url.full': '/test-transaction', 'http.route': '/test-transaction', 'nestjs.controller': 'AppController', 'nestjs.callback': 'testTransaction', - url: '/test-transaction', }, description: 'GET /test-transaction', parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), 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 56a4251a6c34..a5f3370f0cde 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/example-module/transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/example-module/transaction', 'url.full': 'http://localhost:3030/example-module/transaction', 'url.path': '/example-module/transaction', 'http.host': 'localhost:3030', 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 1944e9444f3b..9112118a2c93 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/example-module/transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/example-module/transaction', 'url.full': 'http://localhost:3030/example-module/transaction', 'url.path': '/example-module/transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts index 3e61e3a3e855..c0bc1512565b 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts @@ -129,10 +129,8 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru 'sentry.origin': 'auto.http.otel.node_fetch', 'server.address': 'localhost', 'server.port': 3030, - url: 'http://localhost:3030/', 'url.full': 'http://localhost:3030/', 'url.path': '/', - 'url.query': '', 'url.scheme': 'http', 'user_agent.original': 'node', }, diff --git a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/middleware.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/middleware.test.ts index a76f98fb80e8..36052deaf5c2 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/middleware.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-pages-dir/tests/middleware.test.ts @@ -73,8 +73,6 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru 'http.method': 'GET', 'http.response.status_code': 200, type: 'fetch', - url: 'http://localhost:3030/', - 'http.url': 'http://localhost:3030/', 'url.full': 'http://localhost:3030/', 'server.address': 'localhost:3030', 'sentry.op': 'http.client', diff --git a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts index cb7fbbe46f01..bc6cbde21393 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts @@ -43,7 +43,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/test-transaction/1', - 'http.url': 'http://localhost:3030/test-transaction/1', + 'url.full': 'http://localhost:3030/test-transaction/1', 'http.user_agent': expect.any(String), 'net.host.ip': expect.any(String), 'net.host.name': 'localhost', @@ -56,7 +56,6 @@ test('Should record a transaction for route with parameters', async ({ request } 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: 'http://localhost:3030/test-transaction/1', }), ); 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 9b1960bb4e78..d51e9639696a 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 @@ -43,7 +43,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/test-transaction/1', - 'http.url': 'http://localhost:3030/test-transaction/1', + 'url.full': 'http://localhost:3030/test-transaction/1', 'http.user_agent': expect.any(String), 'net.host.ip': expect.any(String), 'net.host.name': 'localhost', @@ -56,7 +56,6 @@ test('Should record a transaction for route with parameters', async ({ request } 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: 'http://localhost:3030/test-transaction/1', }), ); diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts index 393128ef9fb8..fb089b27b5f0 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts @@ -43,7 +43,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/test-transaction/1', - 'http.url': 'http://localhost:3030/test-transaction/1', + 'url.full': 'http://localhost:3030/test-transaction/1', 'http.user_agent': expect.any(String), 'net.host.ip': expect.any(String), 'net.host.name': 'localhost', @@ -56,7 +56,6 @@ test('Should record a transaction for route with parameters', async ({ request } 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: 'http://localhost:3030/test-transaction/1', }), ); @@ -139,7 +138,7 @@ test('Should record spans from http instrumentation', async ({ request }) => { 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/', - 'http.url': 'http://example.com/', + 'url.full': 'http://example.com/', 'net.peer.ip': expect.any(String), 'net.peer.name': 'example.com', 'net.peer.port': 80, @@ -147,7 +146,6 @@ test('Should record spans from http instrumentation', async ({ request }) => { 'sentry.kind': 'client', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', - url: 'http://example.com/', }), description: 'GET http://example.com/', 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 76f6c59bb29e..ee74f97b9cf3 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 2b1d6b691c35..6727e24c0512 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 08030a7f9852..dbe870bd4c16 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 501b1adb29e0..4783478a7403 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts index 2f474eed8915..abda01da852d 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts @@ -60,10 +60,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-http/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, 'url.path': `/test-outgoing-http/${id}`, 'http.host': 'localhost:3030', @@ -101,10 +99,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', @@ -193,10 +189,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-fetch/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.path': `/test-outgoing-fetch/${id}`, 'http.host': 'localhost:3030', @@ -234,10 +228,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', 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 c13b2e51af24..b5c72b180d96 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 @@ -24,10 +24,8 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts index 41602ab0f6a2..63c198a954bb 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts @@ -60,10 +60,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-http/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, 'url.path': `/test-outgoing-http/${id}`, 'http.host': 'localhost:3030', @@ -101,10 +99,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', @@ -193,10 +189,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-fetch/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.path': `/test-outgoing-fetch/${id}`, 'http.host': 'localhost:3030', @@ -234,10 +228,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts index b0341f8a2b04..8c0017620628 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts index 96c230b6eec9..94014c521af5 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts @@ -60,10 +60,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-http/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, 'url.path': `/test-outgoing-http/${id}`, 'http.host': 'localhost:3030', @@ -101,10 +99,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', @@ -193,10 +189,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-fetch/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.path': `/test-outgoing-fetch/${id}`, 'http.host': 'localhost:3030', @@ -234,10 +228,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts index a1f342cf0df5..d820e157c36e 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts index 3f6c8e10244f..4e324dc5f0f5 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts @@ -18,10 +18,8 @@ test('Sends successful transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-success', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-success', 'url.full': 'http://localhost:3030/test-success', 'url.path': '/test-success', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts index a892a0f6cf83..b86df1bcfa7c 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts @@ -59,10 +59,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-http/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, 'url.path': `/test-outgoing-http/${id}`, 'http.host': 'localhost:3030', @@ -100,10 +98,8 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', @@ -192,10 +188,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: `http://localhost:3030/test-outgoing-fetch/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.path': `/test-outgoing-fetch/${id}`, 'http.host': 'localhost:3030', @@ -233,10 +227,8 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.source': 'route', 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', - url: `http://localhost:3030/test-inbound-headers/${id}`, 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, 'url.path': `/test-inbound-headers/${id}`, 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts index 028663808973..43236447a973 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/tracing.test.ts index 825babc01780..bf1166abd65d 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-dynamic-import/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.test.ts index 321d61a8753a..869aa9670ed5 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/tracing.test.ts index b7c49676cc4f..8dfdbc13f4b2 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-top-level-import/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.test.ts index fbd8e13d0d25..693a702ba10b 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.test.ts index 4839cc87dd57..7f4a0978012b 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/nuxt-5/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-5/tests/tracing.test.ts index 9c456d50d85a..67cb2074d192 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-5/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-5/tests/tracing.test.ts @@ -110,7 +110,7 @@ test.describe('distributed tracing', () => { description: `GET /api/user/${PARAM}`, // fixme: parametrize parent_span_id: clientTxnEvent.contexts?.trace?.span_id, // pageload span is parent data: expect.objectContaining({ - url: `/api/user/${PARAM}`, + 'url.full': expect.stringContaining(`/api/user/${PARAM}`), type: 'fetch', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.browser', diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-lazy-routes/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-router-7-lazy-routes/tests/transactions.test.ts index 1eafc263022e..ff1a65bea2f0 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-7-lazy-routes/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-7-lazy-routes/tests/transactions.test.ts @@ -1414,8 +1414,7 @@ test('Second navigation span is not corrupted by first slow lazy handler complet // The /api/slow-data fetch is triggered by the slow-fetch route's lazy loading if (anotherLazyTransaction) { const leakedSpans = anotherLazyTransaction.spans.filter( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (span: any) => span.description?.includes('slow-data') || span.data?.url?.includes('slow-data'), + span => span.description?.includes('slow-data') || span.data?.['url.full'].includes('slow-data'), ); expect(leakedSpans.length).toBe(0); } @@ -1428,7 +1427,7 @@ test('Second navigation span is not corrupted by first slow lazy handler complet // Verify slow-fetch transaction doesn't contain spans that belong to /another-lazy const wrongSpans = slowFetchTransaction.spans.filter( // eslint-disable-next-line @typescript-eslint/no-explicit-any - (span: any) => span.description?.includes('another-lazy') || span.data?.url?.includes('another-lazy'), + (span: any) => span.description?.includes('another-lazy') || span.data?.['url.full'].includes('another-lazy'), ); expect(wrongSpans.length).toBe(0); } @@ -1512,7 +1511,7 @@ test('GQL fetch span is attributed to the correct navigation transaction when na const pageloadGqlSpans = pageloadSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => span.op === 'http.client' && - (span.description?.includes('/api/graphql') || span.data?.url?.includes('/api/graphql')), + (span.description?.includes('/api/graphql') || span.data?.['url.full'].includes('/api/graphql')), ); expect(pageloadGqlSpans.length).toBe(0); @@ -1534,14 +1533,16 @@ test('GQL fetch span is attributed to the correct navigation transaction when na const navSpans = navigationEvent.spans || []; const userASpans = navSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserAQuery') || span.data?.url?.includes('UserAQuery')), + span.op === 'http.client' && + (span.description?.includes('UserAQuery') || span.data?.['url.full'].includes('UserAQuery')), ); expect(userASpans.length).toBe(1); // Verify NO UserBQuery spans leaked into this transaction const userBSpans = navSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserBQuery') || span.data?.url?.includes('UserBQuery')), + span.op === 'http.client' && + (span.description?.includes('UserBQuery') || span.data?.['url.full'].includes('UserBQuery')), ); expect(userBSpans.length).toBe(0); }); @@ -1572,14 +1573,16 @@ test('GQL fetch spans are attributed to correct navigation transactions when nav const firstNavSpans = firstNavEvent.spans || []; const firstUserASpans = firstNavSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserAQuery') || span.data?.url?.includes('UserAQuery')), + span.op === 'http.client' && + (span.description?.includes('UserAQuery') || span.data?.['url.full'].includes('UserAQuery')), ); expect(firstUserASpans.length).toBe(1); // First navigation must NOT contain UserBQuery spans const firstUserBSpans = firstNavSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserBQuery') || span.data?.url?.includes('UserBQuery')), + span.op === 'http.client' && + (span.description?.includes('UserBQuery') || span.data?.['url.full'].includes('UserBQuery')), ); expect(firstUserBSpans.length).toBe(0); @@ -1603,14 +1606,16 @@ test('GQL fetch spans are attributed to correct navigation transactions when nav const secondNavSpans = secondNavEvent.spans || []; const secondUserBSpans = secondNavSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserBQuery') || span.data?.url?.includes('UserBQuery')), + span.op === 'http.client' && + (span.description?.includes('UserBQuery') || span.data?.['url.full'].includes('UserBQuery')), ); expect(secondUserBSpans.length).toBe(1); // Second navigation must NOT contain UserAQuery spans (no leaking from first nav) const secondUserASpans = secondNavSpans.filter( (span: { op?: string; description?: string; data?: { url?: string } }) => - span.op === 'http.client' && (span.description?.includes('UserAQuery') || span.data?.url?.includes('UserAQuery')), + span.op === 'http.client' && + (span.description?.includes('UserAQuery') || span.data?.['url.full'].includes('UserAQuery')), ); expect(secondUserASpans.length).toBe(0); diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.server.test.ts index 9c2668a7c6c8..c5b0f7c98543 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.server.test.ts @@ -81,7 +81,6 @@ test('server pageload request span has nested request span for sub request', asy data: expect.objectContaining({ 'http.method': 'GET', 'http.route': '/api/users', - 'http.url': 'http://localhost:3030/api/users', 'url.full': 'http://localhost:3030/api/users', 'url.path': '/api/users', 'sentry.op': 'http.server', @@ -90,7 +89,6 @@ test('server pageload request span has nested request span for sub request', asy 'sveltekit.is_data_request': false, 'sveltekit.is_sub_request': true, 'sveltekit.tracing.original_name': 'sveltekit.handle.root', - url: 'http://localhost:3030/api/users', }), description: 'GET /api/users', op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.test.ts index 8d422b40cd3a..f4aafa58f9b3 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-kit-tracing/tests/tracing.test.ts @@ -180,7 +180,7 @@ test('record client-side universal load fetch span and trace', async ({ page }) op: 'http.client', origin: 'auto.http.browser', data: { - url: expect.stringContaining('/api/users'), + 'url.full': expect.stringContaining('/api/users'), type: 'fetch', 'http.method': 'GET', 'http.response.status_code': 200, diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/tests/performance.test.ts index 237da437acad..9b036d7e7d85 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/tests/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/tests/performance.test.ts @@ -173,7 +173,7 @@ test.describe('performance events', () => { op: 'http.client', origin: 'auto.http.browser', data: { - url: expect.stringContaining('/api/users'), + 'url.full': expect.stringContaining('/api/users'), type: 'fetch', 'http.method': 'GET', 'http.response.status_code': 200, diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-2/tests/performance.test.ts index 73324dea0151..82177d597bbc 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/tests/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/tests/performance.test.ts @@ -173,7 +173,7 @@ test.describe('performance events', () => { op: 'http.client', origin: 'auto.http.browser', data: { - url: expect.stringContaining('/api/users'), + 'url.full': expect.stringContaining('/api/users'), type: 'fetch', 'http.method': 'GET', 'http.response.status_code': 200, diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.server.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.server.test.ts index f3ad6d3a7e03..f988ed0ae4b1 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.server.test.ts @@ -81,14 +81,13 @@ test('server pageload request span has nested request span for sub request', asy data: expect.objectContaining({ 'http.method': 'GET', 'http.route': '/api/users', - 'http.url': 'https://localhost:3030/api/users', + 'url.full': 'https://localhost:3030/api/users', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.sveltekit', 'sentry.source': 'route', 'sveltekit.is_data_request': false, 'sveltekit.is_sub_request': true, 'sveltekit.tracing.original_name': 'sveltekit.handle.root', - url: 'https://localhost:3030/api/users', }), description: 'GET /api/users', op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.test.ts b/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.test.ts index 25e2901eb21f..d57704d69412 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/sveltekit-3/tests/tracing.test.ts @@ -165,7 +165,7 @@ test('record client-side universal load fetch span and trace', async ({ page }) op: 'http.client', origin: 'auto.http.browser', data: { - url: expect.stringContaining('/api/users'), + 'url.full': expect.stringContaining('/api/users'), type: 'fetch', 'http.method': 'GET', 'http.response.status_code': 200, 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 4371f2a8178e..367af4d115ad 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 @@ -19,10 +19,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', 'sentry.sample_rate': 1, - url: 'http://localhost:3030/test-transaction', 'sentry.kind': 'server', 'http.response.status_code': 200, - 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', 'url.path': '/test-transaction', 'http.host': 'localhost:3030', 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 20fe459e2997..d3df34d3bea1 100644 --- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts +++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts @@ -18,7 +18,7 @@ describe('express tracing', () => { span_id: expect.stringMatching(/[a-f\d]{16}/), trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { - url: expect.stringMatching(/\/test\/express$/), + 'url.full': expect.stringMatching(/\/test\/express$/), 'http.response.status_code': 200, }, op: 'http.server', @@ -65,7 +65,7 @@ describe('express tracing', () => { trace_id: expect.stringMatching(/[a-f\d]{32}/), span_id: expect.stringMatching(/[a-f\d]{16}/), data: { - url: expect.stringMatching(/\/test\/regex$/), + 'url.full': expect.stringMatching(/\/test\/regex$/), 'http.response.status_code': 200, }, op: 'http.server', @@ -142,9 +142,8 @@ describe('express tracing', () => { trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { 'http.response.status_code': 200, - url: expect.stringMatching(/\/$/), 'http.method': 'GET', - 'http.url': expect.stringMatching(/\/$/), + 'url.full': expect.stringMatching(/\/$/), 'http.route': '/', 'http.target': '/', }, @@ -188,7 +187,7 @@ describe('express tracing', () => { trace_id: expect.stringMatching(/[a-f\d]{32}/), span_id: expect.stringMatching(/[a-f\d]{16}/), data: { - url: expect.stringMatching(`/test/${segment}$`), + 'url.full': expect.stringMatching(`/test/${segment}$`), 'http.response.status_code': 200, }, op: 'http.server', @@ -225,7 +224,7 @@ describe('express tracing', () => { trace_id: expect.stringMatching(/[a-f\d]{32}/), span_id: expect.stringMatching(/[a-f\d]{16}/), data: { - url: expect.stringMatching(`/test/${segment}$`), + 'url.full': expect.stringMatching(`/test/${segment}$`), 'http.response.status_code': 200, }, op: 'http.server', @@ -403,9 +402,8 @@ describe('express tracing', () => { trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { 'http.response.status_code': status_code, - url: expect.stringMatching(url), 'http.method': 'GET', - 'http.url': expect.stringMatching(url), + 'url.full': expect.stringMatching(url), 'http.target': url, }, op: 'http.server', diff --git a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts index 33a5c30bb4a6..16150f7cfd11 100644 --- a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts @@ -26,12 +26,10 @@ describe('outgoing fetch spans - strip query', () => { expect(txn.spans).toHaveLength(1); expect(txn.spans?.[0]).toMatchObject({ data: { - url: `${SERVER_URL}/api/v0/users`, 'url.full': `${SERVER_URL}/api/v0/users?id=1`, 'url.path': '/api/v0/users', - 'url.query': '?id=1', + 'url.query': 'id=1', 'url.scheme': 'http', - 'http.query': 'id=1', 'http.request.method': 'GET', 'http.request.method_original': 'GET', 'http.response.status_code': 200, diff --git a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts index 6a65673ca7da..89b93622cce1 100644 --- a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts @@ -26,13 +26,12 @@ describe('outgoing http spans - strip query', () => { expect(txn.spans).toHaveLength(1); expect(txn.spans?.[0]).toMatchObject({ data: { - url: `${SERVER_URL}/api/v0/users`, - 'http.url': `${SERVER_URL}/api/v0/users?id=1`, + 'url.full': `${SERVER_URL}/api/v0/users?id=1`, 'http.target': '/api/v0/users?id=1', 'http.flavor': '1.1', 'http.host': expect.stringMatching(/localhost:\d+$/), 'http.method': 'GET', - 'http.query': 'id=1', + 'url.query': 'id=1', 'http.response.status_code': 200, 'http.response_content_length_uncompressed': 0, 'http.status_code': 200, diff --git a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts index f5705ac88f81..c3b6cd63ec9f 100644 --- a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts @@ -31,7 +31,7 @@ describe('httpIntegration', () => { span_id: expect.stringMatching(/[a-f\d]{16}/), trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { - url: expect.stringMatching(/\/test$/), + 'url.full': expect.stringMatching(/\/test$/), 'http.response.status_code': 200, attr1: 'yes', attr2: 'yes', @@ -73,7 +73,7 @@ describe('httpIntegration', () => { span_id: expect.stringMatching(/[a-f\d]{16}/), trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { - url: expect.stringMatching(/\/test$/), + 'url.full': expect.stringMatching(/\/test$/), 'http.response.status_code': 200, incomingRequestSpanHook: 'yes', }, @@ -110,14 +110,13 @@ describe('httpIntegration', () => { 'http.flavor': '1.1', 'http.host': `localhost:${port}`, 'http.method': 'GET', - 'http.query': 'a=1&b=2', + 'url.query': 'a=1&b=2', 'http.response.status_code': 200, 'http.route': '/test', 'http.scheme': 'http', 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/test?a=1&b=2', - 'http.url': `http://localhost:${port}/test?a=1&b=2`, 'http.user_agent': 'node', 'net.host.ip': '::1', 'net.host.name': 'localhost', @@ -130,7 +129,6 @@ describe('httpIntegration', () => { 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: `http://localhost:${port}/test`, [URL_FULL]: `http://localhost:${port}/test?a=1&b=2`, [URL_PATH]: '/test', ...getCommonHttpRequestHeaders(), @@ -153,7 +151,7 @@ describe('httpIntegration', () => { 'http.flavor': '1.1', 'http.host': `localhost:${port}`, 'http.method': 'POST', - 'http.query': 'a=1&b=2', + 'url.query': 'a=1&b=2', 'http.request_content_length_uncompressed': 9, 'http.response.status_code': 200, 'http.route': '/test', @@ -161,7 +159,6 @@ describe('httpIntegration', () => { 'http.status_code': 200, 'http.status_text': 'OK', 'http.target': '/test?a=1&b=2', - 'http.url': `http://localhost:${port}/test?a=1&b=2`, 'http.user_agent': 'node', 'net.host.ip': '::1', 'net.host.name': 'localhost', @@ -174,7 +171,6 @@ describe('httpIntegration', () => { 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, 'sentry.source': 'route', - url: `http://localhost:${port}/test`, [URL_FULL]: `http://localhost:${port}/test?a=1&b=2`, [URL_PATH]: '/test', 'http.request.header.content_length': '9', @@ -441,7 +437,7 @@ describe('httpIntegration', () => { span_id: expect.stringMatching(/[a-f\d]{16}/), trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { - url: expect.stringMatching(/\/test$/), + 'url.full': expect.stringMatching(/\/test$/), 'http.response.status_code': 200, }, op: 'http.server', @@ -467,7 +463,7 @@ describe('httpIntegration', () => { span_id: expect.stringMatching(/[a-f\d]{16}/), trace_id: expect.stringMatching(/[a-f\d]{32}/), data: { - url: expect.stringMatching(/\/test$/), + 'url.full': expect.stringMatching(/\/test$/), 'http.response.status_code': 200, }, op: 'http.server', @@ -547,7 +543,7 @@ describe('httpIntegration', () => { .expect({ transaction: event => { expect(event.transaction).toBe('GET /test'); - expect(event.contexts?.trace?.data?.url).toMatch(/\/test$/); + expect(event.contexts?.trace?.data?.['url.full']).toMatch(/\/test$/); expect(event.contexts?.trace?.op).toBe('http.server'); expect(event.contexts?.trace?.status).toBe('ok'); }, @@ -570,7 +566,7 @@ describe('httpIntegration', () => { .expect({ transaction: event => { expect(event.transaction).toBe('GET /favicon.ico'); - expect(event.contexts?.trace?.data?.url).toMatch(/\/favicon.ico$/); + expect(event.contexts?.trace?.data?.['url.full']).toMatch(/\/favicon.ico$/); expect(event.contexts?.trace?.op).toBe('http.server'); expect(event.contexts?.trace?.status).toBe('ok'); }, diff --git a/dev-packages/node-integration-tests/suites/tracing/requestData-streamed/test.ts b/dev-packages/node-integration-tests/suites/tracing/requestData-streamed/test.ts index 314bb0cd4cfb..009e7bde7721 100644 --- a/dev-packages/node-integration-tests/suites/tracing/requestData-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/requestData-streamed/test.ts @@ -131,9 +131,9 @@ describe('requestData-streamed', () => { expect(serverSpan).toBeDefined(); - // url.query and user.ip_address are only set by applyScopeToSegmentSpan - // (not by OTel instrumentation), so they should be absent when the integration is removed - expect(serverSpan?.attributes['url.query']).toBeUndefined(); + // user.ip_address is only set by applyScopeToSegmentSpan (not by OTel instrumentation), + // so it should be absent when the integration is removed. `url.query` is set by + // `httpServerSpansIntegration` itself, so it stays present either way. expect(serverSpan?.attributes['user.ip_address']).toBeUndefined(); }, }) diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index 3825e199c742..b6af07fd03d0 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -134,7 +134,7 @@ export class TraceService implements OnDestroy { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.angular', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', - url: strippedUrl, + [URL_FULL]: strippedUrl, ...(navigationEvent.navigationTrigger && { navigationTrigger: navigationEvent.navigationTrigger, }), diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index 5631338bd63b..b4c593dfc573 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -1,15 +1,16 @@ /* eslint-disable max-lines */ -import { URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { HTTP_ROUTE, URL_FRAGMENT, URL_FULL, URL_PATH, URL_QUERY } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes } from '@sentry/core'; import { addNonEnumerableProperty, flushIfServerless, getIsolationScope, getRootSpan, + getUrlFragment, + getUrlQuery, objectify, SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, spanToJSON, - stripUrlQueryAndFragment, winterCGRequestToRequestData, } from '@sentry/core'; import { @@ -221,7 +222,6 @@ async function instrumentRequestStartHttpServerSpan( method, [URL_FULL]: ctx.url.href, [URL_PATH]: ctx.url.pathname, - url: stripUrlQueryAndFragment(ctx.url.href), ...httpHeadersToSpanAttributes( winterCGHeadersToDict(request.headers), getClient()?.getDataCollectionOptions() ?? false, @@ -229,16 +229,11 @@ async function instrumentRequestStartHttpServerSpan( }; if (parametrizedRoute) { - attributes['http.route'] = parametrizedRoute; + attributes[HTTP_ROUTE] = parametrizedRoute; } - if (ctx.url.search) { - attributes['http.query'] = ctx.url.search; - } - - if (ctx.url.hash) { - attributes['http.fragment'] = ctx.url.hash; - } + attributes[URL_QUERY] = getUrlQuery(ctx.url.search); + attributes[URL_FRAGMENT] = getUrlFragment(ctx.url.hash); isolationScope.setTransactionName(`${method} ${parametrizedRoute || ctx.url.pathname}`); diff --git a/packages/astro/test/server/middleware.test.ts b/packages/astro/test/server/middleware.test.ts index 9f051ebd703e..4cac21a74845 100644 --- a/packages/astro/test/server/middleware.test.ts +++ b/packages/astro/test/server/middleware.test.ts @@ -117,7 +117,6 @@ describe('sentryMiddleware', () => { attributes: { 'sentry.origin': 'auto.http.astro', method: 'GET', - url: 'https://mydomain.io/users/123/details', [URL_FULL]: 'https://mydomain.io/users/123/details', [URL_PATH]: '/users/123/details', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', @@ -156,7 +155,6 @@ describe('sentryMiddleware', () => { attributes: { 'sentry.origin': 'auto.http.astro', method: 'GET', - url: 'http://localhost:1234/a%xx', [URL_FULL]: 'http://localhost:1234/a%xx', [URL_PATH]: 'a%xx', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', diff --git a/packages/browser/src/integrations/fetchStreamPerformance.ts b/packages/browser/src/integrations/fetchStreamPerformance.ts index 6481e2783b7c..dd3342a31cc7 100644 --- a/packages/browser/src/integrations/fetchStreamPerformance.ts +++ b/packages/browser/src/integrations/fetchStreamPerformance.ts @@ -1,3 +1,4 @@ +import { URL_FULL } from '@sentry/conventions/attributes'; import type { IntegrationFn, Span } from '@sentry/core'; import { addFetchEndInstrumentationHandler, @@ -80,7 +81,7 @@ export const fetchStreamPerformanceIntegration = defineIntegration(() => { name: `${method} ${sanitizedUrl}`, startTime: handlerData.endTimestamp, attributes: { - url: stripDataUrlContent(url), + [URL_FULL]: stripDataUrlContent(url), 'http.method': method, type: 'fetch', [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client.stream', diff --git a/packages/browser/src/integrations/graphqlClient.ts b/packages/browser/src/integrations/graphqlClient.ts index 71c05d8381a3..eafead683d22 100644 --- a/packages/browser/src/integrations/graphqlClient.ts +++ b/packages/browser/src/integrations/graphqlClient.ts @@ -68,9 +68,7 @@ function _updateSpanWithGraphQLData(client: Client, options: GraphQLClientOption return; } - // Fall back to `url` because fetch instrumentation only sets `http.url` for absolute URLs; - // relative URLs end up only in `url` (see `getFetchSpanAttributes` in packages/core/src/fetch.ts). - const httpUrl = spanAttributes[URL_FULL] || spanAttributes['http.url'] || spanAttributes['url']; + const httpUrl = spanAttributes[URL_FULL]; const httpMethod = spanAttributes[SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD] || spanAttributes['http.method']; if (!isString(httpUrl) || !isString(httpMethod)) { diff --git a/packages/browser/src/tracing/request.ts b/packages/browser/src/tracing/request.ts index 1c33ceb1f8af..1a236bdcf1c7 100644 --- a/packages/browser/src/tracing/request.ts +++ b/packages/browser/src/tracing/request.ts @@ -14,6 +14,8 @@ import { getClient, getLocationHref, getTraceData, + getUrlFragment, + getUrlQuery, hasSpansEnabled, hasSpanStreamingEnabled, instrumentFetchRequest, @@ -40,7 +42,7 @@ import { } from '@sentry/browser-utils'; import type { BrowserClient } from '../client'; import { baggageHeaderHasSentryValues, createHeadersSafely, getFullURL, isPerformanceResourceTiming } from './utils'; -import { HTTP_URL, URL_FULL } from '@sentry/conventions/attributes'; +import { HTTP_METHOD, SERVER_ADDRESS, URL_FRAGMENT, URL_FULL, URL_QUERY } from '@sentry/conventions/attributes'; /** Options for Request Instrumentation */ export interface RequestInstrumentationOptions { @@ -173,10 +175,6 @@ export function instrumentOutgoingRequests(client: Client, _options?: Partial { op: 'http.client', attributes: { 'http.method': 'POST', - 'http.url': 'http://localhost:4000/graphql', [URL_FULL]: 'http://localhost:4000/graphql', url: 'http://localhost:4000/graphql', }, @@ -391,15 +390,14 @@ describe('GraphqlClient', () => { expect(json.data['graphql.document']).toBe(requestBody.query); }); - test('enriches http.client span for relative URLs (only url attribute)', () => { + test('enriches http.client span for relative URLs', () => { const handler = setupHandler([/\/graphql$/]); - // Fetch instrumentation does not set `http.url` or `url.full` for relative URLs. const span = new SentrySpan({ name: 'POST /graphql', op: 'http.client', attributes: { 'http.method': 'POST', - url: '/graphql', + [URL_FULL]: '/graphql', }, }); @@ -452,7 +450,6 @@ describe('GraphqlClient', () => { op: 'http.client', attributes: { 'http.method': 'POST', - 'http.url': 'http://localhost:4000/graphql', [URL_FULL]: 'http://localhost:4000/graphql', url: 'http://localhost:4000/graphql', }, diff --git a/packages/bun/src/integrations/bunserver.ts b/packages/bun/src/integrations/bunserver.ts index 6ff72e9eb754..d6fd4650e7cb 100644 --- a/packages/bun/src/integrations/bunserver.ts +++ b/packages/bun/src/integrations/bunserver.ts @@ -4,6 +4,8 @@ import { continueTrace, defineIntegration, getClient, + getUrlFragment, + getUrlQuery, httpHeadersToSpanAttributes, isURLObjectRelative, parseStringToURLObject, @@ -15,7 +17,15 @@ import { withIsolationScope, } from '@sentry/core'; import type { ServeOptions } from 'bun'; -import { URL_FULL } from '@sentry/conventions/attributes'; +import { + URL_DOMAIN, + URL_FRAGMENT, + URL_FULL, + URL_PATH, + URL_PORT, + URL_QUERY, + URL_SCHEME, +} from '@sentry/conventions/attributes'; const INTEGRATION_NAME = 'BunServer' as const; @@ -273,25 +283,21 @@ function getSpanAttributesFromParsedUrl( }; if (parsedUrl) { - if (parsedUrl.search) { - attributes['url.query'] = parsedUrl.search; - } - if (parsedUrl.hash) { - attributes['url.fragment'] = parsedUrl.hash; - } + attributes[URL_QUERY] = getUrlQuery(parsedUrl.search); + attributes[URL_FRAGMENT] = getUrlFragment(parsedUrl.hash); if (parsedUrl.pathname) { - attributes['url.path'] = parsedUrl.pathname; + attributes[URL_PATH] = parsedUrl.pathname; } if (!isURLObjectRelative(parsedUrl)) { attributes[URL_FULL] = parsedUrl.href; if (parsedUrl.port) { - attributes['url.port'] = parsedUrl.port; + attributes[URL_PORT] = parsedUrl.port; } if (parsedUrl.protocol) { - attributes['url.scheme'] = parsedUrl.protocol; + attributes[URL_SCHEME] = parsedUrl.protocol; } if (parsedUrl.hostname) { - attributes['url.domain'] = parsedUrl.hostname; + attributes[URL_DOMAIN] = parsedUrl.hostname; } } } diff --git a/packages/bun/test/integrations/bunserver.test.ts b/packages/bun/test/integrations/bunserver.test.ts index a4774ada9ed7..775de5236c55 100644 --- a/packages/bun/test/integrations/bunserver.test.ts +++ b/packages/bun/test/integrations/bunserver.test.ts @@ -48,7 +48,7 @@ describe('Bun Serve Integration', () => { 'sentry.origin': 'auto.http.bun.serve', 'http.request.method': 'GET', 'sentry.source': 'url', - 'url.query': '?id=123', + 'url.query': 'id=123', 'url.path': '/users', 'url.full': `http://localhost:${port}/users?id=123`, 'url.port': port.toString(), diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index 7887de49c687..39902cbe9454 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -1,4 +1,5 @@ -import { HTTP_URL, URL_FULL } from '@sentry/conventions/attributes'; +/* eslint-disable max-lines */ +import { HTTP_METHOD, SERVER_ADDRESS, URL_FRAGMENT, URL_FULL, URL_QUERY } from '@sentry/conventions/attributes'; import { getClient } from './currentScopes'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from './semanticAttributes'; import { setHttpStatus, SPAN_STATUS_ERROR, spanIsIgnored, startInactiveSpan } from './tracing'; @@ -15,6 +16,8 @@ import { getActiveSpan } from './utils/spanUtils'; import { getTraceData } from './utils/traceData'; import { getSanitizedUrlStringFromUrlObject, + getUrlFragment, + getUrlQuery, isURLObjectRelative, parseStringToURLObject, stripDataUrlContent, @@ -385,25 +388,20 @@ function getFetchSpanAttributes( spanOrigin: SpanOrigin, ): SpanAttributes { const attributes: SpanAttributes = { - url: stripDataUrlContent(url), + [URL_FULL]: stripDataUrlContent(url), type: 'fetch', - 'http.method': method, + // oxlint-disable-next-line typescript/no-deprecated + [HTTP_METHOD]: method, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client', }; if (parsedUrl) { if (!isURLObjectRelative(parsedUrl)) { - // oxlint-disable-next-line typescript/no-deprecated - attributes[HTTP_URL] = stripDataUrlContent(parsedUrl.href); attributes[URL_FULL] = stripDataUrlContent(parsedUrl.href); - attributes['server.address'] = parsedUrl.host; - } - if (parsedUrl.search) { - attributes['http.query'] = parsedUrl.search; - } - if (parsedUrl.hash) { - attributes['http.fragment'] = parsedUrl.hash; + attributes[SERVER_ADDRESS] = parsedUrl.host; } + attributes[URL_QUERY] = getUrlQuery(parsedUrl.search); + attributes[URL_FRAGMENT] = getUrlFragment(parsedUrl.hash); } return attributes; } diff --git a/packages/core/src/integrations/http/add-outgoing-request-breadcrumb.ts b/packages/core/src/integrations/http/add-outgoing-request-breadcrumb.ts index 251dbfc540a6..19d4ca60567b 100644 --- a/packages/core/src/integrations/http/add-outgoing-request-breadcrumb.ts +++ b/packages/core/src/integrations/http/add-outgoing-request-breadcrumb.ts @@ -1,6 +1,7 @@ +import { HTTP_METHOD, URL_FRAGMENT, URL_QUERY } from '@sentry/conventions/attributes'; import { addBreadcrumb } from '../../breadcrumbs'; import { getBreadcrumbLogLevelFromHttpStatusCode } from '../../utils/breadcrumb-log-level'; -import { getSanitizedUrlString, parseUrl } from '../../utils/url'; +import { getSanitizedUrlString, getUrlFragment, getUrlQuery, parseUrl } from '../../utils/url'; import { getRequestUrlFromClientRequest } from './get-request-url'; import type { HttpClientRequest, HttpIncomingMessage } from './types'; @@ -23,9 +24,10 @@ export function addOutgoingRequestBreadcrumb( data: { status_code: statusCode, url: getSanitizedUrlString(parsedUrl), - 'http.method': request.method || 'GET', - ...(parsedUrl.search ? { 'http.query': parsedUrl.search } : {}), - ...(parsedUrl.hash ? { 'http.fragment': parsedUrl.hash } : {}), + // eslint-disable-next-line typescript/no-deprecated + [HTTP_METHOD]: request.method || 'GET', + [URL_QUERY]: getUrlQuery(parsedUrl.search), + [URL_FRAGMENT]: getUrlFragment(parsedUrl.hash), }, type: 'http', level, diff --git a/packages/core/src/integrations/http/get-outgoing-span-data.ts b/packages/core/src/integrations/http/get-outgoing-span-data.ts index a3b0705122f7..618f124d3207 100644 --- a/packages/core/src/integrations/http/get-outgoing-span-data.ts +++ b/packages/core/src/integrations/http/get-outgoing-span-data.ts @@ -4,6 +4,15 @@ import { getHttpSpanDetailsFromUrlObject, parseStringToURLObject } from '../../u import type { HttpClientRequest, HttpIncomingMessage } from './types'; import { getRequestUrlFromClientRequest } from './get-request-url'; import type { StartSpanOptions } from '../../types/startSpanOptions'; +import { + HTTP_HOST, + HTTP_METHOD, + HTTP_TARGET, + NET_PEER_NAME, + SENTRY_KIND, + URL_FULL, + USER_AGENT_ORIGINAL, +} from '@sentry/conventions/attributes'; /** * Build the initial span name and attributes for an outgoing HTTP request. @@ -26,13 +35,15 @@ export function getOutgoingRequestSpanData(request: HttpClientRequest): StartSpa // TODO(v11): Update these to the Sentry semantic attributes for urls. // https://getsentry.github.io/sentry-conventions/attributes/ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client', - 'sentry.kind': 'client', - 'http.url': url, - 'http.method': request.method, - 'http.target': request.path || '/', - 'net.peer.name': request.host, - 'http.host': request.getHeader('host') as string | undefined, - ...(userAgent ? { 'user_agent.original': userAgent as string } : {}), + [SENTRY_KIND]: 'client', + [URL_FULL]: url, + /* eslint-disable typescript/no-deprecated */ + [HTTP_METHOD]: request.method, + [HTTP_TARGET]: request.path || '/', + [NET_PEER_NAME]: request.host, + [HTTP_HOST]: request.getHeader('host') as string | undefined, + /* eslint-enable typescript/no-deprecated */ + [USER_AGENT_ORIGINAL]: userAgent || undefined, ...attributes, }, onlyIfParent: true, diff --git a/packages/core/src/integrations/http/server-subscription.ts b/packages/core/src/integrations/http/server-subscription.ts index 95eb90ae5f92..e763ee591145 100644 --- a/packages/core/src/integrations/http/server-subscription.ts +++ b/packages/core/src/integrations/http/server-subscription.ts @@ -40,7 +40,7 @@ import { import { safeMathRandom } from '../../utils/randomSafeContext'; import type { SpanAttributes } from '../../types/span'; import type { SpanStatus } from '../../types/spanStatus'; -import { HTTP_URL, URL_FULL, URL_PATH, SENTRY_KIND } from '@sentry/conventions/attributes'; +import { URL_FULL, URL_PATH, SENTRY_KIND } from '@sentry/conventions/attributes'; // Tree-shakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; @@ -297,8 +297,6 @@ function buildServerSpanWrap( // Old Semantic Conventions attributes for compatibility [URL_FULL]: fullUrl, [URL_PATH]: urlObj?.pathname ?? httpTargetWithoutQueryFragment, - // oxlint-disable-next-line typescript-eslint(no-deprecated) - [HTTP_URL]: fullUrl, 'http.method': method, 'http.target': urlObj ? `${urlObj.pathname}${urlObj.search}` : httpTargetWithoutQueryFragment, 'http.host': host, diff --git a/packages/core/src/integrations/requestdata.ts b/packages/core/src/integrations/requestdata.ts index 8c4f0690073f..3470ec5ceb00 100644 --- a/packages/core/src/integrations/requestdata.ts +++ b/packages/core/src/integrations/requestdata.ts @@ -9,6 +9,7 @@ import type { QueryParams, RequestEventData } from '../types/request'; import type { StreamedSpanJSON } from '../types/span'; import { parseCookie } from '../utils/cookie'; import { httpHeadersToSpanAttributes } from '../utils/request'; +import { getUrlQuery } from '../utils/url'; import { getClientIPAddress, ipHeaderNames } from '../vendor/getIpAddress'; import { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan'; import { URL_FULL, URL_QUERY } from '@sentry/conventions/attributes'; @@ -230,7 +231,7 @@ function extractNormalizedRequestData( function normalizeQueryString(queryString: QueryParams): string | undefined { if (typeof queryString === 'string') { - return queryString || undefined; + return getUrlQuery(queryString); } const pairs = Array.isArray(queryString) ? queryString : Object.entries(queryString); diff --git a/packages/core/src/shared-exports.ts b/packages/core/src/shared-exports.ts index 788ebffeea63..700e65d2a974 100644 --- a/packages/core/src/shared-exports.ts +++ b/packages/core/src/shared-exports.ts @@ -323,6 +323,8 @@ export { isURLObjectRelative, getSanitizedUrlStringFromUrlObject, stripDataUrlContent, + getUrlQuery, + getUrlFragment, } from './utils/url'; export { eventFromMessage, diff --git a/packages/core/src/types/request.ts b/packages/core/src/types/request.ts index 028acbe9f77e..8cc6719a7e2d 100644 --- a/packages/core/src/types/request.ts +++ b/packages/core/src/types/request.ts @@ -1,3 +1,4 @@ +import type { HTTP_METHOD, URL_FRAGMENT, URL_QUERY } from '@sentry/conventions/attributes'; import type { WebFetchHeaders } from './webfetchapi'; /** @@ -21,10 +22,16 @@ export type QueryParams = string | { [key: string]: string } | Array<[string, st * See https://develop.sentry.dev/sdk/data-handling/#structuring-data */ export type SanitizedRequestData = { + /** + * The sanitized URL. Named `url` rather than `url.full` because this shape is also used for + * `http` breadcrumb data, where `url` is the field the Sentry UI renders (see + * {@link FetchBreadcrumbData}). Span attributes use `url.full` instead. + */ url: string; - 'http.method': string; - 'http.fragment'?: string; - 'http.query'?: string; + // oxlint-disable-next-line typescript/no-deprecated + [HTTP_METHOD]: string; + [URL_FRAGMENT]?: string; + [URL_QUERY]?: string; }; export interface RequestHookInfo { diff --git a/packages/core/src/utils/request.ts b/packages/core/src/utils/request.ts index 4dd709c17748..ff990390e9a5 100644 --- a/packages/core/src/utils/request.ts +++ b/packages/core/src/utils/request.ts @@ -10,6 +10,7 @@ import { defaultPiiToCollectionOptions } from './data-collection/defaultPiiToCol import { FILTERED_VALUE, SENSITIVE_COOKIE_NAME_SNIPPETS } from './data-collection/filtering-snippets'; import { filterKeyValueData } from './data-collection/filterKeyValueData'; import { safeUnref } from './timer'; +import { getUrlQuery } from './url'; /** * Maximum size of incoming HTTP request bodies attached to events. @@ -375,8 +376,7 @@ export function extractQueryParamsFromUrl(url: string): string | undefined { try { // The `URL` constructor can't handle internal URLs of the form `/some/path/here`, so stick a dummy protocol and // hostname as the base. Since the point here is just to grab the query string, it doesn't matter what we use. - const queryParams = new URL(url, 'http://s.io').search.slice(1); - return queryParams.length ? queryParams : undefined; + return getUrlQuery(new URL(url, 'http://s.io').search); } catch { return undefined; } diff --git a/packages/core/src/utils/url.ts b/packages/core/src/utils/url.ts index 82d85b5bdc1f..6f88f390b0f7 100644 --- a/packages/core/src/utils/url.ts +++ b/packages/core/src/utils/url.ts @@ -1,4 +1,15 @@ -import { URL_FULL } from '@sentry/conventions/attributes'; +import { + HTTP_ROUTE, + SERVER_ADDRESS, + URL_DOMAIN, + URL_FRAGMENT, + URL_FULL, + URL_PATH, + URL_PORT, + URL_QUERY, + URL_SCHEME, + URL_TEMPLATE, +} from '@sentry/conventions/attributes'; import { SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -115,6 +126,28 @@ export function getSanitizedUrlStringFromUrlObject(url: URLObject): string { return newUrl.toString(); } +/** + * Normalizes a query string for the `url.query` attribute, which is specced without the leading `?`. + * + * Accepts either a raw query string (`URL.search`, which includes the `?`) or an already-stripped one. + * Empty results become `undefined` so callers can assign the return value to an attribute + * unconditionally — setting an attribute to `undefined` is a no-op. + */ +export function getUrlQuery(query: string | undefined): string | undefined { + return query?.replace(/^\?/, '') || undefined; +} + +/** + * Normalizes a fragment for the `url.fragment` attribute, which is specced without the leading `#`. + * + * Accepts either a raw fragment (`URL.hash`, which includes the `#`) or an already-stripped one. + * Empty results become `undefined` so callers can assign the return value to an attribute + * unconditionally — setting an attribute to `undefined` is a no-op. + */ +export function getUrlFragment(fragment: string | undefined): string | undefined { + return fragment?.replace(/^#/, '') || undefined; +} + type PartialRequest = { method?: string; }; @@ -165,7 +198,7 @@ export function getHttpSpanDetailsFromUrlObject( if (routeName) { // This is based on https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name - attributes[kind === 'server' ? 'http.route' : 'url.template'] = routeName; + attributes[kind === 'server' ? HTTP_ROUTE : URL_TEMPLATE] = routeName; attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'route'; } @@ -174,29 +207,29 @@ export function getHttpSpanDetailsFromUrlObject( } if (urlObject) { - if (urlObject.search) { - attributes['url.query'] = urlObject.search; - } - if (urlObject.hash) { - attributes['url.fragment'] = urlObject.hash; - } + // Relative URLs have no meaningful `href`, so fall back to the sanitized path. + attributes[URL_FULL] = isURLObjectRelative(urlObject) + ? getSanitizedUrlStringFromUrlObject(urlObject) + : urlObject.href; + + attributes[URL_QUERY] = getUrlQuery(urlObject.search); + attributes[URL_FRAGMENT] = getUrlFragment(urlObject.hash); if (urlObject.pathname) { - attributes['url.path'] = urlObject.pathname; + attributes[URL_PATH] = urlObject.pathname; if (urlObject.pathname === '/') { attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'route'; } } if (!isURLObjectRelative(urlObject)) { - attributes[URL_FULL] = urlObject.href; if (urlObject.port) { - attributes['url.port'] = urlObject.port; + attributes[URL_PORT] = urlObject.port; } if (urlObject.protocol) { - attributes['url.scheme'] = urlObject.protocol; + attributes[URL_SCHEME] = urlObject.protocol; } if (urlObject.hostname) { - attributes[kind === 'server' ? 'server.address' : 'url.domain'] = urlObject.hostname; + attributes[kind === 'server' ? SERVER_ADDRESS : URL_DOMAIN] = urlObject.hostname; } } } diff --git a/packages/core/test/lib/fetch.test.ts b/packages/core/test/lib/fetch.test.ts index 5e949439c739..1ded8a41a2c4 100644 --- a/packages/core/test/lib/fetch.test.ts +++ b/packages/core/test/lib/fetch.test.ts @@ -488,16 +488,14 @@ describe('instrumentFetchRequest', () => { expect(startInactiveSpanSpy).toHaveBeenCalledWith({ name: 'GET https://api.example.com/users/42', attributes: { - url, type: 'fetch', 'http.method': 'GET', 'sentry.origin': 'auto.http.fetch', 'sentry.op': 'http.client', - 'http.url': url, [URL_FULL]: url, 'server.address': 'api.example.com', - 'http.query': '?include=profile', - 'http.fragment': '#bio', + 'url.query': 'include=profile', + 'url.fragment': 'bio', }, }); }); diff --git a/packages/core/test/lib/integrations/http/add-outgoing-request-breadcrumb.test.ts b/packages/core/test/lib/integrations/http/add-outgoing-request-breadcrumb.test.ts index 8ed6a1f3d660..44ed16eb8b73 100644 --- a/packages/core/test/lib/integrations/http/add-outgoing-request-breadcrumb.test.ts +++ b/packages/core/test/lib/integrations/http/add-outgoing-request-breadcrumb.test.ts @@ -76,12 +76,12 @@ describe('addOutgoingRequestBreadcrumb', () => { ); }); - it('includes http.query when the URL has a query string', () => { + it('includes url.query when the URL has a query string', () => { addOutgoingRequestBreadcrumb(makeMockRequest({ path: '/api/test?foo=bar' }), makeMockResponse()); expect(breadcrumbsModule.addBreadcrumb).toHaveBeenCalledWith( expect.objectContaining({ - data: expect.objectContaining({ 'http.query': '?foo=bar' }), + data: expect.objectContaining({ 'url.query': 'foo=bar' }), }), expect.anything(), ); @@ -90,18 +90,18 @@ describe('addOutgoingRequestBreadcrumb', () => { expect(callArg.data?.url).not.toContain('foo=bar'); }); - it('does not include http.query when the URL has no query string', () => { + it('does not include url.query when the URL has no query string', () => { addOutgoingRequestBreadcrumb(makeMockRequest(), makeMockResponse()); const callArg = vi.mocked(breadcrumbsModule.addBreadcrumb).mock.calls[0]![0]; - expect(callArg.data).not.toHaveProperty('http.query'); + expect(callArg.data?.['url.query']).toBeUndefined(); }); - it('does not include http.fragment by default', () => { + it('does not include url.fragment by default', () => { addOutgoingRequestBreadcrumb(makeMockRequest(), makeMockResponse()); const callArg = vi.mocked(breadcrumbsModule.addBreadcrumb).mock.calls[0]![0]; - expect(callArg.data).not.toHaveProperty('http.fragment'); + expect(callArg.data?.['url.fragment']).toBeUndefined(); }); it('sets level to "warning" for 4xx status codes', () => { diff --git a/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts b/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts index 2076c9cc9d15..90b3b1e06744 100644 --- a/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts +++ b/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts @@ -5,6 +5,7 @@ import { } from '../../../../src/integrations/http/get-outgoing-span-data'; import type { HttpClientRequest, HttpIncomingMessage } from '../../../../src/integrations/http/types'; import type { Span } from '../../../../src/types/span'; +import { HTTP_METHOD, HTTP_TARGET, NET_PEER_NAME, URL_FULL } from '@sentry/conventions/attributes'; function makeMockRequest(overrides: Partial> = {}): HttpClientRequest { return { @@ -64,13 +65,13 @@ describe('getOutgoingRequestSpanData', () => { expect(result.name).toMatch(/^POST /); }); - it('includes http.url, http.method, http.target, net.peer.name', () => { + it('includes URL_FULL, HTTP_METHOD, HTTP_TARGET, NET_PEER_NAME', () => { const result = getOutgoingRequestSpanData(makeMockRequest()); expect(result.attributes).toMatchObject({ - 'http.url': 'http://example.com/api/test', - 'http.method': 'GET', - 'http.target': '/api/test', - 'net.peer.name': 'example.com', + [URL_FULL]: 'http://example.com/api/test', + [HTTP_METHOD]: 'GET', + [HTTP_TARGET]: '/api/test', + [NET_PEER_NAME]: 'example.com', }); }); @@ -89,12 +90,12 @@ describe('getOutgoingRequestSpanData', () => { it('omits user_agent.original when user-agent header is absent', () => { const result = getOutgoingRequestSpanData(makeMockRequest()); - expect(result.attributes).not.toHaveProperty('user_agent.original'); + expect(result.attributes!['user_agent.original']).toBeUndefined(); }); it('includes non-standard port in the URL', () => { const result = getOutgoingRequestSpanData(makeMockRequest({ port: 3000 })); - expect(result.attributes!['http.url']).toContain(':3000'); + expect(result.attributes![URL_FULL]).toContain(':3000'); }); }); diff --git a/packages/core/test/lib/tracing/spans/estimateSize.test.ts b/packages/core/test/lib/tracing/spans/estimateSize.test.ts index 131f89188a62..eee7bfb0e819 100644 --- a/packages/core/test/lib/tracing/spans/estimateSize.test.ts +++ b/packages/core/test/lib/tracing/spans/estimateSize.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import { estimateSerializedSpanSizeInBytes } from '../../../../src/tracing/spans/estimateSize'; import type { SerializedStreamedSpan } from '../../../../src/types/span'; +import { HTTP_METHOD, URL_FULL } from '@sentry/conventions/attributes'; // Produces a realistic trace_id (32 hex chars) and span_id (16 hex chars) const TRACE_ID = 'a1b2c3d4e5f607189a0b1c2d3e4f5060'; @@ -62,8 +63,8 @@ describe('estimateSerializedSpanSizeInBytes', () => { status: 'ok', is_segment: false, attributes: { - 'http.method': { type: 'string', value: 'GET' }, - 'http.url': { type: 'string', value: 'https://example.com/api/users?page=1&limit=100' }, + [HTTP_METHOD]: { type: 'string', value: 'GET' }, + [URL_FULL]: { type: 'string', value: 'https://example.com/api/users?page=1&limit=100' }, 'http.status_code': { type: 'integer', value: 200 }, 'db.statement': { type: 'string', value: 'SELECT * FROM users WHERE id = $1' }, 'sentry.origin': { type: 'string', value: 'auto.http.fetch' }, diff --git a/packages/core/test/lib/tracing/spans/spanBuffer.test.ts b/packages/core/test/lib/tracing/spans/spanBuffer.test.ts index 07714a46a441..224ab4504dd2 100644 --- a/packages/core/test/lib/tracing/spans/spanBuffer.test.ts +++ b/packages/core/test/lib/tracing/spans/spanBuffer.test.ts @@ -3,6 +3,7 @@ import type { Client, StreamedSpanEnvelope } from '../../../../src'; import { SentrySpan, setCurrentClient, SpanBuffer } from '../../../../src'; import type { SerializedStreamedSpanWithSegmentSpan } from '../../../../src/tracing/spans/captureSpan'; import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client'; +import { HTTP_METHOD, URL_FULL } from '@sentry/conventions/attributes'; describe('SpanBuffer', () => { let client: TestClient; @@ -359,8 +360,8 @@ describe('SpanBuffer', () => { buffer.add( makeSpan('trace1', 'span1', segmentSpan, { attributes: { - 'http.method': { type: 'string', value: 'GET' }, - 'http.url': { type: 'string', value: 'https://example.com/api/v1/users?page=1&limit=100' }, + [HTTP_METHOD]: { type: 'string', value: 'GET' }, + [URL_FULL]: { type: 'string', value: 'https://example.com/api/v1/users?page=1&limit=100' }, 'db.statement': { type: 'string', value: 'SELECT * FROM users WHERE id = 1' }, }, }), diff --git a/packages/core/test/lib/utils/url.test.ts b/packages/core/test/lib/utils/url.test.ts index 7bdfcfd63804..9f42966b5625 100644 --- a/packages/core/test/lib/utils/url.test.ts +++ b/packages/core/test/lib/utils/url.test.ts @@ -3,6 +3,8 @@ import { getHttpSpanDetailsFromUrlObject, getSanitizedUrlString, getSanitizedUrlStringFromUrlObject, + getUrlFragment, + getUrlQuery, isURLObjectRelative, parseStringToURLObject, parseUrl, @@ -292,6 +294,33 @@ describe('parseStringToURLObject', () => { }); }); +describe('getUrlQuery', () => { + it.each([ + ['?foo=bar', 'foo=bar'], + ['foo=bar', 'foo=bar'], + ['?foo=bar&baz=qux', 'foo=bar&baz=qux'], + ['?a=?b', 'a=?b'], + ['?', undefined], + ['', undefined], + [undefined, undefined], + ])('strips the leading ? from %s', (input, expected) => { + expect(getUrlQuery(input)).toBe(expected); + }); +}); + +describe('getUrlFragment', () => { + it.each([ + ['#section', 'section'], + ['section', 'section'], + ['##double', '#double'], + ['#', undefined], + ['', undefined], + [undefined, undefined], + ])('strips the leading # from %s', (input, expected) => { + expect(getUrlFragment(input)).toBe(expected); + }); +}); + describe('isURLObjectRelative', () => { it('returns true for relative URLs', () => { expect(isURLObjectRelative(parseStringToURLObject('/path/to/happiness')!)).toBe(true); @@ -415,6 +444,7 @@ describe('getHttpSpanDetailsFromUrlObject', () => { 'sentry.origin': 'test-origin', 'sentry.source': 'url', 'url.path': '/api/users', + 'url.full': '/api/users', }); }); @@ -426,8 +456,8 @@ describe('getHttpSpanDetailsFromUrlObject', () => { 'sentry.origin': 'test-origin', 'sentry.source': 'url', 'url.path': '/api/users', - 'url.query': '?q=test', - 'url.fragment': '#section', + 'url.query': 'q=test', + 'url.fragment': 'section', 'url.full': 'https://example.com/api/users?q=test#section', 'server.address': 'example.com', 'url.scheme': 'https:', @@ -551,7 +581,7 @@ describe('getHttpSpanDetailsFromUrlObject', () => { 'sentry.origin': 'test-origin', 'sentry.source': 'route', 'url.path': '/api/search', - 'url.query': '?q=test&page=1', + 'url.query': 'q=test&page=1', 'url.full': 'https://example.com/api/search?q=test&page=1', 'server.address': 'example.com', 'url.scheme': 'https:', @@ -573,7 +603,7 @@ describe('getHttpSpanDetailsFromUrlObject', () => { 'sentry.origin': 'test-origin', 'sentry.source': 'route', 'url.path': '/api/docs', - 'url.fragment': '#section-1', + 'url.fragment': 'section-1', 'url.full': 'https://example.com/api/docs#section-1', 'server.address': 'example.com', 'url.scheme': 'https:', diff --git a/packages/nestjs/src/integrations/wrap-route.ts b/packages/nestjs/src/integrations/wrap-route.ts index c910e658fcf4..7d31f539dd3a 100644 --- a/packages/nestjs/src/integrations/wrap-route.ts +++ b/packages/nestjs/src/integrations/wrap-route.ts @@ -1,4 +1,4 @@ -import { HTTP_ROUTE } from '@sentry/conventions/attributes'; +import { HTTP_METHOD, HTTP_ROUTE, 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'; @@ -95,8 +95,9 @@ export function wrapRequestContextHandler( [AttributeNames.CALLBACK]: callbackName, [AttributeNames.VERSION]: moduleVersion || undefined, [HTTP_ROUTE]: httpRoute || undefined, - ['http.method']: req.method || undefined, - ['http.url']: req.originalUrl || req.url || undefined, + // oxlint-disable-next-line typescript/no-deprecated + [HTTP_METHOD]: req.method || undefined, + [URL_FULL]: req.originalUrl || req.url || undefined, }; return startSpan({ name: spanName, op: `${NestType.REQUEST_CONTEXT}.nestjs`, attributes }, () => handler.apply(this, handlerArgs), diff --git a/packages/nestjs/test/orchestrion/nestjs.test.ts b/packages/nestjs/test/orchestrion/nestjs.test.ts index d8238107c278..1e80c7f9854c 100644 --- a/packages/nestjs/test/orchestrion/nestjs.test.ts +++ b/packages/nestjs/test/orchestrion/nestjs.test.ts @@ -261,7 +261,7 @@ describe('NestJS orchestrion subscriber: request_context / request_handler', () 'nestjs.version': '10.4.1', 'http.route': '/cats', 'http.method': 'GET', - 'http.url': '/cats?q=1', + 'url.full': '/cats?q=1', }); }); diff --git a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts index c238e13efdf4..7e7d221b9bba 100644 --- a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts +++ b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts @@ -3,6 +3,7 @@ import { debug, GLOBAL_OBJ, parseSemver, suppressTracing } from '@sentry/core'; import type { StackFrame } from 'stacktrace-parser'; import * as stackTraceParser from 'stacktrace-parser'; import { DEBUG_BUILD } from './debug-build'; +import { URL_FULL } from '@sentry/conventions/attributes'; type OriginalStackFrameResponse = { originalStackFrame: StackFrame; @@ -61,7 +62,7 @@ export async function devErrorSymbolicationEventProcessor(event: Event, hint: Ev // Filter out spans for requests resolving source maps for stack frames in dev mode if (event.type === 'transaction') { event.spans = event.spans?.filter(span => { - const httpUrlAttribute: unknown = span.data?.['http.url']; + const httpUrlAttribute: unknown = span.data?.[URL_FULL]; if (typeof httpUrlAttribute === 'string') { return !httpUrlAttribute.includes('__nextjs_original-stack-frame'); // could also be __nextjs_original-stack-frames (plural) } diff --git a/packages/nextjs/src/common/utils/dropMiddlewareTunnelRequests.ts b/packages/nextjs/src/common/utils/dropMiddlewareTunnelRequests.ts index 7263efb2030b..323b55137403 100644 --- a/packages/nextjs/src/common/utils/dropMiddlewareTunnelRequests.ts +++ b/packages/nextjs/src/common/utils/dropMiddlewareTunnelRequests.ts @@ -1,4 +1,4 @@ -import { HTTP_TARGET, HTTP_URL, URL_FULL } from '@sentry/conventions/attributes'; +import { HTTP_TARGET, URL_FULL } from '@sentry/conventions/attributes'; import { getClient, GLOBAL_OBJ, @@ -51,9 +51,7 @@ export function dropMiddlewareTunnelRequests(span: Span, attrs: SpanAttributes | } function isSentryRequestSpan(attrs: SpanAttributes): boolean { - // `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now. - // eslint-disable-next-line typescript/no-deprecated - const httpUrl = attrs[HTTP_URL] || attrs[URL_FULL]; + const httpUrl = attrs[URL_FULL]; if (!httpUrl) { return false; diff --git a/packages/nextjs/src/common/utils/getNormalizedRequestFromAttributes.ts b/packages/nextjs/src/common/utils/getNormalizedRequestFromAttributes.ts index 0f7d62d26422..433ce026ade5 100644 --- a/packages/nextjs/src/common/utils/getNormalizedRequestFromAttributes.ts +++ b/packages/nextjs/src/common/utils/getNormalizedRequestFromAttributes.ts @@ -2,7 +2,6 @@ import { HTTP_METHOD, HTTP_REQUEST_METHOD, HTTP_TARGET, - HTTP_URL, URL_FULL, URL_PATH, URL_QUERY, @@ -18,7 +17,7 @@ export function getNormalizedRequestFromAttributes(attributes: SpanAttributes): const method = attributes[HTTP_REQUEST_METHOD] || attributes[HTTP_METHOD]; // eslint-disable-next-line typescript/no-deprecated - const url = attributes[URL_FULL] || attributes[HTTP_URL] || attributes[URL_PATH] || attributes[HTTP_TARGET]; + const url = attributes[URL_FULL] || attributes[URL_PATH] || attributes[HTTP_TARGET]; if (typeof method !== 'string' && typeof url !== 'string') { return undefined; diff --git a/packages/nextjs/test/common/devErrorSymbolicationEventProcessor.test.ts b/packages/nextjs/test/common/devErrorSymbolicationEventProcessor.test.ts index 130f8ea685df..ecb4fdd0408d 100644 --- a/packages/nextjs/test/common/devErrorSymbolicationEventProcessor.test.ts +++ b/packages/nextjs/test/common/devErrorSymbolicationEventProcessor.test.ts @@ -2,6 +2,7 @@ import type { Event, EventHint, SpanJSON } from '@sentry/core'; import { GLOBAL_OBJ } from '@sentry/core'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { devErrorSymbolicationEventProcessor } from '../../src/common/devErrorSymbolicationEventProcessor'; +import { URL_FULL } from '@sentry/conventions/attributes'; vi.mock('@sentry/core', async () => { const actual = await vi.importActual('@sentry/core'); @@ -190,17 +191,17 @@ describe('devErrorSymbolicationEventProcessor', () => { spans: [ { data: { - 'http.url': 'http://localhost:3000/__nextjs_original-stack-frame?file=test.js', + [URL_FULL]: 'http://localhost:3000/__nextjs_original-stack-frame?file=test.js', }, }, { data: { - 'http.url': 'http://localhost:3000/__nextjs_original-stack-frames', + [URL_FULL]: 'http://localhost:3000/__nextjs_original-stack-frames', }, }, { data: { - 'http.url': 'http://localhost:3000/api/users', + [URL_FULL]: 'http://localhost:3000/api/users', }, }, { @@ -216,11 +217,11 @@ describe('devErrorSymbolicationEventProcessor', () => { const result = await devErrorSymbolicationEventProcessor(mockEvent, mockHint); expect(result?.spans).toHaveLength(2); - expect(result?.spans?.[0]?.data?.['http.url']).toBe('http://localhost:3000/api/users'); + expect(result?.spans?.[0]?.data?.[URL_FULL]).toBe('http://localhost:3000/api/users'); expect(result?.spans?.[1]?.data?.['other.attribute']).toBe('value'); }); - it('should preserve spans without http.url attribute', async () => { + it('should preserve spans without url.full attribute', async () => { const mockEvent: Event = { type: 'transaction', spans: [ @@ -240,13 +241,13 @@ describe('devErrorSymbolicationEventProcessor', () => { expect(result?.spans?.[0]?.data?.['other.attribute']).toBe('value'); }); - it('should handle spans with non-string http.url attribute', async () => { + it('should handle spans with non-string url.full attribute', async () => { const mockEvent: Event = { type: 'transaction', spans: [ { data: { - 'http.url': 123, // non-string + [URL_FULL]: 123, // non-string }, }, ] as unknown as SpanJSON[], diff --git a/packages/nextjs/test/common/utils/getNormalizedRequestFromAttributes.test.ts b/packages/nextjs/test/common/utils/getNormalizedRequestFromAttributes.test.ts index 68038f02b20b..9e09e0f007d6 100644 --- a/packages/nextjs/test/common/utils/getNormalizedRequestFromAttributes.test.ts +++ b/packages/nextjs/test/common/utils/getNormalizedRequestFromAttributes.test.ts @@ -72,7 +72,7 @@ describe('getNormalizedRequestFromAttributes', () => { expect(normalizedRequest).toEqual({ url: '/foo?a=1', query_string: 'a=1' }); }); - it('falls back to `url.path` when `url.full` and `http.url` are absent', () => { + it('falls back to `url.path` when `url.full` and `http.target` are absent', () => { const normalizedRequest = getNormalizedRequestFromAttributes({ 'http.request.method': 'GET', 'url.path': '/api/resource', diff --git a/packages/node/src/integrations/http/httpServerSpansIntegration.ts b/packages/node/src/integrations/http/httpServerSpansIntegration.ts index ce716190d78a..74dc7d57eb97 100644 --- a/packages/node/src/integrations/http/httpServerSpansIntegration.ts +++ b/packages/node/src/integrations/http/httpServerSpansIntegration.ts @@ -14,7 +14,6 @@ import { HTTP_SCHEME, HTTP_STATUS_CODE, HTTP_TARGET, - HTTP_URL, HTTP_USER_AGENT, NET_HOST_IP, NET_HOST_NAME, @@ -23,8 +22,10 @@ import { NET_PEER_PORT, NET_TRANSPORT, SENTRY_HTTP_PREFETCH, + URL_FRAGMENT, URL_FULL, URL_PATH, + URL_QUERY, SENTRY_KIND, } from '@sentry/conventions/attributes'; import type { @@ -52,6 +53,8 @@ import { bindScopeToEmitter, startInactiveSpan, withActiveSpan, + getUrlFragment, + getUrlQuery, } from '@sentry/core'; import { DEBUG_BUILD } from '../../debug-build'; import type { NodeClient } from '../../sdk/client'; @@ -166,6 +169,9 @@ const _httpServerSpansIntegration = ((options: HttpServerSpansIntegrationOptions const httpTargetWithoutQueryFragment = urlObj ? urlObj.pathname : stripUrlQueryAndFragment(fullUrl); const bestEffortTransactionName = `${method} ${httpTargetWithoutQueryFragment}`; + const query = getUrlQuery(urlObj?.search); + const fragment = getUrlFragment(urlObj?.hash); + const span = startInactiveSpan({ name: bestEffortTransactionName, attributes: { @@ -176,9 +182,10 @@ const _httpServerSpansIntegration = ((options: HttpServerSpansIntegrationOptions [SENTRY_HTTP_PREFETCH]: isKnownPrefetchRequest(request) || undefined, [URL_FULL]: fullUrl, [URL_PATH]: urlObj?.pathname ?? httpTargetWithoutQueryFragment, + [URL_QUERY]: query, + [URL_FRAGMENT]: fragment, // Old Semantic Conventions attributes - added for compatibility with what `@opentelemetry/instrumentation-http` output before /* eslint-disable typescript/no-deprecated */ - [HTTP_URL]: fullUrl, [HTTP_METHOD]: normalizedRequest.method, [HTTP_TARGET]: urlObj ? `${urlObj.pathname}${urlObj.search}` : httpTargetWithoutQueryFragment, [HTTP_HOST]: host, diff --git a/packages/node/src/integrations/http/index.ts b/packages/node/src/integrations/http/index.ts index 36f0d02c66ec..bec41e95a729 100644 --- a/packages/node/src/integrations/http/index.ts +++ b/packages/node/src/integrations/http/index.ts @@ -202,9 +202,6 @@ export const httpIntegration = defineIntegration((options: HttpOptions = {}) => const url = getRequestUrlFromClientRequest(request); if (url.startsWith('data:')) { const sanitizedUrl = stripDataUrlContent(url); - // TODO(v11): Update these to the Sentry semantic attributes. - // https://getsentry.github.io/sentry-conventions/attributes/ - span.setAttribute('http.url', sanitizedUrl); span.setAttribute(URL_FULL, sanitizedUrl); span.updateName(`${request.method || 'GET'} ${sanitizedUrl}`); } diff --git a/packages/node/src/integrations/node-fetch/undici-instrumentation.ts b/packages/node/src/integrations/node-fetch/undici-instrumentation.ts index 139ca29aa465..f7ddd06b0888 100644 --- a/packages/node/src/integrations/node-fetch/undici-instrumentation.ts +++ b/packages/node/src/integrations/node-fetch/undici-instrumentation.ts @@ -32,6 +32,8 @@ import { SPAN_STATUS_ERROR, startInactiveSpan, stripDataUrlContent, + getUrlFragment, + getUrlQuery, } from '@sentry/core'; import { addFetchRequestBreadcrumb, addTracePropagationHeadersToFetchRequest } from '../../utils/outgoingFetchRequest'; import { @@ -42,6 +44,7 @@ import { SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, + URL_FRAGMENT, URL_FULL, URL_PATH, URL_QUERY, @@ -203,6 +206,7 @@ function onRequestCreated(config: NodeFetchOptions, { request }: RequestMessage) // Skip instrumenting this request. return; } + const urlScheme = requestUrl.protocol.replace(':', ''); const requestMethod = getRequestMethod(request.method); const attributes: SpanAttributes = { @@ -211,7 +215,8 @@ function onRequestCreated(config: NodeFetchOptions, { request }: RequestMessage) [ATTR_HTTP_REQUEST_METHOD_ORIGINAL]: request.method, [URL_FULL]: requestUrl.toString(), [URL_PATH]: requestUrl.pathname, - [URL_QUERY]: requestUrl.search, + [URL_QUERY]: getUrlQuery(requestUrl.search), + [URL_FRAGMENT]: getUrlFragment(requestUrl.hash), [URL_SCHEME]: urlScheme, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.node_fetch', }; @@ -219,7 +224,6 @@ function onRequestCreated(config: NodeFetchOptions, { request }: RequestMessage) // Sanitize data URLs to prevent long base64 strings in span attributes if (url.startsWith('data:')) { const sanitizedUrl = stripDataUrlContent(url); - attributes['http.url'] = sanitizedUrl; attributes[URL_FULL] = sanitizedUrl; attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME] = `${request.method || 'GET'} ${sanitizedUrl}`; } diff --git a/packages/node/src/utils/outgoingFetchRequest.ts b/packages/node/src/utils/outgoingFetchRequest.ts index a94779633f43..cb2655294929 100644 --- a/packages/node/src/utils/outgoingFetchRequest.ts +++ b/packages/node/src/utils/outgoingFetchRequest.ts @@ -1,3 +1,4 @@ +import { HTTP_METHOD, URL_FRAGMENT, URL_QUERY } from '@sentry/conventions/attributes'; import type { LRUMap, SanitizedRequestData, Span } from '@sentry/core'; import { addBreadcrumb, @@ -6,6 +7,8 @@ import { getClient, getSanitizedUrlString, getTraceData, + getUrlFragment, + getUrlQuery, parseUrl, shouldPropagateTraceForUrl, mergeBaggageHeaders, @@ -252,19 +255,13 @@ function getBreadcrumbData(request: UndiciRequest): Partial = { + return { url: getSanitizedUrlString(parsedUrl), - 'http.method': request.method || 'GET', + // eslint-disable-next-line typescript/no-deprecated + [HTTP_METHOD]: request.method || 'GET', + [URL_QUERY]: getUrlQuery(parsedUrl.search), + [URL_FRAGMENT]: getUrlFragment(parsedUrl.hash), }; - - if (parsedUrl.search) { - data['http.query'] = parsedUrl.search; - } - if (parsedUrl.hash) { - data['http.fragment'] = parsedUrl.hash; - } - - return data; } catch { return {}; } diff --git a/packages/opentelemetry/src/asyncLocalStorageContextManager.ts b/packages/opentelemetry/src/asyncLocalStorageContextManager.ts index 13c32e62d0ac..822ef51c8187 100644 --- a/packages/opentelemetry/src/asyncLocalStorageContextManager.ts +++ b/packages/opentelemetry/src/asyncLocalStorageContextManager.ts @@ -77,7 +77,11 @@ export class SentryAsyncLocalStorageContextManager implements ContextManager { } public disable(): this { - this._asyncLocalStorage.disable(); + try { + this._asyncLocalStorage.disable(); + } catch { + // we don't care if something goes wrong here + } return this; } diff --git a/packages/opentelemetry/src/propagator.ts b/packages/opentelemetry/src/propagator.ts index 18fc78177ca6..d76418a36ac3 100644 --- a/packages/opentelemetry/src/propagator.ts +++ b/packages/opentelemetry/src/propagator.ts @@ -1,7 +1,7 @@ import type { Baggage, Context, Span, SpanContext, TextMapGetter, TextMapSetter } from '@opentelemetry/api'; import { context, INVALID_TRACEID, propagation, trace, TraceFlags } from '@opentelemetry/api'; import { isTracingSuppressed, W3CBaggagePropagator } from '@opentelemetry/core'; -import { HTTP_URL, URL_FULL } from '@sentry/conventions/attributes'; +import { URL_FULL } from '@sentry/conventions/attributes'; import type { Client, continueTrace, DynamicSamplingContext, Scope } from '@sentry/core'; import { baggageHeaderToDynamicSamplingContext, @@ -270,9 +270,7 @@ function getExistingSentryTrace(carrier: unknown): string | string[] | undefined */ function getCurrentURL(span: Span): string | undefined { const spanData = spanToJSON(span).data; - // `URL_FULL` is the new attribute, but we still support the old one, `HTTP_URL`, for now. - // eslint-disable-next-line typescript/no-deprecated - const urlAttribute = spanData[HTTP_URL] || spanData[URL_FULL]; + const urlAttribute = spanData[URL_FULL]; if (typeof urlAttribute === 'string') { return urlAttribute; } diff --git a/packages/opentelemetry/src/utils/parseSpanDescription.ts b/packages/opentelemetry/src/utils/parseSpanDescription.ts index f47a0ab5b618..3d26c1075a2b 100644 --- a/packages/opentelemetry/src/utils/parseSpanDescription.ts +++ b/packages/opentelemetry/src/utils/parseSpanDescription.ts @@ -8,16 +8,19 @@ import { HTTP_REQUEST_METHOD, HTTP_ROUTE, HTTP_TARGET, - HTTP_URL, MESSAGING_SYSTEM, RPC_SERVICE, SENTRY_GRAPHQL_OPERATION, SENTRY_KIND, + URL_FRAGMENT, URL_FULL, + URL_QUERY, } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes, TransactionSource } from '@sentry/core'; import { getSanitizedUrlString, + getUrlFragment, + getUrlQuery, parseUrl, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -179,17 +182,15 @@ export function descriptionForHttpMethod( const data: Record = {}; if (url) { - data.url = url; + data[URL_FULL] = url; } - if (query) { - // Strip the leading `?`/`#` (the `URL.search`/`URL.hash` prefix) so the attribute matches the - // canonical format the OTel SDK exporter emits (`getData` in `spanExporter.ts` slices these too). - // TODO(v11): emit `url.query`/`url.fragment` (OTel-standard, no leading `?`/`#`) and drop - // this stripping + `http.query`/`http.fragment`; `http.query` is specced to keep the leading `?`. - data['http.query'] = query.slice(1); + const urlQuery = getUrlQuery(query); + if (urlQuery) { + data[URL_QUERY] = urlQuery; } - if (fragment) { - data['http.fragment'] = fragment.slice(1); + const urlFragment = getUrlFragment(fragment); + if (urlFragment) { + data[URL_FRAGMENT] = urlFragment; } // If the span kind is neither client nor server, we use the original name @@ -252,8 +253,7 @@ export function getSanitizedUrl(attributes: Attributes): { // eslint-disable-next-line typescript/no-deprecated const httpTarget = attributes[HTTP_TARGET]; // This is the full URL, including host & query params etc., e.g. https://example.com/sub?foo=bar - // eslint-disable-next-line typescript/no-deprecated - const httpUrl = attributes[HTTP_URL] || attributes[URL_FULL]; + const httpUrl = attributes[URL_FULL]; // This is the normalized route name - may not always be available! const httpRoute = attributes[HTTP_ROUTE]; diff --git a/packages/opentelemetry/test/tracerProvider.test.ts b/packages/opentelemetry/test/tracerProvider.test.ts index 27e074bbd85a..672bd05fe807 100644 --- a/packages/opentelemetry/test/tracerProvider.test.ts +++ b/packages/opentelemetry/test/tracerProvider.test.ts @@ -19,6 +19,7 @@ import { applyOtelSpanData } from '../src/applyOtelSpanData'; import { SentryTracerProvider } from '../src/tracerProvider'; import { cleanupOtel } from './helpers/mockSdkInit'; import { init as initTestClient } from './helpers/TestClient'; +import { URL_FULL } from '@sentry/conventions/attributes'; describe('SentryTracerProvider', () => { beforeEach(() => { @@ -228,7 +229,7 @@ describe('SentryTracerProvider', () => { kind: SpanKind.SERVER, attributes: { 'http.method': 'POST', - 'http.url': 'https://www.example.com/my-path', + [URL_FULL]: 'https://www.example.com/my-path', 'http.target': '/my-path', }, }); diff --git a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts index 46229b90ed9a..4334c4727367 100644 --- a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts +++ b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts @@ -9,10 +9,10 @@ import { HTTP_ROUTE, HTTP_STATUS_CODE, HTTP_TARGET, - HTTP_URL, MESSAGING_SYSTEM, RPC_SERVICE, SENTRY_KIND, + URL_FULL, } from '@sentry/conventions/attributes'; import { SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { describe, expect, it } from 'vitest'; @@ -360,7 +360,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path', + [URL_FULL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', [SENTRY_KIND]: 'client' as const, }, @@ -369,7 +369,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'GET https://www.example.com/my-path', data: { - url: 'https://www.example.com/my-path', + 'url.full': 'https://www.example.com/my-path', }, source: 'url', }, @@ -379,7 +379,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path', + [URL_FULL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', 'sentry.http.prefetch': true, [SENTRY_KIND]: 'client' as const, @@ -389,7 +389,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.client.prefetch', description: 'GET https://www.example.com/my-path', data: { - url: 'https://www.example.com/my-path', + 'url.full': 'https://www.example.com/my-path', }, source: 'url', }, @@ -399,7 +399,7 @@ describe('descriptionForHttpMethod', () => { 'POST', { [HTTP_METHOD]: 'POST', - [HTTP_URL]: 'https://www.example.com/my-path', + [URL_FULL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', [SENTRY_KIND]: 'server' as const, }, @@ -408,7 +408,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.server', description: 'POST /my-path', data: { - url: 'https://www.example.com/my-path', + 'url.full': 'https://www.example.com/my-path', }, source: 'url', }, @@ -418,7 +418,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path/123', + [URL_FULL]: 'https://www.example.com/my-path/123', [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', [SENTRY_KIND]: 'client' as const, @@ -428,7 +428,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'GET /my-path/:id', data: { - url: 'https://www.example.com/my-path/123', + 'url.full': 'https://www.example.com/my-path/123', }, source: 'route', }, @@ -438,7 +438,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path', + [URL_FULL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', }, 'test name', @@ -446,7 +446,7 @@ describe('descriptionForHttpMethod', () => { op: 'http', description: 'test name', data: { - url: 'https://www.example.com/my-path', + 'url.full': 'https://www.example.com/my-path', }, source: 'custom', }, @@ -456,7 +456,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path/123', + [URL_FULL]: 'https://www.example.com/my-path/123', [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', @@ -467,7 +467,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'test name', data: { - url: 'https://www.example.com/my-path/123', + 'url.full': 'https://www.example.com/my-path/123', }, source: 'custom', }, @@ -477,7 +477,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path/123', + [URL_FULL]: 'https://www.example.com/my-path/123', [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', @@ -489,7 +489,7 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'custom name', data: { - url: 'https://www.example.com/my-path/123', + 'url.full': 'https://www.example.com/my-path/123', }, source: 'custom', }, @@ -499,7 +499,7 @@ describe('descriptionForHttpMethod', () => { 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path/123', + [URL_FULL]: 'https://www.example.com/my-path/123', [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', @@ -511,17 +511,17 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'custom name', data: { - url: 'https://www.example.com/my-path/123', + 'url.full': 'https://www.example.com/my-path/123', }, source: 'component', }, ], [ - 'strips the leading `?`/`#` from http.query and http.fragment', + 'strips the leading `?`/`#` for url.query and url.fragment', 'GET', { [HTTP_METHOD]: 'GET', - [HTTP_URL]: 'https://www.example.com/my-path?id=1#section', + [URL_FULL]: 'https://www.example.com/my-path?id=1#section', [HTTP_TARGET]: '/my-path?id=1#section', [SENTRY_KIND]: 'client' as const, }, @@ -530,9 +530,9 @@ describe('descriptionForHttpMethod', () => { op: 'http.client', description: 'GET https://www.example.com/my-path', data: { - url: 'https://www.example.com/my-path', - 'http.query': 'id=1', - 'http.fragment': 'section', + 'url.full': 'https://www.example.com/my-path', + 'url.query': 'id=1', + 'url.fragment': 'section', }, source: 'url', }, @@ -559,7 +559,7 @@ describe('getSanitizedUrl', () => { [ 'uses url without query for client request', { - [HTTP_URL]: 'http://example.com/?what=true', + [URL_FULL]: 'http://example.com/?what=true', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/?what=true', [HTTP_HOST]: 'example.com:80', @@ -577,7 +577,7 @@ describe('getSanitizedUrl', () => { [ 'uses url without hash for client request', { - [HTTP_URL]: 'http://example.com/sub#hash', + [URL_FULL]: 'http://example.com/sub#hash', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/sub#hash', [HTTP_HOST]: 'example.com:80', @@ -595,7 +595,7 @@ describe('getSanitizedUrl', () => { [ 'uses route if available for client request', { - [HTTP_URL]: 'http://example.com/?what=true', + [URL_FULL]: 'http://example.com/?what=true', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/?what=true', [HTTP_ROUTE]: '/my-route', @@ -631,7 +631,7 @@ describe('getSanitizedUrl', () => { [ 'uses target without query for server request', { - [HTTP_URL]: 'http://example.com/?what=true', + [URL_FULL]: 'http://example.com/?what=true', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/?what=true', [HTTP_HOST]: 'example.com:80', @@ -649,7 +649,7 @@ describe('getSanitizedUrl', () => { [ 'uses target without hash for server request', { - [HTTP_URL]: 'http://example.com/?what=true', + [URL_FULL]: 'http://example.com/?what=true', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/sub#hash', [HTTP_HOST]: 'example.com:80', @@ -667,7 +667,7 @@ describe('getSanitizedUrl', () => { [ 'uses route for server request if available', { - [HTTP_URL]: 'http://example.com/?what=true', + [URL_FULL]: 'http://example.com/?what=true', [HTTP_METHOD]: 'GET', [HTTP_TARGET]: '/?what=true', [HTTP_ROUTE]: '/my-route', diff --git a/packages/react-router/src/client/createClientInstrumentation.ts b/packages/react-router/src/client/createClientInstrumentation.ts index 9ad9421609a4..68244445eb35 100644 --- a/packages/react-router/src/client/createClientInstrumentation.ts +++ b/packages/react-router/src/client/createClientInstrumentation.ts @@ -24,7 +24,7 @@ import { finalizeNavigationSpanFromHydratedRouter, updateNavigationSpanUrlFromLocation, } from './utils'; -import { URL_TEMPLATE } from '@sentry/conventions/attributes'; +import { URL_FULL, URL_TEMPLATE } from '@sentry/conventions/attributes'; const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; @@ -127,7 +127,7 @@ export function createSentryClientInstrumentation( const result = await callNavigate(); if (result.status === 'error' && result.error instanceof Error) { captureInstrumentationError(result, captureErrors, 'react_router.navigate', { - 'http.url': info.currentUrl, + [URL_FULL]: info.currentUrl, }); } return; @@ -174,7 +174,7 @@ export function createSentryClientInstrumentation( navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); } captureInstrumentationError(result, captureErrors, 'react_router.navigate', { - 'http.url': WINDOW.location?.pathname || info.currentUrl, + [URL_FULL]: WINDOW.location?.pathname || info.currentUrl, }); } } finally { @@ -210,7 +210,7 @@ export function createSentryClientInstrumentation( navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); } captureInstrumentationError(result, captureErrors, 'react_router.navigate', { - 'http.url': toPath, + [URL_FULL]: toPath, }); } return; @@ -230,7 +230,7 @@ export function createSentryClientInstrumentation( if (result.status === 'error' && result.error instanceof Error) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.fetcher', { - 'http.url': info.href, + [URL_FULL]: info.href, }); } }, @@ -264,7 +264,7 @@ export function createSentryClientInstrumentation( if (result.status === 'error' && result.error instanceof Error) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.client_loader', { - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, @@ -290,7 +290,7 @@ export function createSentryClientInstrumentation( if (result.status === 'error' && result.error instanceof Error) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.client_action', { - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, @@ -326,7 +326,7 @@ export function createSentryClientInstrumentation( if (result.status === 'error' && result.error instanceof Error) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', { - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, diff --git a/packages/react-router/src/server/createServerInstrumentation.ts b/packages/react-router/src/server/createServerInstrumentation.ts index be826c3d7f5d..98d8c98ee46f 100644 --- a/packages/react-router/src/server/createServerInstrumentation.ts +++ b/packages/react-router/src/server/createServerInstrumentation.ts @@ -75,7 +75,7 @@ export function createSentryServerInstrumentation( existingRootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.request_handler', { 'http.method': info.request.method, - 'http.url': pathname, + [URL_FULL]: pathname, }); } } finally { @@ -102,7 +102,7 @@ export function createSentryServerInstrumentation( span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.request_handler', { 'http.method': info.request.method, - 'http.url': pathname, + [URL_FULL]: pathname, }); } } finally { @@ -142,7 +142,7 @@ export function createSentryServerInstrumentation( span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.loader', { 'http.method': info.request.method, - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, @@ -169,7 +169,7 @@ export function createSentryServerInstrumentation( span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.action', { 'http.method': info.request.method, - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, @@ -212,7 +212,7 @@ export function createSentryServerInstrumentation( span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); captureInstrumentationError(result, captureErrors, 'react_router.middleware', { 'http.method': info.request.method, - 'http.url': urlPath, + [URL_FULL]: urlPath, }); } }, diff --git a/packages/react-router/test/client/createClientInstrumentation.test.ts b/packages/react-router/test/client/createClientInstrumentation.test.ts index d5c44f4cf6ca..350871dbb5e7 100644 --- a/packages/react-router/test/client/createClientInstrumentation.test.ts +++ b/packages/react-router/test/client/createClientInstrumentation.test.ts @@ -324,7 +324,7 @@ describe('createSentryClientInstrumentation', () => { }); expect(core.captureException).toHaveBeenCalledWith(mockError, { - mechanism: { type: 'react_router.client_loader', handled: false, data: { 'http.url': '/test-path' } }, + mechanism: { type: 'react_router.client_loader', handled: false, data: { 'url.full': '/test-path' } }, }); // Should also set span status to error for actual Error instances @@ -384,7 +384,7 @@ describe('createSentryClientInstrumentation', () => { }); expect(core.captureException).toHaveBeenCalledWith(mockError, { - mechanism: { type: 'react_router.navigate', handled: false, data: { 'http.url': '/about' } }, + mechanism: { type: 'react_router.navigate', handled: false, data: { 'url.full': '/about' } }, }); // Should set span status to error @@ -511,7 +511,7 @@ describe('createSentryClientInstrumentation', () => { expect(mockNavigationSpan.setStatus).toHaveBeenCalledWith({ code: 2, message: 'internal_error' }); expect(core.captureException).toHaveBeenCalledWith(mockError, { - mechanism: { type: 'react_router.navigate', handled: false, data: { 'http.url': '/error-page' } }, + mechanism: { type: 'react_router.navigate', handled: false, data: { 'url.full': '/error-page' } }, }); }); diff --git a/packages/react-router/test/common/utils.test.ts b/packages/react-router/test/common/utils.test.ts index 3479744328ce..53c660b7f7d6 100644 --- a/packages/react-router/test/common/utils.test.ts +++ b/packages/react-router/test/common/utils.test.ts @@ -89,7 +89,7 @@ describe('captureInstrumentationError', () => { it('should capture error when captureErrors is true', () => { const error = new Error('test error'); const result = { status: 'error' as const, error }; - const data = { 'http.url': '/test' }; + const data = { 'url.full': '/test' }; captureInstrumentationError(result, true, 'react_router.loader', data); diff --git a/packages/react-router/test/server/createServerInstrumentation.test.ts b/packages/react-router/test/server/createServerInstrumentation.test.ts index 37143cb66a26..ad2219deb18b 100644 --- a/packages/react-router/test/server/createServerInstrumentation.test.ts +++ b/packages/react-router/test/server/createServerInstrumentation.test.ts @@ -182,7 +182,7 @@ describe('createSentryServerInstrumentation', () => { mechanism: { type: 'react_router.request_handler', handled: false, - data: { 'http.method': 'GET', 'http.url': '/api/users' }, + data: { 'http.method': 'GET', 'url.full': '/api/users' }, }, }); }); @@ -209,7 +209,7 @@ describe('createSentryServerInstrumentation', () => { mechanism: { type: 'react_router.request_handler', handled: false, - data: { 'http.method': 'GET', 'http.url': '/api/users' }, + data: { 'http.method': 'GET', 'url.full': '/api/users' }, }, }); }); @@ -544,7 +544,7 @@ describe('createSentryServerInstrumentation', () => { mechanism: { type: 'react_router.loader', handled: false, - data: { 'http.method': 'GET', 'http.url': '/test' }, + data: { 'http.method': 'GET', 'url.full': '/test' }, }, }); diff --git a/packages/remix/src/server/instrumentServer.ts b/packages/remix/src/server/instrumentServer.ts index c4eb4ed7e420..46e4c33285ca 100644 --- a/packages/remix/src/server/instrumentServer.ts +++ b/packages/remix/src/server/instrumentServer.ts @@ -133,7 +133,7 @@ function makeWrappedDocumentRequestFunction(instrumentTracing?: boolean) { onlyIfParent: true, attributes: { method: request.method, - url: request.url, + [URL_FULL]: request.url, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.remix', [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.remix.document_request', }, diff --git a/packages/remix/src/server/integrations/tracing-channel.ts b/packages/remix/src/server/integrations/tracing-channel.ts index 485554e13d15..7051c9cbc2c8 100644 --- a/packages/remix/src/server/integrations/tracing-channel.ts +++ b/packages/remix/src/server/integrations/tracing-channel.ts @@ -16,7 +16,6 @@ import { HTTP_METHOD, HTTP_ROUTE, HTTP_STATUS_CODE, - HTTP_URL, URL_FULL, URL_PATH, SENTRY_KIND, @@ -72,8 +71,6 @@ function getRequestAttributes(request: unknown): SpanAttributes { attributes[HTTP_METHOD] = method; } if (typeof url === 'string') { - // oxlint-disable-next-line typescript/no-deprecated - attributes[HTTP_URL] = url; const urlObject = parseStringToURLObject(url); attributes[URL_FULL] = urlObject && !isURLObjectRelative(urlObject) ? urlObject.href : undefined; attributes[URL_PATH] = urlObject?.pathname; diff --git a/packages/remix/src/vendor/instrumentation.ts b/packages/remix/src/vendor/instrumentation.ts index e12253b9a380..d33341507723 100644 --- a/packages/remix/src/vendor/instrumentation.ts +++ b/packages/remix/src/vendor/instrumentation.ts @@ -21,7 +21,7 @@ import { InstrumentationNodeModuleFile, isWrapped, } from '@opentelemetry/instrumentation'; -import { CODE_FUNCTION, HTTP_METHOD, HTTP_ROUTE, HTTP_STATUS_CODE, HTTP_URL } from '@sentry/conventions/attributes'; +import { CODE_FUNCTION, HTTP_METHOD, HTTP_ROUTE, HTTP_STATUS_CODE, URL_FULL } from '@sentry/conventions/attributes'; import type { Params } from '@remix-run/router'; import type * as remixRunServerRuntime from '@remix-run/server-runtime'; import type * as remixRunServerRuntimeData from '@remix-run/server-runtime/dist/data'; @@ -334,7 +334,7 @@ export class RemixInstrumentation extends InstrumentationBase { const addRequestAttributesToSpan = (span: Span, request: Request): void => { span.setAttributes({ [HTTP_METHOD]: request.method, - [HTTP_URL]: request.url, + [URL_FULL]: request.url, }); }; diff --git a/packages/remix/test/server/tracing-channel.test.ts b/packages/remix/test/server/tracing-channel.test.ts index a9a1c243f1c3..2db4ac97bc39 100644 --- a/packages/remix/test/server/tracing-channel.test.ts +++ b/packages/remix/test/server/tracing-channel.test.ts @@ -50,7 +50,7 @@ describe('remixIntegration (Orchestrion-based)', () => { 'sentry.op': 'http.server', 'code.function': 'requestHandler', 'http.method': 'GET', - 'http.url': 'http://localhost/users', + 'url.full': 'http://localhost/users', }), }), ); @@ -102,7 +102,7 @@ describe('remixIntegration (Orchestrion-based)', () => { 'sentry.op': 'loader.remix', 'code.function': 'loader', 'http.method': 'GET', - 'http.url': 'http://localhost/users/123', + 'url.full': 'http://localhost/users/123', 'match.route.id': 'routes/users.$userId', 'match.params.userId': '123', }), diff --git a/packages/sveltekit/src/server-common/handle.ts b/packages/sveltekit/src/server-common/handle.ts index 20965b8e6ddb..5a852c9eb779 100644 --- a/packages/sveltekit/src/server-common/handle.ts +++ b/packages/sveltekit/src/server-common/handle.ts @@ -23,7 +23,7 @@ import { import type { Handle, ResolveOptions } from '@sveltejs/kit'; import { DEBUG_BUILD } from '../common/debug-build'; import { getTracePropagationData, sendErrorToSentry } from './utils'; -import { HTTP_ROUTE, HTTP_URL, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { HTTP_ROUTE, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; export type SentryHandleOptions = { /** @@ -180,8 +180,7 @@ async function instrumentHandle( [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.sveltekit', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: routeName ? 'route' : 'url', 'sveltekit.tracing.original_name': originalName, - // oxlint-disable-next-line typescript-eslint(no-deprecated) - [URL_FULL]: kitRootSpanAttributes[URL_FULL] ?? kitRootSpanAttributes[HTTP_URL] ?? event.url.href, + [URL_FULL]: kitRootSpanAttributes[URL_FULL] ?? event.url.href, [URL_PATH]: kitRootSpanAttributes[URL_PATH] ?? event.url.pathname, ...(routeName && { [HTTP_ROUTE]: routeName,