Skip to content

Commit 0276c03

Browse files
authored
feat(core): Deprecate transaction metadata in favor of attributes (#10097)
This deprecates any usage of `metadata` on transactions. The main usages we have are to set `sampleRate` and `source` in there. These I replaced with semantic attributes. For backwards compatibility, when creating the transaction event we still check the metadata there as well. Other usage of metadata (mostly around `request`) remains intact for now, we need to replace this in v8 - e.g. put this on the isolation scope, probably. This is the first usage of [Semantic Attributes](https://github.com/getsentry/rfcs/blob/main/text/0116-sentry-semantic-conventions.md) in the SDK! This replaces #10041
1 parent 4a920b5 commit 0276c03

File tree

60 files changed

+515
-230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+515
-230
lines changed

MIGRATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ In v8, the Span class is heavily reworked. The following properties & methods ar
8989
* `span.traceId`: Use `span.spanContext().traceId` instead.
9090
* `span.name`: Use `spanToJSON(span).description` instead.
9191
* `span.description`: Use `spanToJSON(span).description` instead.
92+
* `transaction.setMetadata()`: Use attributes instead, or set data on the scope.
93+
* `transaction.metadata`: Use attributes instead, or set data on the scope.
9294

9395
## Deprecate `pushScope` & `popScope` in favor of `withScope`
9496

dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/subject.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ const chicken = {};
22
const egg = { contains: chicken };
33
chicken.lays = egg;
44

5-
const circularObject = chicken;
6-
7-
const transaction = Sentry.startTransaction({ name: 'circular_object_test_transaction', data: circularObject });
8-
const span = transaction.startChild({ op: 'circular_object_test_span', data: circularObject });
5+
const transaction = Sentry.startTransaction({ name: 'circular_object_test_transaction', data: { chicken } });
6+
const span = transaction.startChild({ op: 'circular_object_test_span', data: { chicken } });
97

108
span.end();
119
transaction.end();

dev-packages/browser-integration-tests/suites/public-api/startTransaction/circular_data/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ sentryTest('should be able to handle circular data', async ({ getLocalTestPath,
1717

1818
expect(eventData.contexts).toMatchObject({
1919
trace: {
20-
data: { lays: { contains: '[Circular ~]' } },
20+
data: { chicken: { lays: { contains: '[Circular ~]' } } },
2121
},
2222
});
2323

2424
expect(eventData?.spans?.[0]).toMatchObject({
25-
data: { lays: { contains: '[Circular ~]' } },
25+
data: { chicken: { lays: { contains: '[Circular ~]' } } },
2626
op: 'circular_object_test_span',
2727
});
2828

dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import http from 'http';
2+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
23
import * as Sentry from '@sentry/node';
34
import * as Tracing from '@sentry/tracing';
45
import cors from 'cors';
@@ -34,7 +35,7 @@ app.get('/test/express', (_req, res) => {
3435
if (transaction) {
3536
// eslint-disable-next-line deprecation/deprecation
3637
transaction.traceId = '86f39e84263a4de99c326acab3bfe3bd';
37-
transaction.setMetadata({ source: 'route' });
38+
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
3839
}
3940
const headers = http.get('http://somewhere.not.sentry/').getHeaders();
4041

packages/angular-ivy/ng-package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"entryFile": "src/index.ts",
66
"umdModuleIds": {
77
"@sentry/browser": "Sentry",
8-
"@sentry/utils": "Sentry.util"
8+
"@sentry/utils": "Sentry.util",
9+
"@sentry/core": "Sentry.core"
910
}
1011
},
11-
"allowedNonPeerDependencies": ["@sentry/browser", "@sentry/utils", "@sentry/types", "tslib"],
12+
"allowedNonPeerDependencies": ["@sentry/browser", "@sentry/core", "@sentry/utils", "@sentry/types", "tslib"],
1213
"assets": ["README.md", "LICENSE"]
1314
}

packages/angular-ivy/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"dependencies": {
2424
"@sentry/browser": "7.92.0",
25+
"@sentry/core": "7.92.0",
2526
"@sentry/types": "7.92.0",
2627
"@sentry/utils": "7.92.0",
2728
"tslib": "^2.4.1"

packages/angular/ng-package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"entryFile": "src/index.ts",
66
"umdModuleIds": {
77
"@sentry/browser": "Sentry",
8-
"@sentry/utils": "Sentry.util"
8+
"@sentry/utils": "Sentry.util",
9+
"@sentry/core": "Sentry.core"
910
}
1011
},
11-
"whitelistedNonPeerDependencies": ["@sentry/browser", "@sentry/utils", "@sentry/types", "tslib"],
12+
"whitelistedNonPeerDependencies": ["@sentry/browser", "@sentry/core", "@sentry/utils", "@sentry/types", "tslib"],
1213
"assets": ["README.md", "LICENSE"]
1314
}

packages/angular/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
},
2323
"dependencies": {
2424
"@sentry/browser": "7.92.0",
25+
"@sentry/core": "7.92.0",
2526
"@sentry/types": "7.92.0",
2627
"@sentry/utils": "7.92.0",
2728
"tslib": "^2.4.1"

packages/angular/src/tracing.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router
88
import { NavigationCancel, NavigationError, Router } from '@angular/router';
99
import { NavigationEnd, NavigationStart, ResolveEnd } from '@angular/router';
1010
import { WINDOW, getCurrentScope } from '@sentry/browser';
11+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON } from '@sentry/core';
1112
import type { Span, Transaction, TransactionContext } from '@sentry/types';
1213
import { logger, stripUrlQueryAndFragment, timestampInSeconds } from '@sentry/utils';
1314
import type { Observable } from 'rxjs';
@@ -39,7 +40,9 @@ export function routingInstrumentation(
3940
name: WINDOW.location.pathname,
4041
op: 'pageload',
4142
origin: 'auto.pageload.angular',
42-
metadata: { source: 'url' },
43+
attributes: {
44+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
45+
},
4346
});
4447
}
4548
}
@@ -80,7 +83,9 @@ export class TraceService implements OnDestroy {
8083
name: strippedUrl,
8184
op: 'navigation',
8285
origin: 'auto.navigation.angular',
83-
metadata: { source: 'url' },
86+
attributes: {
87+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
88+
},
8489
});
8590
}
8691

