diff --git a/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts b/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts index 26ba665a418f..5d4ebe233c4d 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/captureFeedback/test.ts @@ -44,6 +44,7 @@ sentryTest('should capture feedback (@sentry-internal/feedback import)', async ( const feedbackEvent = envelopeRequestParser((await feedbackRequestPromise).request()); expect(feedbackEvent).toEqual({ type: 'feedback', + breadcrumbs: expect.any(Array), contexts: { feedback: { contact_email: 'janedoe@example.org', diff --git a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/test.ts b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/test.ts index 1590c68652a3..057b5d43a1c8 100644 --- a/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/test.ts +++ b/dev-packages/browser-integration-tests/suites/feedback/captureFeedbackAndReplay/test.ts @@ -50,15 +50,16 @@ sentryTest('should capture feedback (@sentry-internal/feedback import)', async ( expect(breadcrumbs).toEqual( expect.arrayContaining([ - { + expect.objectContaining({ category: 'sentry.feedback', data: { feedbackId: expect.any(String) }, - }, + }), ]), ); expect(feedbackEvent).toEqual({ type: 'feedback', + breadcrumbs: expect.any(Array), contexts: { feedback: { contact_email: 'janedoe@example.org', diff --git a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js index e28325fcf78e..579523ee2015 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js @@ -1,4 +1,5 @@ import * as Sentry from '@sentry/browser'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/browser'; import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; @@ -17,4 +18,4 @@ scope.addEventProcessor(event => { event.transaction = 'testTransactionDSC'; return event; }); -scope.getTransaction().setMetadata({ source: 'custom' }); +scope.getTransaction().setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'custom'); diff --git a/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/propagation.test.ts index 9b83e882a739..cbb2c889edec 100644 --- a/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/propagation.test.ts @@ -65,6 +65,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.response.status_code': 200, 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', + 'sentry.source': 'route', }, op: 'http.server', span_id: expect.any(String), @@ -89,6 +90,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.response.status_code': 200, 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', + 'sentry.source': 'route', }, op: 'http.server', parent_span_id: outgoingHttpSpanId, @@ -162,6 +164,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.response.status_code': 200, 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', + 'sentry.source': 'route', }, op: 'http.server', span_id: expect.any(String), @@ -186,6 +189,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.response.status_code': 200, 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', + 'sentry.source': 'route', }, op: 'http.server', parent_span_id: outgoingHttpSpanId, diff --git a/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/transactions.test.ts index d2ab9e3d664f..0429adca8623 100644 --- a/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/transactions.test.ts @@ -30,6 +30,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.response.status_code': 200, 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', + 'sentry.source': 'route', }, op: 'http.server', span_id: expect.any(String), diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts index 8df1b9c3d988..08b3a8f024cc 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import express from 'express'; const app = express(); @@ -9,7 +8,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/packages/core/src/tracing/dynamicSamplingContext.ts b/packages/core/src/tracing/dynamicSamplingContext.ts index ff4599a42a68..222763a8a781 100644 --- a/packages/core/src/tracing/dynamicSamplingContext.ts +++ b/packages/core/src/tracing/dynamicSamplingContext.ts @@ -3,6 +3,7 @@ import { dropUndefinedKeys } from '@sentry/utils'; import { DEFAULT_ENVIRONMENT } from '../constants'; import { getClient } from '../currentScopes'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes'; import { getRootSpan } from '../utils/getRootSpan'; import { spanIsSampled, spanToJSON } from '../utils/spanUtils'; @@ -66,7 +67,7 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly { name: 'tx', metadata: { sampleRate: 0.56, - source: 'route', + }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, sampled: true, }); @@ -98,9 +100,11 @@ describe('getDynamicSamplingContextFromSpan', () => { const transaction = new Transaction({ name: 'tx', metadata: { - source: 'url', sampleRate: 0.56, }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + }, }); const dsc = getDynamicSamplingContextFromSpan(transaction); @@ -110,11 +114,11 @@ describe('getDynamicSamplingContextFromSpan', () => { test.each([ ['is included if transaction source is parameterized route/url', 'route'], ['is included if transaction source is a custom name', 'custom'], - ])('%s', (_: string, source) => { + ] as const)('%s', (_: string, source: TransactionSource) => { const transaction = startInactiveSpan({ name: 'tx', - metadata: { - ...(source && { source: source as TransactionSource }), + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, }, }); diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index d95f713147ec..1d06ea009937 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -266,6 +266,7 @@ describe('startSpan', () => { data: { 'sentry.origin': 'auto.http.browser', 'sentry.sample_rate': 0, + 'sentry.source': 'custom', }, origin: 'auto.http.browser', description: 'GET users/[id]', diff --git a/packages/core/test/lib/tracing/transaction.test.ts b/packages/core/test/lib/tracing/transaction.test.ts index 415c0448f78e..9371bda548fd 100644 --- a/packages/core/test/lib/tracing/transaction.test.ts +++ b/packages/core/test/lib/tracing/transaction.test.ts @@ -1,4 +1,9 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Transaction } from '../../../src'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + Transaction, +} from '../../../src'; describe('transaction', () => { describe('name', () => { @@ -16,7 +21,7 @@ describe('transaction', () => { transaction.name = 'new name'; expect(transaction.name).toEqual('new name'); - expect(transaction.metadata.source).toEqual('custom'); + expect(transaction.attributes['sentry.source']).toEqual('custom'); }); it('allows to update the name via setName', () => { @@ -27,7 +32,7 @@ describe('transaction', () => { transaction.setName('new name'); expect(transaction.name).toEqual('new name'); - expect(transaction.metadata.source).toEqual('custom'); + expect(transaction.attributes['sentry.source']).toEqual('custom'); }); it('allows to update the name via updateName', () => { @@ -38,7 +43,7 @@ describe('transaction', () => { transaction.updateName('new name'); expect(transaction.name).toEqual('new name'); - expect(transaction.metadata.source).toEqual('route'); + expect(transaction.attributes['sentry.source']).toEqual('route'); }); /* eslint-enable deprecation/deprecation */ }); @@ -48,15 +53,13 @@ describe('transaction', () => { it('works with defaults', () => { const transaction = new Transaction({ name: 'span name' }); expect(transaction.metadata).toEqual({ - source: 'custom', spanMetadata: {}, }); }); it('allows to set metadata in constructor', () => { - const transaction = new Transaction({ name: 'span name', metadata: { source: 'url', request: {} } }); + const transaction = new Transaction({ name: 'span name', metadata: { request: {} } }); expect(transaction.metadata).toEqual({ - source: 'url', spanMetadata: {}, request: {}, }); @@ -71,37 +74,31 @@ describe('transaction', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 0.5, }, }); + expect(transaction.metadata).toEqual({ - source: 'url', sampleRate: 0.5, spanMetadata: {}, request: {}, }); - }); - - it('allows to update metadata via setMetadata', () => { - const transaction = new Transaction({ name: 'span name', metadata: { source: 'url', request: {} } }); - - transaction.setMetadata({ source: 'route' }); - expect(transaction.metadata).toEqual({ - source: 'route', - spanMetadata: {}, - request: {}, + expect(transaction.attributes).toEqual({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 0.5, }); }); - it('allows to update metadata via setAttribute', () => { - const transaction = new Transaction({ name: 'span name', metadata: { source: 'url', request: {} } }); + it('allows to update metadata via setMetadata', () => { + const transaction = new Transaction({ name: 'span name', metadata: {} }); - transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); + transaction.setMetadata({ request: {} }); expect(transaction.metadata).toEqual({ - source: 'route', spanMetadata: {}, request: {}, }); }); + /* eslint-enable deprecation/deprecation */ }); }); diff --git a/packages/deno/test/__snapshots__/mod.test.ts.snap b/packages/deno/test/__snapshots__/mod.test.ts.snap index d728072d38d6..417acf1e7639 100644 --- a/packages/deno/test/__snapshots__/mod.test.ts.snap +++ b/packages/deno/test/__snapshots__/mod.test.ts.snap @@ -41,41 +41,6 @@ snapshot[`captureException 1`] = ` }, stacktrace: { frames: [ - { - colno: 20, - filename: "ext:cli/40_testing.js", - function: "outerWrapped", - in_app: false, - lineno: 472, - }, - { - colno: 33, - filename: "ext:cli/40_testing.js", - function: "exitSanitizer", - in_app: false, - lineno: 458, - }, - { - colno: 31, - filename: "ext:cli/40_testing.js", - function: "resourceSanitizer", - in_app: false, - lineno: 410, - }, - { - colno: 33, - filename: "ext:cli/40_testing.js", - function: "asyncOpSanitizer", - in_app: false, - lineno: 177, - }, - { - colno: 11, - filename: "ext:cli/40_testing.js", - function: "innerWrapped", - in_app: false, - lineno: 526, - }, { colno: 27, context_line: " client.captureException(something());", diff --git a/packages/deno/test/normalize.ts b/packages/deno/test/normalize.ts index 64295932e00d..4dbbc8f3f6ec 100644 --- a/packages/deno/test/normalize.ts +++ b/packages/deno/test/normalize.ts @@ -152,9 +152,9 @@ function normalizeEvent(event: sentryTypes.Event): sentryTypes.Event { } if (event.exception?.values?.[0].stacktrace?.frames) { - // Exlcude Deno frames since these may change between versions + // Exclude Deno frames since these may change between versions event.exception.values[0].stacktrace.frames = event.exception.values[0].stacktrace.frames.filter( - frame => !frame.filename?.includes('deno:'), + frame => !frame.filename?.includes('deno:') && !frame.filename?.startsWith('ext:'), ); } diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index f403df54284e..5f5cbf054666 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -9,6 +9,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, applySdkMetadata } from '@sentry/core import { GLOBAL_OBJ } from '@sentry/utils'; import Ember from 'ember'; +import type { TransactionSource } from '@sentry/types'; import type { EmberSentryConfig, GlobalConfig, OwnConfig } from './types'; function _getSentryInitConfig(): EmberSentryConfig['sentry'] { @@ -68,11 +69,12 @@ export const instrumentRoutePerformance = (BaseRoute description: string, fn: X, args: Parameters, + source: TransactionSource, ): Promise> => { return startSpan( { attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'ember', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, }, op, name: description, @@ -94,15 +96,22 @@ export const instrumentRoutePerformance = (BaseRoute this.fullRouteName, super.beforeModel.bind(this), args, + 'custom', ); } public async model(...args: unknown[]): Promise { - return instrumentFunction('ui.ember.route.model', this.fullRouteName, super.model.bind(this), args); + return instrumentFunction('ui.ember.route.model', this.fullRouteName, super.model.bind(this), args, 'custom'); } public afterModel(...args: unknown[]): void | Promise { - return instrumentFunction('ui.ember.route.after_model', this.fullRouteName, super.afterModel.bind(this), args); + return instrumentFunction( + 'ui.ember.route.after_model', + this.fullRouteName, + super.afterModel.bind(this), + args, + 'custom', + ); } public setupController(...args: unknown[]): void | Promise { @@ -111,6 +120,7 @@ export const instrumentRoutePerformance = (BaseRoute this.fullRouteName, super.setupController.bind(this), args, + 'custom', ); } }, diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 1f4cdaf992c9..0c54a4f5b665 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -1,4 +1,4 @@ -import { getIsolationScope } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getIsolationScope } from '@sentry/core'; import { addTracingExtensions, captureException, @@ -94,8 +94,8 @@ async function withServerActionInstrumentationImplementation { diff --git a/packages/node-experimental/test/integration/scope.test.ts b/packages/node-experimental/test/integration/scope.test.ts index 8f73f5487b2b..3f6c8a441216 100644 --- a/packages/node-experimental/test/integration/scope.test.ts +++ b/packages/node-experimental/test/integration/scope.test.ts @@ -88,7 +88,7 @@ describe('Integration | Scope', () => { expect.objectContaining({ contexts: expect.objectContaining({ trace: { - data: { 'otel.kind': 'INTERNAL', 'sentry.origin': 'manual' }, + data: { 'otel.kind': 'INTERNAL', 'sentry.origin': 'manual', 'sentry.source': 'custom' }, span_id: spanId, status: 'ok', trace_id: traceId, diff --git a/packages/node-experimental/test/integration/transactions.test.ts b/packages/node-experimental/test/integration/transactions.test.ts index 72dd4966bc41..f1b89e922641 100644 --- a/packages/node-experimental/test/integration/transactions.test.ts +++ b/packages/node-experimental/test/integration/transactions.test.ts @@ -29,7 +29,9 @@ describe('Integration | Transactions', () => { { op: 'test op', name: 'test name', - source: 'task', + attributes: { + [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task', + }, origin: 'auto.test', metadata: { requestPath: 'test-path' }, }, @@ -85,6 +87,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), @@ -106,7 +109,6 @@ describe('Integration | Transactions', () => { transaction: 'test name', }), sampleRate: 1, - source: 'task', spanMetadata: expect.any(Object), requestPath: 'test-path', }), @@ -185,26 +187,34 @@ describe('Integration | Transactions', () => { Sentry.addBreadcrumb({ message: 'test breadcrumb 1', timestamp: 123456 }); Sentry.withIsolationScope(() => { - Sentry.startSpan({ op: 'test op', name: 'test name', source: 'task', origin: 'auto.test' }, span => { - Sentry.addBreadcrumb({ message: 'test breadcrumb 2', timestamp: 123456 }); + Sentry.startSpan( + { + op: 'test op', + name: 'test name', + origin: 'auto.test', + attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' }, + }, + span => { + Sentry.addBreadcrumb({ message: 'test breadcrumb 2', timestamp: 123456 }); - span.setAttributes({ - 'test.outer': 'test value', - }); + span.setAttributes({ + 'test.outer': 'test value', + }); - const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' }); - subSpan.end(); + const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' }); + subSpan.end(); - Sentry.setTag('test.tag', 'test value'); + Sentry.setTag('test.tag', 'test value'); - Sentry.startSpan({ name: 'inner span 2' }, innerSpan => { - Sentry.addBreadcrumb({ message: 'test breadcrumb 3', timestamp: 123456 }); + Sentry.startSpan({ name: 'inner span 2' }, innerSpan => { + Sentry.addBreadcrumb({ message: 'test breadcrumb 3', timestamp: 123456 }); - innerSpan.setAttributes({ - 'test.inner': 'test value', + innerSpan.setAttributes({ + 'test.inner': 'test value', + }); }); - }); - }); + }, + ); }); Sentry.withIsolationScope(() => { @@ -251,6 +261,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), @@ -297,6 +308,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op b', 'sentry.origin': 'manual', + 'sentry.source': 'custom', }, op: 'test op b', span_id: expect.any(String), @@ -409,6 +421,7 @@ describe('Integration | Transactions', () => { data: { 'otel.kind': 'INTERNAL', 'sentry.origin': 'manual', + 'sentry.source': 'custom', }, span_id: expect.any(String), status: 'ok', @@ -452,6 +465,7 @@ describe('Integration | Transactions', () => { data: { 'otel.kind': 'INTERNAL', 'sentry.origin': 'manual', + 'sentry.source': 'custom', }, span_id: expect.any(String), status: 'ok', @@ -508,12 +522,20 @@ describe('Integration | Transactions', () => { context.with( trace.setSpanContext(setPropagationContextOnContext(context.active(), propagationContext), spanContext), () => { - Sentry.startSpan({ op: 'test op', name: 'test name', source: 'task', origin: 'auto.test' }, () => { - const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' }); - subSpan.end(); + Sentry.startSpan( + { + op: 'test op', + name: 'test name', + origin: 'auto.test', + attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task' }, + }, + () => { + const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' }); + subSpan.end(); - Sentry.startSpan({ name: 'inner span 2' }, () => {}); - }); + Sentry.startSpan({ name: 'inner span 2' }, () => {}); + }, + ); }, ); @@ -531,6 +553,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 0ac97daae7c7..8e1cb695c05b 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -72,7 +72,7 @@ export function tracingHandler(): ( op: 'http.server', origin: 'auto.http.node.tracingHandler', ...ctx, - data: { + attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, }, metadata: { diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index 2af325d5ddbd..af550ef70643 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -1,6 +1,7 @@ import * as http from 'http'; import * as https from 'https'; import type { SentrySpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { Transaction } from '@sentry/core'; import { getCurrentScope, makeMain, setUser, spanToJSON, startInactiveSpan } from '@sentry/core'; import { Hub, addTracingExtensions } from '@sentry/core'; @@ -162,7 +163,7 @@ describe('tracing', () => { it('adds the transaction name to the the baggage header if a valid transaction source is set', async () => { nock('http://dogs.are.great').get('/').reply(200); - createTransactionOnScope({}, { metadata: { source: 'route' } }); + createTransactionOnScope({}, { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' } }); const request = http.get({ host: 'http://dogs.are.great/', headers: { baggage: 'dog=great' } }); const baggageHeader = request.getHeader('baggage') as string; @@ -176,7 +177,7 @@ describe('tracing', () => { it('does not add the transaction name to the the baggage header if url transaction source is set', async () => { nock('http://dogs.are.great').get('/').reply(200); - createTransactionOnScope({}, { metadata: { source: 'url' } }); + createTransactionOnScope({}, { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } }); const request = http.get({ host: 'http://dogs.are.great/', headers: { baggage: 'dog=great' } }); const baggageHeader = request.getHeader('baggage') as string; diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts index 9996fc73111f..f79dc9f5b2e4 100644 --- a/packages/opentelemetry-node/src/spanprocessor.ts +++ b/packages/opentelemetry-node/src/spanprocessor.ts @@ -179,7 +179,9 @@ function getTraceData(otelSpan: OtelSpan, parentContext: Context): Partial { otelSpan.end(); // eslint-disable-next-line deprecation/deprecation - expect(sentrySpan?.transaction?.metadata.source).toBe('url'); + expect(sentrySpan?.transaction?.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('url'); }); }); @@ -687,7 +688,7 @@ describe('SentrySpanProcessor', () => { otelSpan.end(); // eslint-disable-next-line deprecation/deprecation - expect(sentrySpan?.transaction?.metadata.source).toBe('route'); + expect(sentrySpan?.transaction?.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('route'); }); }); @@ -703,7 +704,7 @@ describe('SentrySpanProcessor', () => { otelSpan.end(); // eslint-disable-next-line deprecation/deprecation - expect(sentrySpan?.transaction?.metadata.source).toBe('route'); + expect(sentrySpan?.transaction?.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('route'); }); }); diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index 1f6792932dcd..e8baeb17d2cc 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -4,6 +4,7 @@ import { ExportResultCode } from '@opentelemetry/core'; import type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; import type { Transaction } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, flush, getCurrentHub } from '@sentry/core'; import type { Scope, Span as SentrySpan, SpanOrigin, TransactionSource } from '@sentry/types'; import { addNonEnumerableProperty, logger } from '@sentry/utils'; @@ -159,10 +160,12 @@ function createTransactionForOtelSpan(span: ReadableSpan): Transaction { status: mapStatus(span), startTimestamp: convertOtelTimeToSeconds(span.startTime), metadata: { - source, sampleRate: span.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] as number | undefined, ...metadata, }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, + }, data: removeSentryAttributes(data), origin, tags, diff --git a/packages/opentelemetry/test/custom/transaction.test.ts b/packages/opentelemetry/test/custom/transaction.test.ts index ae07939981cc..f56350abeb8e 100644 --- a/packages/opentelemetry/test/custom/transaction.test.ts +++ b/packages/opentelemetry/test/custom/transaction.test.ts @@ -24,7 +24,6 @@ describe('startTranscation', () => { expect(transaction.spanRecorder?.spans).toHaveLength(1); // eslint-disable-next-line deprecation/deprecation expect(transaction.metadata).toEqual({ - source: 'custom', spanMetadata: {}, }); @@ -55,7 +54,6 @@ describe('startTranscation', () => { expect(transaction).toBeInstanceOf(Transaction); // eslint-disable-next-line deprecation/deprecation expect(transaction.metadata).toEqual({ - source: 'custom', spanMetadata: {}, }); diff --git a/packages/opentelemetry/test/integration/scope.test.ts b/packages/opentelemetry/test/integration/scope.test.ts index cc4def42ddbc..594fa1bcf9ae 100644 --- a/packages/opentelemetry/test/integration/scope.test.ts +++ b/packages/opentelemetry/test/integration/scope.test.ts @@ -98,6 +98,7 @@ describe('Integration | Scope', () => { data: { 'otel.kind': 'INTERNAL', 'sentry.origin': 'manual', + 'sentry.source': 'custom', }, span_id: spanId, status: 'ok', diff --git a/packages/opentelemetry/test/integration/transactions.test.ts b/packages/opentelemetry/test/integration/transactions.test.ts index 2da60af0195d..08a62e93361d 100644 --- a/packages/opentelemetry/test/integration/transactions.test.ts +++ b/packages/opentelemetry/test/integration/transactions.test.ts @@ -1,6 +1,6 @@ import { TraceFlags, context, trace } from '@opentelemetry/api'; import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { addBreadcrumb, getClient, setTag, withIsolationScope } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addBreadcrumb, getClient, setTag, withIsolationScope } from '@sentry/core'; import type { PropagationContext, TransactionEvent } from '@sentry/types'; import { logger } from '@sentry/utils'; @@ -31,9 +31,11 @@ describe('Integration | Transactions', () => { { op: 'test op', name: 'test name', - source: 'task', origin: 'auto.test', metadata: { requestPath: 'test-path' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'task', + }, }, span => { addBreadcrumb({ message: 'test breadcrumb 2', timestamp: 123456 }); @@ -86,6 +88,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), @@ -106,7 +109,6 @@ describe('Integration | Transactions', () => { transaction: 'test name', }), sampleRate: 1, - source: 'task', spanMetadata: expect.any(Object), requestPath: 'test-path', }), @@ -250,6 +252,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), @@ -296,6 +299,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op b', 'sentry.origin': 'manual', + 'sentry.source': 'custom', }, op: 'test op b', span_id: expect.any(String), @@ -377,6 +381,7 @@ describe('Integration | Transactions', () => { 'otel.kind': 'INTERNAL', 'sentry.op': 'test op', 'sentry.origin': 'auto.test', + 'sentry.source': 'task', }, op: 'test op', span_id: expect.any(String), diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index 5785eb7fdb00..fa6e1d09dad8 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -218,8 +218,10 @@ describe('trace', () => { name: 'outer', op: 'my-op', origin: 'auto.test.origin', - source: 'task', metadata: { requestPath: 'test-path' }, + attributes: { + [InternalSentrySemanticAttributes.SOURCE]: 'task', + }, }, span => { expect(span).toBeDefined(); @@ -335,7 +337,9 @@ describe('trace', () => { name: 'outer', op: 'my-op', origin: 'auto.test.origin', - source: 'task', + attributes: { + [InternalSentrySemanticAttributes.SOURCE]: 'task', + }, metadata: { requestPath: 'test-path' }, }); diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 10e91837149d..347e8a2f73e8 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -78,8 +78,8 @@ export function startPageloadSpan(): void { op: 'pageload', origin: 'auto.pageload.remix', tags: DEFAULT_TAGS, - metadata: { - source: 'url', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, }; @@ -103,8 +103,8 @@ function startNavigationSpan(matches: RouteMatch[]): void { op: 'navigation', origin: 'auto.navigation.remix', tags: DEFAULT_TAGS, - metadata: { - source: 'route', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, }; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 19e541fd4ebc..7eb30e46af12 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -1,6 +1,7 @@ /* eslint-disable max-lines */ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getActiveTransaction, getClient, @@ -415,13 +416,13 @@ export function startRequestHandlerTransaction( op: 'http.server', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.remix', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, }, tags: { method: request.method, }, ...traceparentData, metadata: { - source, dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, }, }); diff --git a/packages/sveltekit/src/client/load.ts b/packages/sveltekit/src/client/load.ts index 3e454bdb364a..621015badbf1 100644 --- a/packages/sveltekit/src/client/load.ts +++ b/packages/sveltekit/src/client/load.ts @@ -1,4 +1,9 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, handleCallbackErrors, startSpan } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + handleCallbackErrors, + startSpan, +} from '@sentry/core'; import { captureException } from '@sentry/svelte'; import { addNonEnumerableProperty, objectify } from '@sentry/utils'; import type { LoadEvent } from '@sveltejs/kit'; @@ -86,12 +91,10 @@ export function wrapLoadWithSentry any>(origLoad: T) op: 'function.sveltekit.load', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: routeId ? 'route' : 'url', }, name: routeId ? routeId : event.url.pathname, status: 'ok', - metadata: { - source: routeId ? 'route' : 'url', - }, }, () => handleCallbackErrors(() => wrappingTarget.apply(thisArg, [patchedEvent]), sendErrorToSentry), ); diff --git a/packages/sveltekit/src/server/handle.ts b/packages/sveltekit/src/server/handle.ts index e06838cca413..cc53f7541923 100644 --- a/packages/sveltekit/src/server/handle.ts +++ b/packages/sveltekit/src/server/handle.ts @@ -1,5 +1,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getCurrentScope, getDynamicSamplingContextFromSpan, @@ -179,12 +180,12 @@ async function instrumentHandle( op: 'http.server', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: event.route?.id ? 'route' : 'url', }, name: `${event.request.method} ${event.route?.id || event.url.pathname}`, status: 'ok', ...traceparentData, metadata: { - source: event.route?.id ? 'route' : 'url', dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, }, }, diff --git a/packages/sveltekit/src/server/load.ts b/packages/sveltekit/src/server/load.ts index 9728dcf47b5b..0d73b27a9d1b 100644 --- a/packages/sveltekit/src/server/load.ts +++ b/packages/sveltekit/src/server/load.ts @@ -1,5 +1,10 @@ /* eslint-disable @sentry-internal/sdk/no-optional-chaining */ -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getCurrentScope, startSpan } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + getCurrentScope, + startSpan, +} from '@sentry/core'; import { captureException } from '@sentry/node'; import { addNonEnumerableProperty, objectify } from '@sentry/utils'; import type { LoadEvent, ServerLoadEvent } from '@sveltejs/kit'; @@ -69,12 +74,10 @@ export function wrapLoadWithSentry any>(origLoad: T) op: 'function.sveltekit.load', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: routeId ? 'route' : 'url', }, name: routeId ? routeId : event.url.pathname, status: 'ok', - metadata: { - source: routeId ? 'route' : 'url', - }, }; try { @@ -138,11 +141,11 @@ export function wrapServerLoadWithSentry any>(origSe op: 'function.sveltekit.server.load', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: routeId ? 'route' : 'url', }, name: routeId ? routeId : event.url.pathname, status: 'ok', metadata: { - source: routeId ? 'route' : 'url', dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, }, data: { diff --git a/packages/sveltekit/test/client/load.test.ts b/packages/sveltekit/test/client/load.test.ts index ca7c1d625224..3c625865cf1c 100644 --- a/packages/sveltekit/test/client/load.test.ts +++ b/packages/sveltekit/test/client/load.test.ts @@ -3,7 +3,7 @@ import type { Load } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; import { vi } from 'vitest'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { wrapLoadWithSentry } from '../../src/client/load'; const mockCaptureException = vi.spyOn(SentrySvelte, 'captureException').mockImplementation(() => 'xx'); @@ -109,13 +109,11 @@ describe('wrapLoadWithSentry', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, op: 'function.sveltekit.load', name: '/users/[id]', status: 'ok', - metadata: { - source: 'route', - }, }, expect.any(Function), ); @@ -139,13 +137,11 @@ describe('wrapLoadWithSentry', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, op: 'function.sveltekit.load', name: '/users/123', status: 'ok', - metadata: { - source: 'url', - }, }, expect.any(Function), ); diff --git a/packages/sveltekit/test/server/handle.test.ts b/packages/sveltekit/test/server/handle.test.ts index 9bba3c99e68e..019eab5992d0 100644 --- a/packages/sveltekit/test/server/handle.test.ts +++ b/packages/sveltekit/test/server/handle.test.ts @@ -1,4 +1,4 @@ -import { addTracingExtensions } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addTracingExtensions } from '@sentry/core'; import { NodeClient, setCurrentClient } from '@sentry/node'; import * as SentryNode from '@sentry/node'; import type { Transaction } from '@sentry/types'; @@ -133,7 +133,7 @@ describe('handleSentry', () => { expect(ref.name).toEqual('GET /users/[id]'); expect(ref.op).toEqual('http.server'); expect(ref.status).toEqual(isError ? 'internal_error' : 'ok'); - expect(ref.metadata.source).toEqual('route'); + expect(ref.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); expect(ref.endTimestamp).toBeDefined(); expect(ref.spanRecorder.spans).toHaveLength(1); @@ -169,7 +169,7 @@ describe('handleSentry', () => { expect(ref.name).toEqual('GET /users/[id]'); expect(ref.op).toEqual('http.server'); expect(ref.status).toEqual(isError ? 'internal_error' : 'ok'); - expect(ref.metadata.source).toEqual('route'); + expect(ref.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); expect(ref.endTimestamp).toBeDefined(); diff --git a/packages/sveltekit/test/server/load.test.ts b/packages/sveltekit/test/server/load.test.ts index 388541a8d884..790ded799106 100644 --- a/packages/sveltekit/test/server/load.test.ts +++ b/packages/sveltekit/test/server/load.test.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, addTracingExtensions } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addTracingExtensions } from '@sentry/core'; import * as SentryNode from '@sentry/node'; import type { Load, ServerLoad } from '@sveltejs/kit'; import { error, redirect } from '@sveltejs/kit'; @@ -199,13 +199,11 @@ describe('wrapLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, op: 'function.sveltekit.load', name: '/users/[id]', status: 'ok', - metadata: { - source: 'route', - }, }, expect.any(Function), ); @@ -220,13 +218,11 @@ describe('wrapLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, op: 'function.sveltekit.load', name: '/users/123', status: 'ok', - metadata: { - source: 'url', - }, }, expect.any(Function), ); @@ -256,6 +252,7 @@ describe('wrapServerLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, op: 'function.sveltekit.server.load', name: '/users/[id]', @@ -275,7 +272,6 @@ describe('wrapServerLoadWithSentry calls trace', () => { trace_id: '1234567890abcdef1234567890abcdef', transaction: 'dogpark', }, - source: 'route', }, }, expect.any(Function), @@ -291,16 +287,15 @@ describe('wrapServerLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, op: 'function.sveltekit.server.load', name: '/users/[id]', status: 'ok', + metadata: {}, data: { 'http.method': 'GET', }, - metadata: { - source: 'route', - }, }, expect.any(Function), ); @@ -315,6 +310,7 @@ describe('wrapServerLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', }, op: 'function.sveltekit.server.load', name: '/users/[id]', @@ -327,7 +323,6 @@ describe('wrapServerLoadWithSentry calls trace', () => { }, metadata: { dynamicSamplingContext: {}, - source: 'route', }, }, expect.any(Function), @@ -346,6 +341,7 @@ describe('wrapServerLoadWithSentry calls trace', () => { { attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, op: 'function.sveltekit.server.load', name: '/users/123', @@ -365,7 +361,6 @@ describe('wrapServerLoadWithSentry calls trace', () => { trace_id: '1234567890abcdef1234567890abcdef', transaction: 'dogpark', }, - source: 'url', }, }, expect.any(Function), diff --git a/packages/tracing-internal/src/browser/browserTracingIntegration.ts b/packages/tracing-internal/src/browser/browserTracingIntegration.ts index 95dee0c42f5e..ad70af5aa666 100644 --- a/packages/tracing-internal/src/browser/browserTracingIntegration.ts +++ b/packages/tracing-internal/src/browser/browserTracingIntegration.ts @@ -236,16 +236,15 @@ export const browserTracingIntegration = ((_options: Partial( startTimestamp: browserPerformanceTimeOrigin ? browserPerformanceTimeOrigin / 1000 : undefined, op: 'pageload', origin: 'auto.pageload.browser', - metadata: { source: 'url' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + }, }); } @@ -58,7 +61,9 @@ export function instrumentRoutingWithDefaults( name: WINDOW.location.pathname, op: 'navigation', origin: 'auto.navigation.browser', - metadata: { source: 'url' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + }, }); } }); diff --git a/packages/tracing-internal/src/node/integrations/express.ts b/packages/tracing-internal/src/node/integrations/express.ts index 7dabd973252e..617a7d981cf4 100644 --- a/packages/tracing-internal/src/node/integrations/express.ts +++ b/packages/tracing-internal/src/node/integrations/express.ts @@ -376,7 +376,7 @@ function instrumentRouter(appOrRouter: ExpressRouter): void { const transaction = res.__sentry_transaction; const attributes = (transaction && spanToJSON(transaction).data) || {}; - if (transaction && attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] !== 'custom') { + if (transaction && attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'url') { // If the request URL is '/' or empty, the reconstructed route will be empty. // Therefore, we fall back to setting the final route to '/' in this case. const finalRoute = req._reconstructedRoute || '/'; diff --git a/packages/tracing-internal/test/browser/browserTracingIntegration.test.ts b/packages/tracing-internal/test/browser/browserTracingIntegration.test.ts index 7171d41592bd..2655ae05dbe7 100644 --- a/packages/tracing-internal/test/browser/browserTracingIntegration.test.ts +++ b/packages/tracing-internal/test/browser/browserTracingIntegration.test.ts @@ -233,6 +233,7 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, span_id: expect.any(String), start_timestamp: expect.any(Number), @@ -266,6 +267,7 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.test', [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', testy: 'yes', }, span_id: expect.any(String), @@ -327,6 +329,7 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, span_id: expect.any(String), start_timestamp: expect.any(Number), @@ -360,6 +363,7 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.test', [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', testy: 'yes', }, span_id: expect.any(String), diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts index be16c8cf092e..fb93661607aa 100644 --- a/packages/tracing-internal/test/browser/browsertracing.test.ts +++ b/packages/tracing-internal/test/browser/browsertracing.test.ts @@ -1,5 +1,12 @@ /* eslint-disable deprecation/deprecation */ -import { TRACING_DEFAULTS, getClient, getCurrentHub, setCurrentClient, spanToJSON } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + TRACING_DEFAULTS, + getClient, + getCurrentHub, + setCurrentClient, + spanToJSON, +} from '@sentry/core'; import * as hubExtensions from '@sentry/core'; import type { BaseTransportOptions, ClientOptions, DsnComponents, HandlerDataHistory } from '@sentry/types'; import { JSDOM } from 'jsdom'; @@ -240,7 +247,7 @@ describe('BrowserTracing', () => { const transaction = getActiveTransaction() as IdleTransaction; expect(transaction).toBeDefined(); expect(transaction.name).toBe('newName'); - expect(transaction.metadata.source).toBe('custom'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('custom'); expect(mockBeforeNavigation).toHaveBeenCalledTimes(1); }); @@ -252,13 +259,17 @@ describe('BrowserTracing', () => { createBrowserTracing(true, { beforeNavigate: mockBeforeNavigation, routingInstrumentation: (customStartTransaction: (obj: any) => void) => { - customStartTransaction({ name: 'a/path', op: 'pageload', metadata: { source: 'url' } }); + customStartTransaction({ + name: 'a/path', + op: 'pageload', + attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' }, + }); }, }); const transaction = getActiveTransaction() as IdleTransaction; expect(transaction).toBeDefined(); expect(transaction.name).toBe('a/path'); - expect(transaction.metadata.source).toBe('url'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('url'); expect(mockBeforeNavigation).toHaveBeenCalledTimes(1); }); diff --git a/packages/tracing-internal/test/browser/router.test.ts b/packages/tracing-internal/test/browser/router.test.ts index a27926ad9803..e7a12ea91506 100644 --- a/packages/tracing-internal/test/browser/router.test.ts +++ b/packages/tracing-internal/test/browser/router.test.ts @@ -1,3 +1,4 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import type { HandlerDataHistory } from '@sentry/types'; import { JSDOM } from 'jsdom'; @@ -45,7 +46,7 @@ conditionalTest({ min: 16 })('instrumentRoutingWithDefaults', () => { name: 'blank', op: 'pageload', origin: 'auto.pageload.browser', - metadata: { source: 'url' }, + attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' }, startTimestamp: expect.any(Number), }); }); @@ -80,7 +81,7 @@ conditionalTest({ min: 16 })('instrumentRoutingWithDefaults', () => { name: 'blank', op: 'navigation', origin: 'auto.navigation.browser', - metadata: { source: 'url' }, + attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' }, }); }); diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts index 8975b3762a64..f65ceb75eaf6 100644 --- a/packages/tracing/test/span.test.ts +++ b/packages/tracing/test/span.test.ts @@ -12,7 +12,7 @@ import { setCurrentClient, spanToJSON, } from '@sentry/core'; -import type { BaseTransportOptions, ClientOptions, TransactionSource } from '@sentry/types'; +import type { BaseTransportOptions, ClientOptions } from '@sentry/types'; import { TRACEPARENT_REGEXP, Transaction } from '../src'; import { getDefaultBrowserClientOptions } from './testutils'; @@ -667,8 +667,8 @@ describe('SentrySpan', () => { const transaction = new Transaction( { name: 'tx', - metadata: { - source: 'url', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, }, getCurrentHub(), @@ -681,12 +681,12 @@ describe('SentrySpan', () => { test.each([ ['is included if transaction source is paremeterized route/url', 'route'], ['is included if transaction source is a custom name', 'custom'], - ])('%s', (_: string, source) => { + ] as const)('%s', (_, source) => { const transaction = new Transaction( { name: 'tx', - metadata: { - ...(source && { source: source as TransactionSource }), + attributes: { + ...(source && { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source }), }, }, getCurrentHub(), diff --git a/packages/tracing/test/transaction.test.ts b/packages/tracing/test/transaction.test.ts index f9e950dd9cb9..55d162becc21 100644 --- a/packages/tracing/test/transaction.test.ts +++ b/packages/tracing/test/transaction.test.ts @@ -16,17 +16,20 @@ describe('`Transaction` class', () => { describe('transaction name source', () => { it('sets source in constructor if provided', () => { - const transaction = new Transaction({ name: 'dogpark', metadata: { source: 'route' } }); + const transaction = new Transaction({ + name: 'dogpark', + attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' }, + }); expect(transaction.name).toEqual('dogpark'); - expect(transaction.metadata.source).toEqual('route'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); }); it("sets source to be `'custom'` in constructor if not provided", () => { const transaction = new Transaction({ name: 'dogpark' }); expect(transaction.name).toEqual('dogpark'); - expect(transaction.metadata.source).toBe('custom'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('custom'); }); it("sets source to `'custom'` when assigning to `name` property", () => { @@ -34,7 +37,7 @@ describe('`Transaction` class', () => { transaction.name = 'ballpit'; expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('custom'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('custom'); }); it('sets instrumenter to be `sentry` in constructor if not provided', () => { @@ -55,7 +58,7 @@ describe('`Transaction` class', () => { transaction.setName('ballpit'); expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('custom'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('custom'); }); it('uses given `source` value', () => { @@ -63,7 +66,7 @@ describe('`Transaction` class', () => { transaction.setName('ballpit', 'route'); expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('route'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); }); }); @@ -74,7 +77,7 @@ describe('`Transaction` class', () => { transaction.updateName('ballpit'); expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('route'); + expect(transaction.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); }); }); }); @@ -170,6 +173,7 @@ describe('`Transaction` class', () => { data: { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, span_id: transaction.spanId, trace_id: transaction.traceId, @@ -201,6 +205,7 @@ describe('`Transaction` class', () => { data: { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, span_id: transaction.spanId, trace_id: transaction.traceId, diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index 69704d497b8f..f9e29a188327 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -2,7 +2,7 @@ import type { TraceContext } from './context'; import type { Instrumenter } from './instrumenter'; import type { Primitive } from './misc'; import type { HrTime } from './opentelemetry'; -import type { Transaction } from './transaction'; +import type { Transaction, TransactionSource } from './transaction'; type SpanOriginType = 'manual' | 'auto'; type SpanOriginCategory = string; // e.g. http, db, ui, .... @@ -26,7 +26,7 @@ export type SpanAttributeValue = export type SpanAttributes = Partial<{ 'sentry.origin': string; 'sentry.op': string; - 'sentry.source': string; + 'sentry.source': TransactionSource; 'sentry.sample_rate': number; }> & Record; diff --git a/packages/types/src/transaction.ts b/packages/types/src/transaction.ts index 49b92b2e218a..df22d28de7fc 100644 --- a/packages/types/src/transaction.ts +++ b/packages/types/src/transaction.ts @@ -109,7 +109,7 @@ export interface Transaction extends TransactionContext, Omit