Skip to content

Commit fb7e516

Browse files
authored
feat(core): Deprecate Span.op in favor of op attribute (#10189)
Deprecate `Span.op` in favour of: - `spanToJson` to get the span op - `startSpan` functions to set the initial span op - `setAttribute('SEMANTIC_ATTRIBUTE_SENTRY_OP', ...)` to update the span op Going forward, the span op will become a semantic, Sentry-specific span attribute. With this PR we already set, get and update the attribute but still provide the deprecated `op` getter and setter for v7 backwards compatibility.
1 parent 64ba9ec commit fb7e516

File tree

20 files changed

+101
-28
lines changed

20 files changed

+101
-28
lines changed

MIGRATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ In v8, the Span class is heavily reworked. The following properties & methods ar
205205
- `span.transaction`: Use `getRootSpan` utility function instead.
206206
- `span.spanRecorder`: Span recording will be handled internally by the SDK.
207207
- `span.status`: Use `.setStatus` to set or update and `spanToJSON()` to read the span status.
208+
- `span.op`: Use `startSpan` functions to set, `setAttribute()` to update and `spanToJSON` to read the span operation.
208209
- `transaction.setMetadata()`: Use attributes instead, or set data on the scope.
209210
- `transaction.metadata`: Use attributes instead, or set data on the scope.
210211
- `transaction.setContext()`: Set context on the surrounding scope instead.

dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/middleware.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru
6363
expect(middlewareTransaction.spans).toEqual(
6464
expect.arrayContaining([
6565
{
66-
data: { 'http.method': 'GET', 'http.response.status_code': 200, type: 'fetch', url: 'http://localhost:3030/' },
66+
data: {
67+
'http.method': 'GET',
68+
'http.response.status_code': 200,
69+
type: 'fetch',
70+
url: 'http://localhost:3030/',
71+
'sentry.op': 'http.client',
72+
},
6773
description: 'GET http://localhost:3030/',
6874
op: 'http.client',
6975
origin: 'auto.http.wintercg_fetch',

dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/propagation.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
6363
url: 'http://localhost:3030/test-outgoing-http',
6464
'otel.kind': 'SERVER',
6565
'http.response.status_code': 200,
66+
'sentry.op': 'http.server',
6667
},
6768
op: 'http.server',
6869
span_id: expect.any(String),
@@ -85,6 +86,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
8586
url: 'http://localhost:3030/test-inbound-headers',
8687
'otel.kind': 'SERVER',
8788
'http.response.status_code': 200,
89+
'sentry.op': 'http.server',
8890
},
8991
op: 'http.server',
9092
parent_span_id: outgoingHttpSpanId,
@@ -156,6 +158,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
156158
url: 'http://localhost:3030/test-outgoing-fetch',
157159
'otel.kind': 'SERVER',
158160
'http.response.status_code': 200,
161+
'sentry.op': 'http.server',
159162
},
160163
op: 'http.server',
161164
span_id: expect.any(String),
@@ -178,6 +181,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
178181
url: 'http://localhost:3030/test-inbound-headers',
179182
'otel.kind': 'SERVER',
180183
'http.response.status_code': 200,
184+
'sentry.op': 'http.server',
181185
},
182186
op: 'http.server',
183187
parent_span_id: outgoingHttpSpanId,

dev-packages/e2e-tests/test-applications/node-experimental-fastify-app/tests/transactions.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ test('Sends an API route transaction', async ({ baseURL }) => {
2828
url: 'http://localhost:3030/test-transaction',
2929
'otel.kind': 'SERVER',
3030
'http.response.status_code': 200,
31+
'sentry.op': 'http.server',
3132
},
3233
op: 'http.server',
3334
span_id: expect.any(String),

packages/core/src/semanticAttributes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';
99
* Use this attribute to represent the sample rate used for a span.
1010
*/
1111
export const SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate';
12+
13+
/**
14+
* Use this attribute to represent the operation of a span.
15+
*/
16+
export const SEMANTIC_ATTRIBUTE_SENTRY_OP = 'sentry.op';

packages/core/src/tracing/idletransaction.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,15 @@ export class IdleTransaction extends Transaction {
148148
this._finished = true;
149149
this.activities = {};
150150

151+
// eslint-disable-next-line deprecation/deprecation
151152
if (this.op === 'ui.action.click') {
152153
this.setAttribute(FINISH_REASON_TAG, this._finishReason);
153154
}
154155

155156
// eslint-disable-next-line deprecation/deprecation
156157
if (this.spanRecorder) {
157158
DEBUG_BUILD &&
159+
// eslint-disable-next-line deprecation/deprecation
158160
logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op);
159161

160162
for (const callback of this._beforeFinishCallbacks) {

packages/core/src/tracing/sampling.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export function sampleTransaction<T extends Transaction>(
9595
}
9696

9797
DEBUG_BUILD &&
98+
// eslint-disable-next-line deprecation/deprecation
9899
logger.log(`[Tracing] starting ${transaction.op} transaction - ${spanToJSON(transaction).description}`);
99100
return transaction;
100101
}

packages/core/src/tracing/span.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
import { dropUndefinedKeys, logger, timestampInSeconds, uuid4 } from '@sentry/utils';
1717

1818
import { DEBUG_BUILD } from '../debug-build';
19+
import { SEMANTIC_ATTRIBUTE_SENTRY_OP } from '../semanticAttributes';
1920
import { getRootSpan } from '../utils/getRootSpan';
2021
import {
2122
TRACE_FLAG_NONE,
@@ -67,11 +68,6 @@ export class Span implements SpanInterface {
6768
*/
6869
public parentSpanId?: string;
6970

70-
/**
71-
* @inheritDoc
72-
*/
73-
public op?: string;
74-
7571
/**
7672
* Tags for the span.
7773
* @deprecated Use `getSpanAttributes(span)` instead.
@@ -158,7 +154,7 @@ export class Span implements SpanInterface {
158154
this._sampled = spanContext.sampled;
159155
}
160156
if (spanContext.op) {
161-
this.op = spanContext.op;
157+
this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, spanContext.op);
162158
}
163159
if (spanContext.status) {
164160
this._status = spanContext.status;
@@ -317,6 +313,25 @@ export class Span implements SpanInterface {
317313
this._status = status;
318314
}
319315

316+
/**
317+
* Operation of the span
318+
*
319+
* @deprecated Use `spanToJSON().op` to read the op instead.
320+
*/
321+
public get op(): string | undefined {
322+
return this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] as string | undefined;
323+
}
324+
325+
/**
326+
* Operation of the span
327+
*
328+
* @deprecated Use `startSpan()` functions to set or `span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'op')
329+
* to update the span instead.
330+
*/
331+
public set op(op: string | undefined) {
332+
this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, op);
333+
}
334+
320335
/* eslint-enable @typescript-eslint/member-ordering */
321336

322337
/** @inheritdoc */
@@ -512,6 +527,7 @@ export class Span implements SpanInterface {
512527
data: this._getData(),
513528
description: this._name,
514529
endTimestamp: this._endTime,
530+
// eslint-disable-next-line deprecation/deprecation
515531
op: this.op,
516532
parentSpanId: this.parentSpanId,
517533
sampled: this._sampled,
@@ -535,6 +551,7 @@ export class Span implements SpanInterface {
535551
// eslint-disable-next-line deprecation/deprecation
536552
this._name = spanContext.name || spanContext.description;
537553
this._endTime = spanContext.endTimestamp;
554+
// eslint-disable-next-line deprecation/deprecation
538555
this.op = spanContext.op;
539556
this.parentSpanId = spanContext.parentSpanId;
540557
this._sampled = spanContext.sampled;
@@ -569,7 +586,7 @@ export class Span implements SpanInterface {
569586
return dropUndefinedKeys({
570587
data: this._getData(),
571588
description: this._name,
572-
op: this.op,
589+
op: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] as string | undefined,
573590
parent_span_id: this.parentSpanId,
574591
span_id: this._spanId,
575592
start_timestamp: this._startTime,

packages/core/src/tracing/transaction.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ export class Transaction extends SpanClass implements TransactionInterface {
344344
transaction.measurements = this._measurements;
345345
}
346346

347+
// eslint-disable-next-line deprecation/deprecation
347348
DEBUG_BUILD && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this._name}.`);
348349

349350
return transaction;

packages/core/test/lib/utils/spanUtils.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ describe('spanToJSON', () => {
8787
origin: 'auto',
8888
start_timestamp: 123,
8989
timestamp: 456,
90+
data: {
91+
'sentry.op': 'test op',
92+
},
9093
});
9194
});
9295

0 commit comments

Comments
 (0)