@@ -6,7 +6,7 @@ import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling';
6
6
import { forEachEnvelopeItem , GLOBAL_OBJ , logger , uuid4 } from '@sentry/utils' ;
7
7
8
8
import { WINDOW } from '../helpers' ;
9
- import type { JSSelfProfile , JSSelfProfileStack , ProcessedJSSelfProfile } from './jsSelfProfiling' ;
9
+ import type { JSSelfProfile , JSSelfProfileStack } from './jsSelfProfiling' ;
10
10
11
11
const MS_TO_NS = 1e6 ;
12
12
// Use 0 as main thread id which is identical to threadId in node:worker_threads
@@ -64,9 +64,7 @@ if (isUserAgentData(userAgentData)) {
64
64
. catch ( e => void e ) ;
65
65
}
66
66
67
- function isProcessedJSSelfProfile (
68
- profile : ThreadCpuProfile | ProcessedJSSelfProfile ,
69
- ) : profile is ProcessedJSSelfProfile {
67
+ function isProcessedJSSelfProfile ( profile : ThreadCpuProfile | JSSelfProfile ) : profile is JSSelfProfile {
70
68
return ! ( 'thread_metadata' in profile ) ;
71
69
}
72
70
@@ -75,7 +73,7 @@ function isProcessedJSSelfProfile(
75
73
/**
76
74
*
77
75
*/
78
- export function enrichWithThreadInformation ( profile : ThreadCpuProfile | ProcessedJSSelfProfile ) : ThreadCpuProfile {
76
+ export function enrichWithThreadInformation ( profile : ThreadCpuProfile | JSSelfProfile ) : ThreadCpuProfile {
79
77
if ( ! isProcessedJSSelfProfile ( profile ) ) {
80
78
return profile ;
81
79
}
@@ -87,7 +85,7 @@ export function enrichWithThreadInformation(profile: ThreadCpuProfile | Processe
87
85
// by the integration before the event is processed by other integrations.
88
86
export interface ProfiledEvent extends Event {
89
87
sdkProcessingMetadata : {
90
- profile ?: ProcessedJSSelfProfile ;
88
+ profile ?: JSSelfProfile ;
91
89
} ;
92
90
}
93
91
@@ -120,7 +118,11 @@ function getTraceId(event: Event): string {
120
118
/**
121
119
* Creates a profiling event envelope from a Sentry event.
122
120
*/
123
- export function createProfilePayload ( event : ProfiledEvent , processedProfile : ProcessedJSSelfProfile ) : Profile {
121
+ export function createProfilePayload (
122
+ event : ProfiledEvent ,
123
+ processedProfile : JSSelfProfile ,
124
+ profile_id : string ,
125
+ ) : Profile {
124
126
if ( event . type !== 'transaction' ) {
125
127
// createProfilingEventEnvelope should only be called for transactions,
126
128
// we type guard this behavior with isProfiledTransactionEvent.
@@ -133,17 +135,13 @@ export function createProfilePayload(event: ProfiledEvent, processedProfile: Pro
133
135
) ;
134
136
}
135
137
136
- if ( ! processedProfile . profile_id ) {
137
- throw new TypeError ( 'Profile is missing profile_id' ) ;
138
- }
139
-
140
138
const traceId = getTraceId ( event ) ;
141
139
const enrichedThreadProfile = enrichWithThreadInformation ( processedProfile ) ;
142
140
const transactionStartMs = typeof event . start_timestamp === 'number' ? event . start_timestamp * 1000 : Date . now ( ) ;
143
141
const transactionEndMs = typeof event . timestamp === 'number' ? event . timestamp * 1000 : Date . now ( ) ;
144
142
145
143
const profile : Profile = {
146
- event_id : processedProfile . profile_id ,
144
+ event_id : profile_id ,
147
145
timestamp : new Date ( transactionStartMs ) . toISOString ( ) ,
148
146
platform : 'javascript' ,
149
147
version : '1' ,
@@ -420,8 +418,8 @@ export function isValidSampleRate(rate: unknown): boolean {
420
418
return true ;
421
419
}
422
420
423
- function isValidProfile ( profile : ProcessedJSSelfProfile ) : profile is ProcessedJSSelfProfile & { profile_id : string } {
424
- if ( profile . samples . length <= 1 ) {
421
+ function isValidProfile ( profile : JSSelfProfile ) : profile is JSSelfProfile & { profile_id : string } {
422
+ if ( profile . samples . length < 2 ) {
425
423
if ( __DEBUG_BUILD__ ) {
426
424
// Log a warning if the profile has less than 2 samples so users can know why
427
425
// they are not seeing any profiling data and we cant avoid the back and forth
@@ -431,7 +429,10 @@ function isValidProfile(profile: ProcessedJSSelfProfile): profile is ProcessedJS
431
429
return false ;
432
430
}
433
431
434
- if ( ! profile . profile_id ) {
432
+ if ( ! profile . frames . length ) {
433
+ if ( __DEBUG_BUILD__ ) {
434
+ logger . log ( '[Profiling] Discarding profile because it contains no frames' ) ;
435
+ }
435
436
return false ;
436
437
}
437
438
@@ -443,24 +444,23 @@ function isValidProfile(profile: ProcessedJSSelfProfile): profile is ProcessedJS
443
444
* @param event
444
445
* @returns {Profile | null }
445
446
*/
446
- export function createProfilingEvent ( profile : ProcessedJSSelfProfile , event : ProfiledEvent ) : Profile | null {
447
+ export function createProfilingEvent ( profile_id : string , profile : JSSelfProfile , event : ProfiledEvent ) : Profile | null {
447
448
if ( ! isValidProfile ( profile ) ) {
448
449
return null ;
449
450
}
450
451
451
- return createProfilePayload ( event , profile ) ;
452
+ return createProfilePayload ( event , profile , profile_id ) ;
452
453
}
453
454
454
-
455
- export const PROFILE_MAP : Map < string , ProcessedJSSelfProfile > = new Map ( ) ;
455
+ export const PROFILE_MAP : Map < string , JSSelfProfile > = new Map ( ) ;
456
456
/**
457
457
*
458
458
*/
459
- export function addProfileToMap ( profile : ProcessedJSSelfProfile ) : void {
460
- PROFILE_MAP . set ( profile . profile_id , profile ) ;
459
+ export function addProfileToMap ( profile_id : string , profile : JSSelfProfile ) : void {
460
+ PROFILE_MAP . set ( profile_id , profile ) ;
461
461
462
- if ( PROFILE_MAP . size > 30 ) {
463
- const last : string = [ ... PROFILE_MAP . keys ( ) ] . pop ( ) as string ;
462
+ if ( PROFILE_MAP . size > 30 ) {
463
+ const last : string = PROFILE_MAP . keys ( ) . next ( ) . value ;
464
464
PROFILE_MAP . delete ( last ) ;
465
465
}
466
- }
466
+ }
0 commit comments