@@ -123,9 +128,10 @@ export class TraceService implements OnDestroy {
123128
// eslint-disable-next-line deprecation/deprecation
124129
const transaction = getActiveTransaction();
125130
// TODO (v8 / #5416): revisit the source condition. Do we want to make the parameterized route the default?
126-
if (transaction && transaction.metadata.source === 'url') {
131+
const attributes = (transaction && spanToJSON(transaction).data) || {};
132+
if (transaction && attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'url') {
127133
transaction.updateName(route);
128-
transaction.setMetadata({ source: 'route' });
134+
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
129135
}
130136
}),
131137
);

packages/angular/test/tracing.test.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Component } from '@angular/core';
22
import type { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
3+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
34

45
import { TraceClassDecorator, TraceDirective, TraceMethodDecorator, instrumentAngularRouting } from '../src';
56
import { getParameterizedRouteFromSnapshot } from '../src/tracing';
@@ -11,7 +12,14 @@ const defaultStartTransaction = (ctx: any) => {
1112
transaction = {
1213
...ctx,
1314
updateName: jest.fn(name => (transaction.name = name)),
14-
setMetadata: jest.fn(),
15+
setAttribute: jest.fn(),
16+
toJSON: () => ({
17+
data: {
18+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',
19+
...ctx.data,
20+
...ctx.attributes,
21+
},
22+
}),
1523
};
1624

1725
return transaction;
@@ -45,7 +53,7 @@ describe('Angular Tracing', () => {
4553
name: '/',
4654
op: 'pageload',
4755
origin: 'auto.pageload.angular',
48-
metadata: { source: 'url' },
56+
attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' },
4957
});
5058
});
5159
});
@@ -107,11 +115,15 @@ describe('Angular Tracing', () => {
107115
const customStartTransaction = jest.fn((ctx: any) => {
108116
transaction = {
109117
...ctx,
110-
metadata: {
111-
...ctx.metadata,
112-
source: 'custom',
113-
},
118+
toJSON: () => ({
119+
data: {
120+
...ctx.data,
121+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',
122+
},
123+
}),
124+
metadata: ctx.metadata,
114125
updateName: jest.fn(name => (transaction.name = name)),
126+
setAttribute: jest.fn(),
115127
};
116128

117129
return transaction;
@@ -135,12 +147,12 @@ describe('Angular Tracing', () => {
135147
name: url,
136148
op: 'pageload',
137149
origin: 'auto.pageload.angular',
138-
metadata: { source: 'url' },
150+
attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' },
139151
});
140152

141153
expect(transaction.updateName).toHaveBeenCalledTimes(0);
142154
expect(transaction.name).toEqual(url);
143-
expect(transaction.metadata.source).toBe('custom');
155+
expect(transaction.toJSON().data).toEqual({ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' });
144156

145157
env.destroy();
146158
});
@@ -326,10 +338,10 @@ describe('Angular Tracing', () => {
326338
name: url,
327339
op: 'navigation',
328340
origin: 'auto.navigation.angular',
329-
metadata: { source: 'url' },
341+
attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' },
330342
});
331343
expect(transaction.updateName).toHaveBeenCalledWith(result);
332-
expect(transaction.setMetadata).toHaveBeenCalledWith({ source: 'route' });
344+
expect(transaction.setAttribute).toHaveBeenCalledWith(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
333345

334346
env.destroy();
335347
});

0 commit comments

Comments
 (0)