1
- import { getCurrentScope } from '@sentry/core' ;
2
- import type { Client , EventEnvelope , EventProcessor , Hub , Integration , Transaction } from '@sentry/types' ;
1
+ import { convertIntegrationFnToClass , getCurrentScope } from '@sentry/core' ;
2
+ import type { EventEnvelope , IntegrationFn , Transaction } from '@sentry/types' ;
3
3
import type { Profile } from '@sentry/types/src/profiling' ;
4
4
import { logger } from '@sentry/utils' ;
5
5
@@ -16,108 +16,97 @@ import {
16
16
takeProfileFromGlobalCache ,
17
17
} from './utils' ;
18
18
19
- /**
20
- * Browser profiling integration. Stores any event that has contexts["profile"]["profile_id"]
21
- * This exists because we do not want to await async profiler.stop calls as transaction.finish is called
22
- * in a synchronous context. Instead, we handle sending the profile async from the promise callback and
23
- * rely on being able to pull the event from the cache when we need to construct the envelope. This makes the
24
- * integration less reliable as we might be dropping profiles when the cache is full.
25
- *
26
- * @experimental
27
- */
28
- export class BrowserProfilingIntegration implements Integration {
29
- public static id : string = 'BrowserProfilingIntegration' ;
19
+ const INTEGRATION_NAME = 'BrowserProfiling' ;
30
20
31
- public readonly name : string ;
21
+ const browserProfilingIntegration : IntegrationFn = ( ) => {
22
+ return {
23
+ name : INTEGRATION_NAME ,
24
+ setup ( client ) {
25
+ const scope = getCurrentScope ( ) ;
32
26
33
- /** @deprecated This is never set. */
34
- public getCurrentHub ?: ( ) => Hub ;
27
+ const transaction = scope . getTransaction ( ) ;
35
28
36
- public constructor ( ) {
37
- this . name = BrowserProfilingIntegration . id ;
38
- }
39
-
40
- /**
41
- * @inheritDoc
42
- */
43
- public setupOnce ( _addGlobalEventProcessor : ( callback : EventProcessor ) => void , _getCurrentHub : ( ) => Hub ) : void {
44
- // noop
45
- }
46
-
47
- /** @inheritdoc */
48
- public setup ( client : Client ) : void {
49
- const scope = getCurrentScope ( ) ;
50
-
51
- const transaction = scope . getTransaction ( ) ;
52
-
53
- if ( transaction && isAutomatedPageLoadTransaction ( transaction ) ) {
54
- if ( shouldProfileTransaction ( transaction ) ) {
55
- startProfileForTransaction ( transaction ) ;
56
- }
57
- }
58
-
59
- if ( typeof client . on !== 'function' ) {
60
- logger . warn ( '[Profiling] Client does not support hooks, profiling will be disabled' ) ;
61
- return ;
62
- }
63
-
64
- client . on ( 'startTransaction' , ( transaction : Transaction ) => {
65
- if ( shouldProfileTransaction ( transaction ) ) {
66
- startProfileForTransaction ( transaction ) ;
67
- }
68
- } ) ;
69
-
70
- client . on ( 'beforeEnvelope' , ( envelope ) : void => {
71
- // if not profiles are in queue, there is nothing to add to the envelope.
72
- if ( ! getActiveProfilesCount ( ) ) {
73
- return ;
29
+ if ( transaction && isAutomatedPageLoadTransaction ( transaction ) ) {
30
+ if ( shouldProfileTransaction ( transaction ) ) {
31
+ startProfileForTransaction ( transaction ) ;
32
+ }
74
33
}
75
34
76
- const profiledTransactionEvents = findProfiledTransactionsFromEnvelope ( envelope ) ;
77
- if ( ! profiledTransactionEvents . length ) {
35
+ if ( typeof client . on !== 'function' ) {
36
+ logger . warn ( '[Profiling] Client does not support hooks, profiling will be disabled' ) ;
78
37
return ;
79
38
}
80
39
81
- const profilesToAddToEnvelope : Profile [ ] = [ ] ;
82
-
83
- for ( const profiledTransaction of profiledTransactionEvents ) {
84
- const context = profiledTransaction && profiledTransaction . contexts ;
85
- const profile_id = context && context [ 'profile' ] && context [ 'profile' ] [ 'profile_id' ] ;
86
- const start_timestamp = context && context [ 'profile' ] && context [ 'profile' ] [ 'start_timestamp' ] ;
87
-
88
- if ( typeof profile_id !== 'string' ) {
89
- DEBUG_BUILD && logger . log ( '[Profiling] cannot find profile for a transaction without a profile context' ) ;
90
- continue ;
40
+ client . on ( 'startTransaction' , ( transaction : Transaction ) => {
41
+ if ( shouldProfileTransaction ( transaction ) ) {
42
+ startProfileForTransaction ( transaction ) ;
91
43
}
44
+ } ) ;
92
45
93
- if ( ! profile_id ) {
94
- DEBUG_BUILD && logger . log ( '[Profiling] cannot find profile for a transaction without a profile context' ) ;
95
- continue ;
46
+ client . on ( 'beforeEnvelope' , ( envelope ) : void => {
47
+ // if not profiles are in queue, there is nothing to add to the envelope.
48
+ if ( ! getActiveProfilesCount ( ) ) {
49
+ return ;
96
50
}
97
51
98
- // Remove the profile from the transaction context before sending, relay will take care of the rest.
99
- if ( context && context [ 'profile' ] ) {
100
- delete context . profile ;
52
+ const profiledTransactionEvents = findProfiledTransactionsFromEnvelope ( envelope ) ;
53
+ if ( ! profiledTransactionEvents . length ) {
54
+ return ;
101
55
}
102
56
103
- const profile = takeProfileFromGlobalCache ( profile_id ) ;
104
- if ( ! profile ) {
105
- DEBUG_BUILD && logger . log ( `[Profiling] Could not retrieve profile for transaction: ${ profile_id } ` ) ;
106
- continue ;
57
+ const profilesToAddToEnvelope : Profile [ ] = [ ] ;
58
+
59
+ for ( const profiledTransaction of profiledTransactionEvents ) {
60
+ const context = profiledTransaction && profiledTransaction . contexts ;
61
+ const profile_id = context && context [ 'profile' ] && context [ 'profile' ] [ 'profile_id' ] ;
62
+ const start_timestamp = context && context [ 'profile' ] && context [ 'profile' ] [ 'start_timestamp' ] ;
63
+
64
+ if ( typeof profile_id !== 'string' ) {
65
+ DEBUG_BUILD && logger . log ( '[Profiling] cannot find profile for a transaction without a profile context' ) ;
66
+ continue ;
67
+ }
68
+
69
+ if ( ! profile_id ) {
70
+ DEBUG_BUILD && logger . log ( '[Profiling] cannot find profile for a transaction without a profile context' ) ;
71
+ continue ;
72
+ }
73
+
74
+ // Remove the profile from the transaction context before sending, relay will take care of the rest.
75
+ if ( context && context [ 'profile' ] ) {
76
+ delete context . profile ;
77
+ }
78
+
79
+ const profile = takeProfileFromGlobalCache ( profile_id ) ;
80
+ if ( ! profile ) {
81
+ DEBUG_BUILD && logger . log ( `[Profiling] Could not retrieve profile for transaction: ${ profile_id } ` ) ;
82
+ continue ;
83
+ }
84
+
85
+ const profileEvent = createProfilingEvent (
86
+ profile_id ,
87
+ start_timestamp as number | undefined ,
88
+ profile ,
89
+ profiledTransaction as ProfiledEvent ,
90
+ ) ;
91
+ if ( profileEvent ) {
92
+ profilesToAddToEnvelope . push ( profileEvent ) ;
93
+ }
107
94
}
108
95
109
- const profileEvent = createProfilingEvent (
110
- profile_id ,
111
- start_timestamp as number | undefined ,
112
- profile ,
113
- profiledTransaction as ProfiledEvent ,
114
- ) ;
115
- if ( profileEvent ) {
116
- profilesToAddToEnvelope . push ( profileEvent ) ;
117
- }
118
- }
96
+ addProfilesToEnvelope ( envelope as EventEnvelope , profilesToAddToEnvelope ) ;
97
+ } ) ;
98
+ } ,
99
+ } ;
100
+ } ;
119
101
120
- addProfilesToEnvelope ( envelope as EventEnvelope , profilesToAddToEnvelope ) ;
121
- } ) ;
122
- }
123
- }
102
+ /**
103
+ * Browser profiling integration. Stores any event that has contexts["profile"]["profile_id"]
104
+ * This exists because we do not want to await async profiler.stop calls as transaction.finish is called
105
+ * in a synchronous context. Instead, we handle sending the profile async from the promise callback and
106
+ * rely on being able to pull the event from the cache when we need to construct the envelope. This makes the
107
+ * integration less reliable as we might be dropping profiles when the cache is full.
108
+ *
109
+ * @experimental
110
+ */
111
+ // eslint-disable-next-line deprecation/deprecation
112
+ export const BrowserProfilingIntegration = convertIntegrationFnToClass ( INTEGRATION_NAME , browserProfilingIntegration ) ;
0 commit comments