Skip to content

Commit 6bb58b7

Browse files
committed
feat(angular): Export custom browserTracingIntegration()
Also deprecate the routing Instrumentation.
1 parent ed19b05 commit 6bb58b7

File tree

6 files changed

+81
-18
lines changed

6 files changed

+81
-18
lines changed

packages/angular-ivy/README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,14 @@ Registering a Trace Service is a 3-step process.
9393
instrumentation:
9494

9595
```javascript
96-
import { init, instrumentAngularRouting, BrowserTracing } from '@sentry/angular-ivy';
96+
import { init, browserTracingIntegration } from '@sentry/angular-ivy';
9797

9898
init({
9999
dsn: '__DSN__',
100-
integrations: [
101-
new BrowserTracing({
102-
tracingOrigins: ['localhost', 'https://yourserver.io/api'],
103-
routingInstrumentation: instrumentAngularRouting,
104-
}),
100+
integrations: [
101+
browserTracingIntegration(),
105102
],
103+
tracePropagationTargets: ['localhost', 'https://yourserver.io/api'],
106104
tracesSampleRate: 1,
107105
});
108106
```

packages/angular/README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,14 @@ Registering a Trace Service is a 3-step process.
9393
instrumentation:
9494

9595
```javascript
96-
import { init, instrumentAngularRouting, BrowserTracing } from '@sentry/angular';
96+
import { init, browserTracingIntegration } from '@sentry/angular';
9797

9898
init({
9999
dsn: '__DSN__',
100100
integrations: [
101-
new BrowserTracing({
102-
tracingOrigins: ['localhost', 'https://yourserver.io/api'],
103-
routingInstrumentation: instrumentAngularRouting,
104-
}),
101+
browserTracingIntegration(),
105102
],
103+
tracePropagationTargets: ['localhost', 'https://yourserver.io/api'],
106104
tracesSampleRate: 1,
107105
});
108106
```

packages/angular/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ export { createErrorHandler, SentryErrorHandler } from './errorhandler';
77
export {
88
// eslint-disable-next-line deprecation/deprecation
99
getActiveTransaction,
10-
// TODO `instrumentAngularRouting` is just an alias for `routingInstrumentation`; deprecate the latter at some point
10+
// eslint-disable-next-line deprecation/deprecation
1111
instrumentAngularRouting, // new name
12+
// eslint-disable-next-line deprecation/deprecation
1213
routingInstrumentation, // legacy name
14+
browserTracingIntegration,
1315
TraceClassDecorator,
1416
TraceMethodDecorator,
1517
TraceDirective,

packages/angular/src/tracing.ts

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router
77
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
88
import { NavigationCancel, NavigationError, Router } from '@angular/router';
99
import { NavigationEnd, NavigationStart, ResolveEnd } from '@angular/router';
10-
import { WINDOW, getCurrentScope } from '@sentry/browser';
11-
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON } from '@sentry/core';
12-
import type { Span, Transaction, TransactionContext } from '@sentry/types';
10+
import {
11+
WINDOW,
12+
browserTracingIntegration as originalBrowserTracingIntegration,
13+
getCurrentScope,
14+
startBrowserTracingNavigationSpan,
15+
} from '@sentry/browser';
16+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, spanToJSON, startInactiveSpan } from '@sentry/core';
17+
import type { Integration, Span, Transaction, TransactionContext } from '@sentry/types';
1318
import { logger, stripUrlQueryAndFragment, timestampInSeconds } from '@sentry/utils';
1419
import type { Observable } from 'rxjs';
1520
import { Subscription } from 'rxjs';
@@ -23,8 +28,12 @@ let instrumentationInitialized: boolean;
2328
let stashedStartTransaction: (context: TransactionContext) => Transaction | undefined;
2429
let stashedStartTransactionOnLocationChange: boolean;
2530

