diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index d5cc61b73e95..a66c942076b1 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { captureException, continueTrace, @@ -119,9 +119,11 @@ async function instrumentRequest( const res = await startSpan( { ...traceCtx, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.astro', + }, name: `${method} ${interpolatedRoute || ctx.url.pathname}`, op: 'http.server', - origin: 'auto.http.astro', status: 'ok', metadata: { // eslint-disable-next-line deprecation/deprecation diff --git a/packages/astro/test/server/middleware.test.ts b/packages/astro/test/server/middleware.test.ts index 9fa5bc430c90..c641f5ac6177 100644 --- a/packages/astro/test/server/middleware.test.ts +++ b/packages/astro/test/server/middleware.test.ts @@ -58,6 +58,9 @@ describe('sentryMiddleware', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + attributes: { + 'sentry.origin': 'auto.http.astro', + }, data: { method: 'GET', url: 'https://mydomain.io/users/123/details', @@ -66,7 +69,6 @@ describe('sentryMiddleware', () => { metadata: {}, name: 'GET /users/[id]/details', op: 'http.server', - origin: 'auto.http.astro', status: 'ok', }, expect.any(Function), // the `next` function @@ -94,6 +96,9 @@ describe('sentryMiddleware', () => { expect(startSpanSpy).toHaveBeenCalledWith( { + attributes: { + 'sentry.origin': 'auto.http.astro', + }, data: { method: 'GET', url: 'http://localhost:1234/a%xx', @@ -102,7 +107,6 @@ describe('sentryMiddleware', () => { metadata: {}, name: 'GET a%xx', op: 'http.server', - origin: 'auto.http.astro', status: 'ok', }, expect.any(Function), // the `next` function diff --git a/packages/bun/src/integrations/bunserver.ts b/packages/bun/src/integrations/bunserver.ts index fb12cf94432b..aa8765638647 100644 --- a/packages/bun/src/integrations/bunserver.ts +++ b/packages/bun/src/integrations/bunserver.ts @@ -1,4 +1,5 @@ import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Transaction, captureException, @@ -69,9 +70,11 @@ function instrumentBunServeOptions(serveOptions: Parameters[0] ctx => { return startSpan( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.bun.serve', + }, op: 'http.server', name: `${request.method} ${parsedUrl.path || '/'}`, - origin: 'auto.http.bun.serve', ...ctx, data, metadata: { diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts index 8ddfddb3b353..a52d6bd5e9c8 100644 --- a/packages/core/src/tracing/span.ts +++ b/packages/core/src/tracing/span.ts @@ -130,11 +130,15 @@ export class Span implements SpanInterface { this.tags = spanContext.tags ? { ...spanContext.tags } : {}; // eslint-disable-next-line deprecation/deprecation this.data = spanContext.data ? { ...spanContext.data } : {}; - this._attributes = spanContext.attributes ? { ...spanContext.attributes } : {}; // eslint-disable-next-line deprecation/deprecation this.instrumenter = spanContext.instrumenter || 'sentry'; - this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanContext.origin || 'manual'); + this._attributes = {}; + this.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanContext.origin || 'manual', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op, + ...spanContext.attributes, + }); // eslint-disable-next-line deprecation/deprecation this._name = spanContext.name || spanContext.description; @@ -146,9 +150,6 @@ export class Span implements SpanInterface { if ('sampled' in spanContext) { this._sampled = spanContext.sampled; } - if (spanContext.op) { - this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, spanContext.op); - } if (spanContext.status) { this._status = spanContext.status; } diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index eb070510a3b7..bb92373d3e58 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -20,7 +20,7 @@ import { handleCallbackErrors } from '../utils/handleCallbackErrors'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; import { spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils'; -interface StartSpanOptions extends TransactionContext { +interface StartSpanOptions extends Omit { /** A manually specified start time for the created `Span` object. */ startTime?: SpanTimeInput; @@ -33,7 +33,11 @@ interface StartSpanOptions extends TransactionContext { /** An op for the span. This is a categorization for spans. */ op?: string; - /** The origin of the span - if it comes from auto instrumenation or manual instrumentation. */ + /** + * The origin of the span - if it comes from auto instrumentation or manual instrumentation. + * + * @deprecated Set `attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]` instead. + */ origin?: SpanOrigin; /** Attributes for the span. */ diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index a2bdac43b6dd..cc11793fc07e 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -229,6 +229,40 @@ describe('startSpan', () => { expect(ref.spanRecorder.spans).toHaveLength(2); expect(spanToJSON(ref.spanRecorder.spans[1]).op).toEqual('db.query'); }); + + it.each([ + { origin: 'auto.http.browser' }, + { attributes: { 'sentry.origin': 'auto.http.browser' } }, + // attribute should take precedence over top level origin + { origin: 'manual', attributes: { 'sentry.origin': 'auto.http.browser' } }, + ])('correctly sets the span origin', async () => { + let ref: any = undefined; + client.on('finishTransaction', transaction => { + ref = transaction; + }); + try { + await startSpan({ name: 'GET users/[id]', origin: 'auto.http.browser' }, () => { + return callback(); + }); + } catch (e) { + // + } + + const jsonSpan = spanToJSON(ref); + expect(jsonSpan).toEqual({ + data: { + 'sentry.origin': 'auto.http.browser', + 'sentry.sample_rate': 0, + }, + origin: 'auto.http.browser', + description: 'GET users/[id]', + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: isError ? 'internal_error' : undefined, + timestamp: expect.any(Number), + trace_id: expect.any(String), + }); + }); }); it('creates & finishes span', async () => { diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index 4f1f399654e4..b3ccfffa404f 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -5,7 +5,7 @@ import { getOwnConfig, isDevelopingApp, macroCondition } from '@embroider/macros import { startSpan } from '@sentry/browser'; import type { BrowserOptions } from '@sentry/browser'; import * as Sentry from '@sentry/browser'; -import { applySdkMetadata } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, applySdkMetadata } from '@sentry/core'; import { GLOBAL_OBJ } from '@sentry/utils'; import Ember from 'ember'; @@ -82,9 +82,11 @@ export const instrumentRoutePerformance = (BaseRoute ): Promise> => { return startSpan( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'ember', + }, op, name: description, - origin: 'auto.ui.ember', }, () => { return fn(...args); diff --git a/packages/ember/addon/instance-initializers/sentry-performance.ts b/packages/ember/addon/instance-initializers/sentry-performance.ts index b25125b28da6..acabe5334cad 100644 --- a/packages/ember/addon/instance-initializers/sentry-performance.ts +++ b/packages/ember/addon/instance-initializers/sentry-performance.ts @@ -11,6 +11,7 @@ import type { ExtendedBackburner } from '@sentry/ember/runloop'; import type { Span, Transaction } from '@sentry/types'; import { GLOBAL_OBJ, browserPerformanceTimeOrigin, timestampInSeconds } from '@sentry/utils'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import type { BrowserClient } from '..'; import { getActiveSpan, startInactiveSpan } from '..'; import type { EmberRouterMain, EmberSentryConfig, GlobalConfig, OwnConfig, StartTransactionFunction } from '../types'; @@ -150,9 +151,11 @@ export function _instrumentEmberRouter( }, }); transitionSpan = startInactiveSpan({ + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.ember', + }, op: 'ui.ember.transition', name: `route:${fromRoute} -> route:${toRoute}`, - origin: 'auto.ui.ember', }); }); @@ -212,9 +215,11 @@ function _instrumentEmberRunloop(config: EmberSentryConfig): void { if ((now - currentQueueStart) * 1000 >= minQueueDuration) { startInactiveSpan({ + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.ember', + }, name: 'runloop', op: `ui.ember.runloop.${queue}`, - origin: 'auto.ui.ember', startTimestamp: currentQueueStart, })?.end(now); } @@ -370,7 +375,9 @@ function _instrumentInitialLoad(config: EmberSentryConfig): void { startInactiveSpan({ op: 'ui.ember.init', name: 'init', - origin: 'auto.ui.ember', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.ember', + }, startTimestamp, })?.end(endTimestamp); performance.clearMarks(startName); diff --git a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts index 59114ddee709..109a586d7cd6 100644 --- a/packages/nextjs/src/common/utils/edgeWrapperUtils.ts +++ b/packages/nextjs/src/common/utils/edgeWrapperUtils.ts @@ -1,4 +1,5 @@ import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addTracingExtensions, captureException, @@ -40,8 +41,10 @@ export function withEdgeWrapping( ...transactionContext, name: options.spanDescription, op: options.spanOp, - origin: 'auto.function.nextjs.withEdgeWrapping', - attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.withEdgeWrapping', + }, metadata: { // eslint-disable-next-line deprecation/deprecation ...transactionContext.metadata, diff --git a/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts index 16228aa0cda8..91c95e264875 100644 --- a/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/common/wrapApiHandlerWithSentry.ts @@ -9,6 +9,7 @@ import { } from '@sentry/core'; import { consoleSandbox, isString, logger, objectify, stripUrlQueryAndFragment } from '@sentry/utils'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import type { AugmentedNextApiRequest, AugmentedNextApiResponse, NextApiHandler } from './types'; import { platformSupportsStreaming } from './utils/platformSupportsStreaming'; import { flushQueue } from './utils/responseEnd'; @@ -108,9 +109,9 @@ export function withSentry(apiHandler: NextApiHandler, parameterizedRoute?: stri ...transactionContext, name: `${reqMethod}${reqPath}`, op: 'http.server', - origin: 'auto.http.nextjs', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nextjs', }, metadata: { // eslint-disable-next-line deprecation/deprecation diff --git a/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts b/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts index f2e829704dd6..5e6a051ffcfb 100644 --- a/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts +++ b/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts @@ -12,6 +12,7 @@ import { import type { WebFetchHeaders } from '@sentry/types'; import { winterCGHeadersToDict } from '@sentry/utils'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import type { GenerationFunctionContext } from '../common/types'; import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils'; import { commonObjectToPropagationContext } from './utils/commonObjectTracing'; @@ -67,11 +68,11 @@ export function wrapGenerationFunctionWithSentry a { op: 'function.nextjs', name: `${componentType}.${generationFunctionIdentifier} (${componentRoute})`, - origin: 'auto.function.nextjs', ...transactionContext, data, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs', }, metadata: { // eslint-disable-next-line deprecation/deprecation diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index a0a1ae2f77aa..f8b6c5698550 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -10,6 +10,7 @@ import { } from '@sentry/core'; import { winterCGHeadersToDict } from '@sentry/utils'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { isNotFoundNavigationError, isRedirectNavigationError } from '../common/nextNavigationErrorUtils'; import type { ServerComponentContext } from '../common/types'; import { commonObjectToPropagationContext } from './utils/commonObjectTracing'; @@ -61,9 +62,9 @@ export function wrapServerComponentWithSentry any> op: 'function.nextjs', name: `${componentType} Server Component (${componentRoute})`, status: 'ok', - origin: 'auto.function.nextjs', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs', }, metadata: { // eslint-disable-next-line deprecation/deprecation diff --git a/packages/nextjs/test/config/withSentry.test.ts b/packages/nextjs/test/config/withSentry.test.ts index 91b61516a240..1ae933549b17 100644 --- a/packages/nextjs/test/config/withSentry.test.ts +++ b/packages/nextjs/test/config/withSentry.test.ts @@ -1,5 +1,5 @@ import * as SentryCore from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addTracingExtensions } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, addTracingExtensions } from '@sentry/core'; import type { NextApiRequest, NextApiResponse } from 'next'; import type { AugmentedNextApiResponse, NextApiHandler } from '../../src/common/types'; @@ -44,9 +44,9 @@ describe('withSentry', () => { { name: 'GET http://dogs.are.great', op: 'http.server', - origin: 'auto.http.nextjs', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nextjs', }, metadata: { request: expect.objectContaining({ url: 'http://dogs.are.great' }), diff --git a/packages/nextjs/test/edge/edgeWrapperUtils.test.ts b/packages/nextjs/test/edge/edgeWrapperUtils.test.ts index 97d6e7b103e1..495e6336e2cd 100644 --- a/packages/nextjs/test/edge/edgeWrapperUtils.test.ts +++ b/packages/nextjs/test/edge/edgeWrapperUtils.test.ts @@ -87,10 +87,10 @@ describe('withEdgeWrapping', () => { }, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [coreSdk.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.withEdgeWrapping', }, name: 'some label', op: 'some op', - origin: 'auto.function.nextjs.withEdgeWrapping', }), expect.any(Function), ); diff --git a/packages/nextjs/test/edge/withSentryAPI.test.ts b/packages/nextjs/test/edge/withSentryAPI.test.ts index ea5e7c4319f0..071bdda93952 100644 --- a/packages/nextjs/test/edge/withSentryAPI.test.ts +++ b/packages/nextjs/test/edge/withSentryAPI.test.ts @@ -1,5 +1,5 @@ import * as coreSdk from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { wrapApiHandlerWithSentry } from '../../src/edge'; @@ -58,10 +58,10 @@ describe('wrapApiHandlerWithSentry', () => { }, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.withEdgeWrapping', }, name: 'POST /user/[userId]/post/[postId]', op: 'http.server', - origin: 'auto.function.nextjs.withEdgeWrapping', }), expect.any(Function), ); @@ -80,10 +80,10 @@ describe('wrapApiHandlerWithSentry', () => { metadata: {}, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [coreSdk.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.withEdgeWrapping', }, name: 'handler (/user/[userId]/post/[postId])', op: 'http.server', - origin: 'auto.function.nextjs.withEdgeWrapping', }), expect.any(Function), ); diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 22171153a534..f90e9dfabd77 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -1,5 +1,6 @@ /* eslint-disable max-lines */ import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getActiveSpan, getActiveTransaction, getClient, @@ -411,7 +412,9 @@ export function startRequestHandlerTransaction( const transaction = hub.startTransaction({ name, op: 'http.server', - origin: 'auto.http.remix', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.remix', + }, tags: { method: request.method, }, diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts index e51ecd56fa4d..89086e7a1c77 100644 --- a/packages/serverless/src/awslambda.ts +++ b/packages/serverless/src/awslambda.ts @@ -23,7 +23,7 @@ import { isString, logger } from '@sentry/utils'; import type { Context, Handler } from 'aws-lambda'; import { performance } from 'perf_hooks'; -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { AWSServices } from './awsservices'; import { DEBUG_BUILD } from './debug-build'; import { markEventUnhandled } from './utils'; @@ -361,10 +361,10 @@ export function wrapHandler( { name: context.functionName, op: 'function.aws.lambda', - origin: 'auto.function.serverless', ...continueTraceContext, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, }, span => { diff --git a/packages/serverless/src/awsservices.ts b/packages/serverless/src/awsservices.ts index 8992b7a7adb0..36a789c52632 100644 --- a/packages/serverless/src/awsservices.ts +++ b/packages/serverless/src/awsservices.ts @@ -1,3 +1,4 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { startInactiveSpan } from '@sentry/node'; import type { Integration, Span } from '@sentry/types'; import { fill } from '@sentry/utils'; @@ -62,7 +63,9 @@ function wrapMakeRequest( span = startInactiveSpan({ name: describe(this, operation, params), op: 'http.client', - origin: 'auto.http.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, }); }); req.on('complete', () => { diff --git a/packages/serverless/src/gcpfunction/cloud_events.ts b/packages/serverless/src/gcpfunction/cloud_events.ts index 92a3eb0e37e7..533c74bb7653 100644 --- a/packages/serverless/src/gcpfunction/cloud_events.ts +++ b/packages/serverless/src/gcpfunction/cloud_events.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, handleCallbackErrors } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, handleCallbackErrors } from '@sentry/core'; import { captureException, flush, getCurrentScope, startSpanManual } from '@sentry/node'; import { logger } from '@sentry/utils'; @@ -35,8 +35,10 @@ function _wrapCloudEventFunction( { name: context.type || '', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', - attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', + }, }, span => { const scope = getCurrentScope(); diff --git a/packages/serverless/src/gcpfunction/events.ts b/packages/serverless/src/gcpfunction/events.ts index 79c609e9108c..501b6f7d6da3 100644 --- a/packages/serverless/src/gcpfunction/events.ts +++ b/packages/serverless/src/gcpfunction/events.ts @@ -1,4 +1,4 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, handleCallbackErrors } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, handleCallbackErrors } from '@sentry/core'; import { captureException, flush, getCurrentScope, startSpanManual } from '@sentry/node'; import { logger } from '@sentry/utils'; @@ -38,8 +38,10 @@ function _wrapEventFunction { name: context.eventType, op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', - attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component' }, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', + }, }, span => { const scope = getCurrentScope(); diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts index 41fa620779c7..84e3627477cd 100644 --- a/packages/serverless/src/gcpfunction/http.ts +++ b/packages/serverless/src/gcpfunction/http.ts @@ -1,4 +1,9 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Transaction, handleCallbackErrors } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + Transaction, + handleCallbackErrors, +} from '@sentry/core'; import type { AddRequestDataToEventOptions } from '@sentry/node'; import { continueTrace, startSpanManual } from '@sentry/node'; import { getCurrentScope } from '@sentry/node'; @@ -78,9 +83,9 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial { diff --git a/packages/serverless/src/google-cloud-grpc.ts b/packages/serverless/src/google-cloud-grpc.ts index 458af78872f7..ba2ddb038a03 100644 --- a/packages/serverless/src/google-cloud-grpc.ts +++ b/packages/serverless/src/google-cloud-grpc.ts @@ -1,4 +1,5 @@ import type { EventEmitter } from 'events'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { startInactiveSpan } from '@sentry/node'; import type { Integration } from '@sentry/types'; import { fill } from '@sentry/utils'; @@ -110,7 +111,9 @@ function fillGrpcFunction(stub: Stub, serviceIdentifier: string, methodName: str const span = startInactiveSpan({ name: `${callType} ${methodName}`, op: `grpc.${serviceIdentifier}`, - origin: 'auto.grpc.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.grpc.serverless', + }, }); ret.on('status', () => { if (span) { diff --git a/packages/serverless/src/google-cloud-http.ts b/packages/serverless/src/google-cloud-http.ts index 369fa6ad230d..769519013785 100644 --- a/packages/serverless/src/google-cloud-http.ts +++ b/packages/serverless/src/google-cloud-http.ts @@ -1,6 +1,7 @@ // '@google-cloud/common' import is expected to be type-only so it's erased in the final .js file. // When TypeScript compiler is upgraded, use `import type` syntax to explicitly assert that we don't want to load a module here. import type * as common from '@google-cloud/common'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { startInactiveSpan } from '@sentry/node'; import type { Integration } from '@sentry/types'; import { fill } from '@sentry/utils'; @@ -55,7 +56,9 @@ function wrapRequestFunction(orig: RequestFunction): RequestFunction { const span = startInactiveSpan({ name: `${httpMethod} ${reqOpts.uri}`, op: `http.client.${identifyService(this.apiEndpoint)}`, - origin: 'auto.http.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, }); orig.call(this, reqOpts, (...args: Parameters) => { if (span) { diff --git a/packages/serverless/test/awslambda.test.ts b/packages/serverless/test/awslambda.test.ts index 0d923074067f..de851cda8bbb 100644 --- a/packages/serverless/test/awslambda.test.ts +++ b/packages/serverless/test/awslambda.test.ts @@ -1,5 +1,5 @@ // NOTE: I have no idea how to fix this right now, and don't want to waste more time, as it builds just fine — Kamil -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import * as SentryNode from '@sentry/node'; import type { Event } from '@sentry/types'; import type { Callback, Handler } from 'aws-lambda'; @@ -206,9 +206,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; @@ -236,9 +236,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; @@ -278,11 +278,11 @@ describe('AWSLambda', () => { parentSpanId: '1121201211212012', parentSampled: false, op: 'function.aws.lambda', - origin: 'auto.function.serverless', name: 'functionName', traceId: '12312012123120121231201212312012', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: { dynamicSamplingContext: { @@ -316,12 +316,12 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', traceId: '12312012123120121231201212312012', parentSpanId: '1121201211212012', parentSampled: false, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: { dynamicSamplingContext: {} }, }; @@ -349,9 +349,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; @@ -390,9 +390,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; @@ -435,9 +435,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; @@ -476,9 +476,9 @@ describe('AWSLambda', () => { const fakeTransactionContext = { name: 'functionName', op: 'function.aws.lambda', - origin: 'auto.function.serverless', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless', }, metadata: {}, }; diff --git a/packages/serverless/test/awsservices.test.ts b/packages/serverless/test/awsservices.test.ts index 16464e315fa6..b18b1d8dd9af 100644 --- a/packages/serverless/test/awsservices.test.ts +++ b/packages/serverless/test/awsservices.test.ts @@ -2,6 +2,7 @@ import * as SentryNode from '@sentry/node'; import * as AWS from 'aws-sdk'; import * as nock from 'nock'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { AWSServices } from '../src/awsservices'; describe('AWSServices', () => { @@ -25,7 +26,9 @@ describe('AWSServices', () => { expect(data.Body?.toString('utf-8')).toEqual('contents'); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', - origin: 'auto.http.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, name: 'aws.s3.getObject foo', }); // @ts-expect-error see "Why @ts-expect-error" note @@ -42,8 +45,10 @@ describe('AWSServices', () => { }); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', - origin: 'auto.http.serverless', name: 'aws.s3.getObject foo', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, }); }); }); @@ -57,7 +62,9 @@ describe('AWSServices', () => { expect(data.Payload?.toString('utf-8')).toEqual('reply'); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client', - origin: 'auto.http.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, name: 'aws.lambda.invoke foo', }); }); diff --git a/packages/serverless/test/gcpfunction.test.ts b/packages/serverless/test/gcpfunction.test.ts index 29cfe0541a0c..8fb51d3bf368 100644 --- a/packages/serverless/test/gcpfunction.test.ts +++ b/packages/serverless/test/gcpfunction.test.ts @@ -2,7 +2,7 @@ import * as domain from 'domain'; import * as SentryNode from '@sentry/node'; import type { Event, Integration } from '@sentry/types'; -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import * as Sentry from '../src'; import { wrapCloudEventFunction, wrapEventFunction, wrapHttpFunction } from '../src/gcpfunction'; import type { @@ -105,9 +105,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'POST /path', op: 'function.gcp.http', - origin: 'auto.function.serverless.gcp_http', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_http', }, metadata: {}, }; @@ -135,12 +135,12 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'POST /path', op: 'function.gcp.http', - origin: 'auto.function.serverless.gcp_http', traceId: '12312012123120121231201212312012', parentSpanId: '1121201211212012', parentSampled: false, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_http', }, metadata: { dynamicSamplingContext: { @@ -168,12 +168,12 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'POST /path', op: 'function.gcp.http', - origin: 'auto.function.serverless.gcp_http', traceId: '12312012123120121231201212312012', parentSpanId: '1121201211212012', parentSampled: false, attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_http', }, metadata: { dynamicSamplingContext: {} }, }; @@ -253,9 +253,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -276,9 +276,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -304,9 +304,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -331,9 +331,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -356,9 +356,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -379,9 +379,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -403,9 +403,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.event', - origin: 'auto.function.serverless.gcp_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_event', }, }; @@ -460,9 +460,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', }, }; @@ -483,9 +483,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', }, }; @@ -508,9 +508,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', }, }; @@ -531,9 +531,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', }, }; @@ -555,9 +555,9 @@ describe('GCPFunction', () => { const fakeTransactionContext = { name: 'event.type', op: 'function.gcp.cloud_event', - origin: 'auto.function.serverless.gcp_cloud_event', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_cloud_event', }, }; diff --git a/packages/serverless/test/google-cloud-grpc.test.ts b/packages/serverless/test/google-cloud-grpc.test.ts index 39ebb4a54ecd..8c0e0866bf0c 100644 --- a/packages/serverless/test/google-cloud-grpc.test.ts +++ b/packages/serverless/test/google-cloud-grpc.test.ts @@ -9,6 +9,7 @@ import * as SentryNode from '@sentry/node'; import * as http2 from 'http2'; import * as nock from 'nock'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { GoogleCloudGrpc } from '../src/google-cloud-grpc'; const spyConnect = jest.spyOn(http2, 'connect'); @@ -121,7 +122,9 @@ describe('GoogleCloudGrpc tracing', () => { expect(resp).toEqual('1637084156623860'); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'grpc.pubsub', - origin: 'auto.grpc.serverless', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.grpc.serverless', + }, name: 'unary call publish', }); await pubsub.close(); diff --git a/packages/serverless/test/google-cloud-http.test.ts b/packages/serverless/test/google-cloud-http.test.ts index 0ef1466647a5..748841e58579 100644 --- a/packages/serverless/test/google-cloud-http.test.ts +++ b/packages/serverless/test/google-cloud-http.test.ts @@ -4,6 +4,7 @@ import { BigQuery } from '@google-cloud/bigquery'; import * as SentryNode from '@sentry/node'; import * as nock from 'nock'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { GoogleCloudHttp } from '../src/google-cloud-http'; describe('GoogleCloudHttp tracing', () => { @@ -52,13 +53,17 @@ describe('GoogleCloudHttp tracing', () => { expect(resp).toEqual([[{ foo: true }]]); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client.bigquery', - origin: 'auto.http.serverless', name: 'POST /jobs', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, }); expect(SentryNode.startInactiveSpan).toBeCalledWith({ op: 'http.client.bigquery', - origin: 'auto.http.serverless', name: expect.stringMatching(/^GET \/queries\/.+/), + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.serverless', + }, }); }); }); diff --git a/packages/sveltekit/src/client/load.ts b/packages/sveltekit/src/client/load.ts index 545105e49c43..14528959d34e 100644 --- a/packages/sveltekit/src/client/load.ts +++ b/packages/sveltekit/src/client/load.ts @@ -1,4 +1,4 @@ -import { handleCallbackErrors, startSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, handleCallbackErrors, startSpan } from '@sentry/core'; import { captureException } from '@sentry/svelte'; import { addNonEnumerableProperty, objectify } from '@sentry/utils'; import type { LoadEvent } from '@sveltejs/kit'; @@ -80,7 +80,9 @@ export function wrapLoadWithSentry any>(origLoad: T) return startSpan( { op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, name: routeId ? routeId : event.url.pathname, status: 'ok', metadata: { diff --git a/packages/sveltekit/src/server/handle.ts b/packages/sveltekit/src/server/handle.ts index 1bb0c485168e..5572e64060d3 100644 --- a/packages/sveltekit/src/server/handle.ts +++ b/packages/sveltekit/src/server/handle.ts @@ -1,4 +1,10 @@ -import { getActiveSpan, getCurrentScope, getDynamicSamplingContextFromSpan, spanToTraceHeader } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + getActiveSpan, + getCurrentScope, + getDynamicSamplingContextFromSpan, + spanToTraceHeader, +} from '@sentry/core'; import { getActiveTransaction, runWithAsyncContext, startSpan } from '@sentry/core'; import { captureException } from '@sentry/node'; /* eslint-disable @sentry-internal/sdk/no-optional-chaining */ @@ -169,7 +175,9 @@ async function instrumentHandle( const resolveResult = await startSpan( { op: 'http.server', - origin: 'auto.http.sveltekit', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.sveltekit', + }, name: `${event.request.method} ${event.route?.id || event.url.pathname}`, status: 'ok', ...traceparentData, diff --git a/packages/sveltekit/src/server/load.ts b/packages/sveltekit/src/server/load.ts index 5d0cd3c1cb90..9728dcf47b5b 100644 --- a/packages/sveltekit/src/server/load.ts +++ b/packages/sveltekit/src/server/load.ts @@ -1,10 +1,10 @@ /* eslint-disable @sentry-internal/sdk/no-optional-chaining */ -import { getCurrentScope, startSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getCurrentScope, startSpan } from '@sentry/core'; import { captureException } from '@sentry/node'; -import type { TransactionContext } from '@sentry/types'; import { addNonEnumerableProperty, objectify } from '@sentry/utils'; import type { LoadEvent, ServerLoadEvent } from '@sveltejs/kit'; +import type { TransactionContext } from '@sentry/types'; import type { SentryWrappedFlag } from '../common/utils'; import { isHttpError, isRedirect } from '../common/utils'; import { flushIfServerless, getTracePropagationData } from './utils'; @@ -67,7 +67,9 @@ export function wrapLoadWithSentry any>(origLoad: T) const traceLoadContext: TransactionContext = { op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, name: routeId ? routeId : event.url.pathname, status: 'ok', metadata: { @@ -134,7 +136,9 @@ export function wrapServerLoadWithSentry any>(origSe const traceLoadContext: TransactionContext = { op: 'function.sveltekit.server.load', - origin: 'auto.function.sveltekit', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, name: routeId ? routeId : event.url.pathname, status: 'ok', metadata: { diff --git a/packages/sveltekit/test/client/load.test.ts b/packages/sveltekit/test/client/load.test.ts index 15d2850b4a8c..e839b5a9cba5 100644 --- a/packages/sveltekit/test/client/load.test.ts +++ b/packages/sveltekit/test/client/load.test.ts @@ -3,6 +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 { wrapLoadWithSentry } from '../../src/client/load'; const mockCaptureException = vi.spyOn(SentrySvelte, 'captureException').mockImplementation(() => 'xx'); @@ -82,8 +83,10 @@ describe('wrapLoadWithSentry', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', name: '/users/[id]', status: 'ok', metadata: { @@ -110,8 +113,10 @@ describe('wrapLoadWithSentry', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', name: '/users/123', status: 'ok', metadata: { diff --git a/packages/sveltekit/test/server/load.test.ts b/packages/sveltekit/test/server/load.test.ts index 6b86ca6b32f6..2656b22f685a 100644 --- a/packages/sveltekit/test/server/load.test.ts +++ b/packages/sveltekit/test/server/load.test.ts @@ -1,4 +1,4 @@ -import { addTracingExtensions } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, addTracingExtensions } from '@sentry/core'; import * as SentryNode from '@sentry/node'; import type { Load, ServerLoad } from '@sveltejs/kit'; import { error, redirect } from '@sveltejs/kit'; @@ -197,8 +197,10 @@ describe('wrapLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', name: '/users/[id]', status: 'ok', metadata: { @@ -216,8 +218,10 @@ describe('wrapLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.load', - origin: 'auto.function.sveltekit', name: '/users/123', status: 'ok', metadata: { @@ -250,8 +254,10 @@ describe('wrapServerLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.server.load', - origin: 'auto.function.sveltekit', name: '/users/[id]', parentSampled: true, parentSpanId: '1234567890abcdef', @@ -284,8 +290,10 @@ describe('wrapServerLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.server.load', - origin: 'auto.function.sveltekit', name: '/users/[id]', status: 'ok', data: { @@ -306,8 +314,10 @@ describe('wrapServerLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.server.load', - origin: 'auto.function.sveltekit', name: '/users/[id]', parentSampled: true, parentSpanId: '1234567890abcdef', @@ -335,8 +345,10 @@ describe('wrapServerLoadWithSentry calls trace', () => { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenCalledWith( { + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.sveltekit', + }, op: 'function.sveltekit.server.load', - origin: 'auto.function.sveltekit', name: '/users/123', parentSampled: true, parentSpanId: '1234567890abcdef', diff --git a/packages/tracing-internal/src/browser/request.ts b/packages/tracing-internal/src/browser/request.ts index c84d0545054b..d2600f02629e 100644 --- a/packages/tracing-internal/src/browser/request.ts +++ b/packages/tracing-internal/src/browser/request.ts @@ -1,5 +1,6 @@ /* eslint-disable max-lines */ import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getClient, getCurrentScope, getDynamicSamplingContextFromClient, @@ -282,10 +283,10 @@ export function xhrCallback( type: 'xhr', 'http.method': sentryXhrData.method, url: sentryXhrData.url, + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser', }, name: `${sentryXhrData.method} ${sentryXhrData.url}`, op: 'http.client', - origin: 'auto.http.browser', }) : undefined; diff --git a/packages/tracing-internal/src/common/fetch.ts b/packages/tracing-internal/src/common/fetch.ts index c96778f8cd35..8f9da76488ad 100644 --- a/packages/tracing-internal/src/common/fetch.ts +++ b/packages/tracing-internal/src/common/fetch.ts @@ -1,4 +1,5 @@ import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getClient, getCurrentScope, getDynamicSamplingContextFromClient, @@ -85,10 +86,10 @@ export function instrumentFetchRequest( url, type: 'fetch', 'http.method': method, + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin, }, name: `${method} ${url}`, op: 'http.client', - origin: spanOrigin, }) : undefined; diff --git a/packages/tracing-internal/src/node/integrations/prisma.ts b/packages/tracing-internal/src/node/integrations/prisma.ts index f51bcd6eef32..4399778f1e80 100644 --- a/packages/tracing-internal/src/node/integrations/prisma.ts +++ b/packages/tracing-internal/src/node/integrations/prisma.ts @@ -1,4 +1,4 @@ -import { getCurrentHub, startSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getCurrentHub, startSpan } from '@sentry/core'; import type { Integration } from '@sentry/types'; import { addNonEnumerableProperty, logger } from '@sentry/utils'; @@ -104,7 +104,9 @@ export class Prisma implements Integration { { name: model ? `${model} ${action}` : action, op: 'db.prisma', - origin: 'auto.db.prisma', + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.prisma', + }, data: { ...clientData, 'db.operation': action }, }, () => next(params), diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts index 7b73d9bb2d51..02841dbd5aca 100644 --- a/packages/tracing/test/hub.test.ts +++ b/packages/tracing/test/hub.test.ts @@ -305,8 +305,8 @@ describe('Hub', () => { makeMain(hub); hub.startTransaction({ name: 'dogpark', parentSampled: true }); - // length 1 because `sentry.origin` is set on span initialization - expect(Transaction.prototype.setAttribute).toHaveBeenCalledTimes(1); + // length 2 because origin and op are set as attributes on span initialization + expect(Transaction.prototype.setAttribute).toHaveBeenCalledTimes(2); }); it('should record sampling method and rate when sampling decision comes from traceSampleRate', () => { diff --git a/packages/tracing/test/integrations/node/prisma.test.ts b/packages/tracing/test/integrations/node/prisma.test.ts index 552edb1b78c2..c86f8aecabe2 100644 --- a/packages/tracing/test/integrations/node/prisma.test.ts +++ b/packages/tracing/test/integrations/node/prisma.test.ts @@ -54,9 +54,11 @@ describe('setupOnce', function () { expect(mockStartSpan).toHaveBeenCalledTimes(1); expect(mockStartSpan).toHaveBeenLastCalledWith( { + attributes: { + 'sentry.origin': 'auto.db.prisma', + }, name: 'user create', op: 'db.prisma', - origin: 'auto.db.prisma', data: { 'db.system': 'postgresql', 'db.prisma.version': '3.1.2', 'db.operation': 'create' }, }, expect.any(Function),