@@ -7,9 +7,14 @@ import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router
7
7
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
8
8
import { NavigationCancel , NavigationError , Router } from '@angular/router' ;
9
9
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' ;
13
18
import { logger , stripUrlQueryAndFragment , timestampInSeconds } from '@sentry/utils' ;
14
19
import type { Observable } from 'rxjs' ;
15
20
import { Subscription } from 'rxjs' ;
@@ -23,8 +28,12 @@ let instrumentationInitialized: boolean;
23
28
let stashedStartTransaction : ( context : TransactionContext ) => Transaction | undefined ;
24
29
let stashedStartTransactionOnLocationChange : boolean ;
25
30
31
+ let hooksBasedInstrumentation = false ;
32
+
26
33
/**
27
34
* Creates routing instrumentation for Angular Router.
35
+ *
36
+ * @deprecated Use `browserTracingIntegration()` instead, which includes Angular-specific instrumentation out of the box.
28
37
*/
29
38
export function routingInstrumentation (
30
39
customStartTransaction : ( context : TransactionContext ) => Transaction | undefined ,
@@ -47,8 +56,28 @@ export function routingInstrumentation(
47
56
}
48
57
}
49
58
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
50
65
export const instrumentAngularRouting = routingInstrumentation ;
51
66
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
+
52
81
/**
53
82
* Grabs active transaction off scope.
54
83
*
@@ -74,7 +103,43 @@ export class TraceService implements OnDestroy {
74
103
return ;
75
104
}
76
105
106
+ if ( this . _routingSpan ) {
107
+ this . _routingSpan . end ( ) ;
108
+ this . _routingSpan = null ;
109
+ }
110
+
77
111
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
+
78
143
// eslint-disable-next-line deprecation/deprecation
79
144
let activeTransaction = getActiveTransaction ( ) ;
80
145
@@ -90,9 +155,6 @@ export class TraceService implements OnDestroy {
90
155
}
91
156
92
157
if ( activeTransaction ) {
93
- if ( this . _routingSpan ) {
94
- this . _routingSpan . end ( ) ;
95
- }
96
158
// eslint-disable-next-line deprecation/deprecation
97
159
this . _routingSpan = activeTransaction . startChild ( {
98
160
description : `${ navigationEvent . url } ` ,
0 commit comments