31+
let hooksBasedInstrumentation = false;
32+
2633
/**
2734
* Creates routing instrumentation for Angular Router.
35+
*
36+
* @deprecated Use `browserTracingIntegration()` instead, which includes Angular-specific instrumentation out of the box.
2837
*/
2938
export function routingInstrumentation(
3039
customStartTransaction: (context: TransactionContext) => Transaction | undefined,
@@ -47,8 +56,28 @@ export function routingInstrumentation(
4756
}
4857
}
4958

59+
/**
60+
* Creates routing instrumentation for Angular Router.
61+
*
62+
* @deprecated Use `browserTracingIntegration()` instead, which includes Angular-specific instrumentation out of the box.
63+
*/
64+
// eslint-disable-next-line deprecation/deprecation
5065
export const instrumentAngularRouting = routingInstrumentation;
5166

67+
/**
68+
* A custom BrowserTracing integration for Angular.
69+
*
70+
* Use this integration in combination with `TraceService`
71+
*/
72+
export function browserTracingIntegration(
73+
options?: Parameters<typeof originalBrowserTracingIntegration>[0],
74+
): Integration {
75+
instrumentationInitialized = true;
76+
hooksBasedInstrumentation = true;
77+
78+
return originalBrowserTracingIntegration(options);
79+
}
80+
5281
/**
5382
* Grabs active transaction off scope.
5483
*
@@ -74,7 +103,43 @@ export class TraceService implements OnDestroy {
74103
return;
75104
}
76105

106+
if (this._routingSpan) {
107+
this._routingSpan.end();
108+
this._routingSpan = null;
109+
}
110+
77111
const strippedUrl = stripUrlQueryAndFragment(navigationEvent.url);
112+
113+
if (hooksBasedInstrumentation) {
114+
if (!getActiveSpan()) {
115+
startBrowserTracingNavigationSpan({
116+
name: strippedUrl,
117+
op: 'navigation',
118+
origin: 'auto.navigation.angular',
119+
attributes: {
120+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
121+
},
122+
});
123+
}
124+
125+
// eslint-disable-next-line deprecation/deprecation
126+
this._routingSpan =
127+
startInactiveSpan({
128+
name: `${navigationEvent.url}`,
129+
op: ANGULAR_ROUTING_OP,
130+
origin: 'auto.ui.angular',
131+
tags: {
132+
'routing.instrumentation': '@sentry/angular',
133+
url: strippedUrl,
134+
...(navigationEvent.navigationTrigger && {
135+
navigationTrigger: navigationEvent.navigationTrigger,
136+
}),
137+
},
138+
}) || null;
139+
140+
return;
141+
}
142+
78143
// eslint-disable-next-line deprecation/deprecation
79144
let activeTransaction = getActiveTransaction();
80145

@@ -90,9 +155,6 @@ export class TraceService implements OnDestroy {
90155
}
91156

92157
if (activeTransaction) {
93-
if (this._routingSpan) {
94-
this._routingSpan.end();
95-
}
96158
// eslint-disable-next-line deprecation/deprecation
97159
this._routingSpan = activeTransaction.startChild({
98160
description: `${navigationEvent.url}`,

packages/angular/test/tracing.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('Angular Tracing', () => {
4444
transaction = undefined;
4545
});
4646

47+
/* eslint-disable deprecation/deprecation */
4748
describe('instrumentAngularRouting', () => {
4849
it('should attach the transaction source on the pageload transaction', () => {
4950
const startTransaction = jest.fn();
@@ -57,6 +58,7 @@ describe('Angular Tracing', () => {
5758
});
5859
});
5960
});
61+
/* eslint-enable deprecation/deprecation */
6062

6163
describe('getParameterizedRouteFromSnapshot', () => {
6264
it.each([

packages/angular/test/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class TestEnv {
5050
useTraceService?: boolean;
5151
additionalProviders?: Provider[];
5252
}): Promise<TestEnv> {
53+
// eslint-disable-next-line deprecation/deprecation
5354
instrumentAngularRouting(
5455
conf.customStartTransaction || jest.fn(),
5556
conf.startTransactionOnPageLoad !== undefined ? conf.startTransactionOnPageLoad : true,

0 commit comments

Comments
 (0)