Skip to content

Commit c551f0a

Browse files
committed
feat(profiling): allow collecting of profiles that started before sentry had loaded
1 parent add811b commit c551f0a

File tree

5 files changed

+25
-13
lines changed

5 files changed

+25
-13
lines changed

packages/browser/src/profiling/hubextensions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export function wrapTransactionWithProfiling(transaction: Transaction): Transact
174174

175175
return profiler
176176
.stop()
177-
.then((p: JSSelfProfile): null => {
177+
.then((profile: JSSelfProfile): null => {
178178
if (maxDurationTimeoutID) {
179179
WINDOW.clearTimeout(maxDurationTimeoutID);
180180
maxDurationTimeoutID = undefined;
@@ -185,7 +185,7 @@ export function wrapTransactionWithProfiling(transaction: Transaction): Transact
185185
}
186186

187187
// In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile.
188-
if (!p) {
188+
if (!profile) {
189189
if (__DEBUG_BUILD__) {
190190
logger.log(
191191
`[Profiling] profiler returned null profile for: ${transaction.name || transaction.description}`,
@@ -195,7 +195,7 @@ export function wrapTransactionWithProfiling(transaction: Transaction): Transact
195195
return null;
196196
}
197197

198-
addProfileToMap(profileId, p);
198+
addProfileToMap(profileId, profile);
199199
return null;
200200
})
201201
.catch(error => {

packages/browser/src/profiling/integration.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,33 @@ export class BrowserProfilingIntegration implements Integration {
5353
// automated page load profile id so that it will get picked up by the beforeEnvelope hook.
5454
const pageLoadProfile = getAutomatedPageLoadProfile(carrier);
5555
if (pageLoadProfile) {
56+
// @TODO JonasB: remove finishTransaction listener if carrier.profiles is empty
5657
client.on('finishTransaction', (transaction: Transaction) => {
5758
if (!isAutomatedPageLoadTransaction(transaction)) {
5859
return;
5960
}
6061

62+
if (pageLoadProfile.stopped) {
63+
__DEBUG_BUILD__ &&
64+
logger.log(
65+
`[Profiling] automated page load transaction already stopped, not stopping again: ${transaction.name ||
66+
transaction.description}`,
67+
);
68+
return;
69+
}
70+
6171
transaction.setContext('profile', { profile_id: AUTOMATED_PAGELOAD_PROFILE_ID });
6272
pageLoadProfile
6373
.stop()
64-
.then((p: JSSelfProfile): null => {
74+
.then((profile: JSSelfProfile): null => {
6575
if (__DEBUG_BUILD__) {
6676
logger.log(
6777
`[Profiling] stopped profiling of transaction: ${transaction.name || transaction.description}`,
6878
);
6979
}
7080

7181
// In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile.
72-
if (!p) {
82+
if (!profile) {
7383
if (__DEBUG_BUILD__) {
7484
logger.log(
7585
`[Profiling] profiler returned null profile for: ${transaction.name || transaction.description}`,
@@ -79,7 +89,7 @@ export class BrowserProfilingIntegration implements Integration {
7989
return null;
8090
}
8191

82-
addProfileToMap(AUTOMATED_PAGELOAD_PROFILE_ID, p);
92+
addProfileToMap(AUTOMATED_PAGELOAD_PROFILE_ID, profile);
8393
return null;
8494
})
8595
.catch(error => {

packages/browser/src/profiling/jsSelfProfiling.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@ export type JSSelfProfile = {
2626
samples: JSSelfProfileSample[];
2727
};
2828

29-
type BufferFullCallback = (trace: JSSelfProfile) => void;
3029

3130
export interface JSSelfProfiler {
3231
sampleInterval: number;
3332
stopped: boolean;
3433

3534
stop: () => Promise<JSSelfProfile>;
36-
addEventListener(event: 'samplebufferfull', callback: BufferFullCallback): void;
35+
addEventListener(event: 'samplebufferfull', callback: (trace: JSSelfProfile) => void): void;
3736
}
3837

3938
export declare const JSSelfProfilerConstructor: {

packages/browser/src/profiling/utils.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling';
66
import { browserPerformanceTimeOrigin, forEachEnvelopeItem, GLOBAL_OBJ, logger, uuid4 } from '@sentry/utils';
77

88
import { WINDOW } from '../helpers';
9-
import type { JSSelfProfile, JSSelfProfileStack } from './jsSelfProfiling';
9+
import type { JSSelfProfile, JSSelfProfileStack, JSSelfProfiler } from './jsSelfProfiling';
1010
import type { Transaction } from '@sentry/types';
11-
import { JSSelfProfiler } from '../../build/npm/types/profiling/jsSelfProfiling';
1211

1312
const MS_TO_NS = 1e6;
1413
// Use 0 as main thread id which is identical to threadId in node:worker_threads
@@ -192,6 +191,9 @@ export function isProfiledTransactionEvent(event: Event): event is ProfiledEvent
192191
return !!(event.sdkProcessingMetadata && event.sdkProcessingMetadata['profile']);
193192
}
194193

194+
/**
195+
* Returns the automated page load profile from the carrier if it exists and removes the reference to it.
196+
*/
195197
export function getAutomatedPageLoadProfile(carrier: Carrier): JSSelfProfiler | undefined {
196198
const __SENTRY__ = carrier.__SENTRY__;
197199
if (
@@ -211,7 +213,6 @@ export function getAutomatedPageLoadProfile(carrier: Carrier): JSSelfProfiler |
211213
See packages/tracing-internal/src/browser/router.ts
212214
*/
213215
export function isAutomatedPageLoadTransaction(transaction: Transaction): boolean {
214-
// @ts-expect-error origin seems untyped
215216
return transaction.op === 'pageload' && transaction.origin === AUTOMATED_PAGELOAD_PROFILE_ID
216217
}
217218

packages/core/src/hub.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import { consoleSandbox, dateTimestampInSeconds, getGlobalSingleton, GLOBAL_OBJ,
2525
import { DEFAULT_ENVIRONMENT } from './constants';
2626
import { Scope } from './scope';
2727
import { closeSession, makeSession, updateSession } from './session';
28-
import type { JSSelfProfiler } from '@sentry/browser';
2928

3029
/**
3130
* API compatibility version of this hub.
@@ -91,7 +90,10 @@ export interface Carrier {
9190
[key: string]: Function;
9291
};
9392
profiling?: {
94-
profiles?: Record<"auto.pageload.browser", JSSelfProfiler>;
93+
/*
94+
* Stores profile started before SDK was initialized
95+
*/
96+
profiles?: Record<"auto.pageload.browser", any>;
9597
}
9698
};
9799
}

0 commit comments

Comments
 (0)