Skip to content

Commit 3b10f4e

Browse files
committed
feat(angular): Export custom browserTracingIntegration()
Also deprecate the routing Instrumentation.
1 parent 20d11cd commit 3b10f4e

File tree

6 files changed

+84
-18
lines changed

6 files changed

+84
-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: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ 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+
disableDefaultBrowserTracingNavigationSpan,
14+
getCurrentScope,
15+
startBrowserTracingNavigationSpan,
16+
} from '@sentry/browser';
17+
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, spanToJSON, startInactiveSpan } from '@sentry/core';
18+
import type { Integration, Span, Transaction, TransactionContext } from '@sentry/types';
1319
import { logger, stripUrlQueryAndFragment, timestampInSeconds } from '@sentry/utils';
1420
import type { Observable } from 'rxjs';
1521
import { Subscription } from 'rxjs';
@@ -23,8 +29,12 @@ let instrumentationInitialized: boolean;
2329
let stashedStartTransaction: (context: TransactionContext) => Transaction | undefined;
2430
let stashedStartTransactionOnLocationChange: boolean;
2531

32+
let hooksBasedInstrumentation = false;
33+
2634
/**
2735
* Creates routing instrumentation for Angular Router.
36+
*
37+
* @deprecated Use `browserTracingIntegration()` instead, which includes Angular-specific instrumentation out of the box.
2838
*/
2939
export function routingInstrumentation(
3040
customStartTransaction: (context: TransactionContext) => Transaction | undefined,
@@ -47,8 +57,30 @@ export function routingInstrumentation(
4757
}
4858
}
4959

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

68+
/**
69+
* A custom BrowserTracing integration for Angular.
70+
*
71+
* Use this integration in combination with `TraceService`
72+
*/
73+
export function browserTracingIntegration(
74+
options?: Parameters<typeof originalBrowserTracingIntegration>[0],
75+
): Integration {
76+
instrumentationInitialized = true;
77+
hooksBasedInstrumentation = true;
78+
79+
disableDefaultBrowserTracingNavigationSpan();
80+
81+
return originalBrowserTracingIntegration(options);
82+
}
83+
5284
/**
5385
* Grabs active transaction off scope.
5486
*
@@ -74,7 +106,43 @@ export class TraceService implements OnDestroy {
74106
return;
75107
}
76108

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

@@ -90,9 +158,6 @@ export class TraceService implements OnDestroy {
90158
}
91159

92160
if (activeTransaction) {
93-
if (this._routingSpan) {
94-
this._routingSpan.end();
95-
}
96161
// eslint-disable-next-line deprecation/deprecation
97162
this._routingSpan = activeTransaction.startChild({
98163
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)