this repo has no description
at main 81 lines 3.3 kB view raw
1import { logger } from '@sentry/utils'; 2import { wrapTransactionWithProfiling } from './hubextensions.js'; 3import { PROFILE_MAP, findProfiledTransactionsFromEnvelope, createProfilingEvent, addProfilesToEnvelope } from './utils.js'; 4 5/** 6 * Browser profiling integration. Stores any event that has contexts["profile"]["profile_id"] 7 * This exists because we do not want to await async profiler.stop calls as transaction.finish is called 8 * in a synchronous context. Instead, we handle sending the profile async from the promise callback and 9 * rely on being able to pull the event from the cache when we need to construct the envelope. This makes the 10 * integration less reliable as we might be dropping profiles when the cache is full. 11 * 12 * @experimental 13 */ 14class BrowserProfilingIntegration {constructor() { BrowserProfilingIntegration.prototype.__init.call(this);BrowserProfilingIntegration.prototype.__init2.call(this); } 15 __init() {this.name = 'BrowserProfilingIntegration';} 16 __init2() {this.getCurrentHub = undefined;} 17 18 /** 19 * @inheritDoc 20 */ 21 setupOnce(addGlobalEventProcessor, getCurrentHub) { 22 this.getCurrentHub = getCurrentHub; 23 const client = this.getCurrentHub().getClient() ; 24 25 if (client && typeof client.on === 'function') { 26 client.on('startTransaction', (transaction) => { 27 wrapTransactionWithProfiling(transaction); 28 }); 29 30 client.on('beforeEnvelope', (envelope) => { 31 // if not profiles are in queue, there is nothing to add to the envelope. 32 if (!PROFILE_MAP['size']) { 33 return; 34 } 35 36 const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope); 37 if (!profiledTransactionEvents.length) { 38 return; 39 } 40 41 const profilesToAddToEnvelope = []; 42 43 for (const profiledTransaction of profiledTransactionEvents) { 44 const context = profiledTransaction && profiledTransaction.contexts; 45 const profile_id = context && context['profile'] && (context['profile']['profile_id'] ); 46 47 if (!profile_id) { 48 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && 49 logger.log('[Profiling] cannot find profile for a transaction without a profile context'); 50 continue; 51 } 52 53 // Remove the profile from the transaction context before sending, relay will take care of the rest. 54 if (context && context['profile']) { 55 delete context.profile; 56 } 57 58 const profile = PROFILE_MAP.get(profile_id); 59 if (!profile) { 60 (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`); 61 continue; 62 } 63 64 PROFILE_MAP.delete(profile_id); 65 const profileEvent = createProfilingEvent(profile_id, profile, profiledTransaction ); 66 67 if (profileEvent) { 68 profilesToAddToEnvelope.push(profileEvent); 69 } 70 } 71 72 addProfilesToEnvelope(envelope, profilesToAddToEnvelope); 73 }); 74 } else { 75 logger.warn('[Profiling] Client does not support hooks, profiling will be disabled'); 76 } 77 } 78} 79 80export { BrowserProfilingIntegration }; 81//# sourceMappingURL=integration.js.map