@sentry/react-native 5.23.0-alpha.1 → 5.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -48
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +1 -54
- package/android/src/newarch/java/io/sentry/react/RNSentryModule.java +0 -10
- package/android/src/oldarch/java/io/sentry/react/RNSentryModule.java +0 -10
- package/dist/js/NativeRNSentry.d.ts +0 -2
- package/dist/js/NativeRNSentry.d.ts.map +1 -1
- package/dist/js/NativeRNSentry.js.map +1 -1
- package/dist/js/client.d.ts +0 -8
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +3 -19
- package/dist/js/client.js.map +1 -1
- package/dist/js/index.d.ts +5 -3
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +5 -3
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/debugsymbolicator.d.ts +8 -60
- package/dist/js/integrations/debugsymbolicator.d.ts.map +1 -1
- package/dist/js/integrations/debugsymbolicator.js +137 -209
- package/dist/js/integrations/debugsymbolicator.js.map +1 -1
- package/dist/js/integrations/debugsymbolicatorutils.d.ts +18 -0
- package/dist/js/integrations/debugsymbolicatorutils.d.ts.map +1 -0
- package/dist/js/integrations/debugsymbolicatorutils.js +70 -0
- package/dist/js/integrations/debugsymbolicatorutils.js.map +1 -0
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +24 -49
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/devicecontext.d.ts +8 -15
- package/dist/js/integrations/devicecontext.d.ts.map +1 -1
- package/dist/js/integrations/devicecontext.js +74 -74
- package/dist/js/integrations/devicecontext.js.map +1 -1
- package/dist/js/integrations/eventorigin.d.ts +8 -15
- package/dist/js/integrations/eventorigin.d.ts.map +1 -1
- package/dist/js/integrations/eventorigin.js +17 -17
- package/dist/js/integrations/eventorigin.js.map +1 -1
- package/dist/js/integrations/expocontext.d.ts +8 -15
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +28 -32
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/exports.d.ts +16 -0
- package/dist/js/integrations/exports.d.ts.map +1 -0
- package/dist/js/integrations/exports.js +16 -0
- package/dist/js/integrations/exports.js.map +1 -0
- package/dist/js/integrations/index.d.ts +4 -1
- package/dist/js/integrations/index.d.ts.map +1 -1
- package/dist/js/integrations/index.js +5 -1
- package/dist/js/integrations/index.js.map +1 -1
- package/dist/js/integrations/modulesloader.d.ts +8 -15
- package/dist/js/integrations/modulesloader.d.ts.map +1 -1
- package/dist/js/integrations/modulesloader.js +34 -31
- package/dist/js/integrations/modulesloader.js.map +1 -1
- package/dist/js/integrations/nativelinkederrors.d.ts +8 -51
- package/dist/js/integrations/nativelinkederrors.d.ts.map +1 -1
- package/dist/js/integrations/nativelinkederrors.js +112 -124
- package/dist/js/integrations/nativelinkederrors.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts +8 -54
- package/dist/js/integrations/reactnativeerrorhandlers.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlers.js +109 -199
- package/dist/js/integrations/reactnativeerrorhandlers.js.map +1 -1
- package/dist/js/integrations/reactnativeerrorhandlersutils.d.ts +27 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.d.ts.map +1 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.js +77 -0
- package/dist/js/integrations/reactnativeerrorhandlersutils.js.map +1 -0
- package/dist/js/integrations/reactnativeinfo.d.ts +8 -15
- package/dist/js/integrations/reactnativeinfo.d.ts.map +1 -1
- package/dist/js/integrations/reactnativeinfo.js +51 -51
- package/dist/js/integrations/reactnativeinfo.js.map +1 -1
- package/dist/js/integrations/release.d.ts +8 -15
- package/dist/js/integrations/release.d.ts.map +1 -1
- package/dist/js/integrations/release.js +55 -57
- package/dist/js/integrations/release.js.map +1 -1
- package/dist/js/integrations/rewriteframes.js +2 -2
- package/dist/js/integrations/rewriteframes.js.map +1 -1
- package/dist/js/integrations/screenshot.d.ts +8 -23
- package/dist/js/integrations/screenshot.d.ts.map +1 -1
- package/dist/js/integrations/screenshot.js +31 -47
- package/dist/js/integrations/screenshot.js.map +1 -1
- package/dist/js/integrations/sdkinfo.d.ts +8 -16
- package/dist/js/integrations/sdkinfo.d.ts.map +1 -1
- package/dist/js/integrations/sdkinfo.js +54 -41
- package/dist/js/integrations/sdkinfo.js.map +1 -1
- package/dist/js/integrations/spotlight.d.ts +10 -2
- package/dist/js/integrations/spotlight.d.ts.map +1 -1
- package/dist/js/integrations/spotlight.js +14 -9
- package/dist/js/integrations/spotlight.js.map +1 -1
- package/dist/js/integrations/viewhierarchy.d.ts +8 -18
- package/dist/js/integrations/viewhierarchy.d.ts.map +1 -1
- package/dist/js/integrations/viewhierarchy.js +46 -43
- package/dist/js/integrations/viewhierarchy.js.map +1 -1
- package/dist/js/options.d.ts +2 -24
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/profiling/integration.d.ts +8 -32
- package/dist/js/profiling/integration.d.ts.map +1 -1
- package/dist/js/profiling/integration.js +120 -119
- package/dist/js/profiling/integration.js.map +1 -1
- package/dist/js/tracing/nativeframes.d.ts +0 -4
- package/dist/js/tracing/nativeframes.d.ts.map +1 -1
- package/dist/js/tracing/nativeframes.js +14 -14
- package/dist/js/tracing/nativeframes.js.map +1 -1
- package/dist/js/utils/environment.d.ts +0 -4
- package/dist/js/utils/environment.d.ts.map +1 -1
- package/dist/js/utils/environment.js +0 -8
- package/dist/js/utils/environment.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.d.ts.map +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts +1 -7
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +0 -24
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +1 -47
- package/ios/RNSentryOnDrawReporter.h +23 -0
- package/ios/RNSentryOnDrawReporter.m +2 -17
- package/package.json +1 -9
- package/src/js/NativeRNSentry.ts +0 -2
- package/ts3.8/dist/js/NativeRNSentry.d.ts +0 -2
- package/ts3.8/dist/js/client.d.ts +0 -8
- package/ts3.8/dist/js/index.d.ts +5 -3
- package/ts3.8/dist/js/integrations/debugsymbolicator.d.ts +8 -60
- package/ts3.8/dist/js/integrations/debugsymbolicatorutils.d.ts +18 -0
- package/ts3.8/dist/js/integrations/devicecontext.d.ts +8 -15
- package/ts3.8/dist/js/integrations/eventorigin.d.ts +8 -15
- package/ts3.8/dist/js/integrations/expocontext.d.ts +8 -15
- package/ts3.8/dist/js/integrations/exports.d.ts +16 -0
- package/ts3.8/dist/js/integrations/index.d.ts +4 -1
- package/ts3.8/dist/js/integrations/modulesloader.d.ts +8 -15
- package/ts3.8/dist/js/integrations/nativelinkederrors.d.ts +8 -51
- package/ts3.8/dist/js/integrations/reactnativeerrorhandlers.d.ts +8 -54
- package/ts3.8/dist/js/integrations/reactnativeerrorhandlersutils.d.ts +27 -0
- package/ts3.8/dist/js/integrations/reactnativeinfo.d.ts +8 -15
- package/ts3.8/dist/js/integrations/release.d.ts +8 -15
- package/ts3.8/dist/js/integrations/screenshot.d.ts +8 -23
- package/ts3.8/dist/js/integrations/sdkinfo.d.ts +8 -16
- package/ts3.8/dist/js/integrations/spotlight.d.ts +10 -2
- package/ts3.8/dist/js/integrations/viewhierarchy.d.ts +8 -18
- package/ts3.8/dist/js/options.d.ts +2 -24
- package/ts3.8/dist/js/profiling/integration.d.ts +8 -32
- package/ts3.8/dist/js/tracing/nativeframes.d.ts +0 -4
- package/ts3.8/dist/js/utils/environment.d.ts +0 -4
- package/ts3.8/dist/js/version.d.ts +1 -1
- package/ts3.8/dist/js/wrapper.d.ts +1 -7
- package/dist/js/integrations/mobilereplay.d.ts +0 -36
- package/dist/js/integrations/mobilereplay.d.ts.map +0 -1
- package/dist/js/integrations/mobilereplay.js +0 -97
- package/dist/js/integrations/mobilereplay.js.map +0 -1
- package/dist/js/utils/clientutils.d.ts +0 -8
- package/dist/js/utils/clientutils.d.ts.map +0 -1
- package/dist/js/utils/clientutils.js +0 -7
- package/dist/js/utils/clientutils.js.map +0 -1
- package/ts3.8/dist/js/integrations/mobilereplay.d.ts +0 -36
- package/ts3.8/dist/js/utils/clientutils.d.ts +0 -8
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable complexity */
|
|
2
|
+
import { convertIntegrationFnToClass, getActiveTransaction, getClient, getCurrentHub } from '@sentry/core';
|
|
2
3
|
import { logger, uuid4 } from '@sentry/utils';
|
|
3
4
|
import { Platform } from 'react-native';
|
|
4
5
|
import { isHermesEnabled } from '../utils/environment';
|
|
@@ -7,132 +8,28 @@ import { PROFILE_QUEUE } from './cache';
|
|
|
7
8
|
import { MAX_PROFILE_DURATION_MS } from './constants';
|
|
8
9
|
import { convertToSentryProfile } from './convertHermesProfile';
|
|
9
10
|
import { addProfilesToEnvelope, createHermesProfilingEvent, enrichCombinedProfileWithEventContext, findProfiledTransactionsFromEnvelope, } from './utils';
|
|
11
|
+
const INTEGRATION_NAME = 'HermesProfiling';
|
|
10
12
|
const MS_TO_NS = 1e6;
|
|
11
13
|
/**
|
|
12
14
|
* Profiling integration creates a profile for each transaction and adds it to the event envelope.
|
|
13
15
|
*
|
|
14
16
|
* @experimental
|
|
15
17
|
*/
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
this.name = HermesProfiling.id;
|
|
22
|
-
this._startCurrentProfileForActiveTransaction = () => {
|
|
23
|
-
if (this._currentProfile) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const transaction = this._getCurrentHub && getActiveTransaction(this._getCurrentHub());
|
|
27
|
-
transaction && this._startCurrentProfile(transaction);
|
|
28
|
-
};
|
|
29
|
-
this._startCurrentProfile = (transaction) => {
|
|
30
|
-
this._finishCurrentProfile();
|
|
31
|
-
const shouldStartProfiling = this._shouldStartProfiling(transaction);
|
|
32
|
-
if (!shouldStartProfiling) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
this._currentProfileTimeout = setTimeout(this._finishCurrentProfile, MAX_PROFILE_DURATION_MS);
|
|
36
|
-
this._startNewProfile(transaction);
|
|
37
|
-
};
|
|
38
|
-
this._shouldStartProfiling = (transaction) => {
|
|
39
|
-
if (!transaction.sampled) {
|
|
40
|
-
logger.log('[Profiling] Transaction is not sampled, skipping profiling');
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
const client = this._getCurrentHub && this._getCurrentHub().getClient();
|
|
44
|
-
const options = client && client.getOptions();
|
|
45
|
-
const profilesSampleRate = options && options._experiments && typeof options._experiments.profilesSampleRate === 'number'
|
|
46
|
-
? options._experiments.profilesSampleRate
|
|
47
|
-
: undefined;
|
|
48
|
-
if (profilesSampleRate === undefined) {
|
|
49
|
-
logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
// Check if we should sample this profile
|
|
53
|
-
if (Math.random() > profilesSampleRate) {
|
|
54
|
-
logger.log('[Profiling] Skip profiling transaction due to sampling.');
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Starts a new profile and links it to the transaction.
|
|
61
|
-
*/
|
|
62
|
-
this._startNewProfile = (transaction) => {
|
|
63
|
-
const profileStartTimestampNs = startProfiling();
|
|
64
|
-
if (!profileStartTimestampNs) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
this._currentProfile = {
|
|
68
|
-
profile_id: uuid4(),
|
|
69
|
-
startTimestampNs: profileStartTimestampNs,
|
|
70
|
-
};
|
|
71
|
-
transaction.setContext('profile', { profile_id: this._currentProfile.profile_id });
|
|
72
|
-
// @ts-expect-error profile_id is not part of the metadata type
|
|
73
|
-
transaction.setMetadata({ profile_id: this._currentProfile.profile_id });
|
|
74
|
-
logger.log('[Profiling] started profiling: ', this._currentProfile.profile_id);
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.
|
|
78
|
-
*/
|
|
79
|
-
this._finishCurrentProfile = () => {
|
|
80
|
-
this._clearCurrentProfileTimeout();
|
|
81
|
-
if (this._currentProfile === undefined) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const profile = stopProfiling(this._currentProfile.startTimestampNs);
|
|
85
|
-
if (!profile) {
|
|
86
|
-
logger.warn('[Profiling] Stop failed. Cleaning up...');
|
|
87
|
-
this._currentProfile = undefined;
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
PROFILE_QUEUE.add(this._currentProfile.profile_id, profile);
|
|
91
|
-
logger.log('[Profiling] finished profiling: ', this._currentProfile.profile_id);
|
|
92
|
-
this._currentProfile = undefined;
|
|
93
|
-
};
|
|
94
|
-
this._createProfileEventFor = (profiledTransaction) => {
|
|
95
|
-
var _a, _b, _c;
|
|
96
|
-
const profile_id = (_b = (_a = profiledTransaction === null || profiledTransaction === void 0 ? void 0 : profiledTransaction.contexts) === null || _a === void 0 ? void 0 : _a['profile']) === null || _b === void 0 ? void 0 : _b['profile_id'];
|
|
97
|
-
if (typeof profile_id !== 'string') {
|
|
98
|
-
logger.log('[Profiling] cannot find profile for a transaction without a profile context');
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
// Remove the profile from the transaction context before sending, relay will take care of the rest.
|
|
102
|
-
if ((_c = profiledTransaction === null || profiledTransaction === void 0 ? void 0 : profiledTransaction.contexts) === null || _c === void 0 ? void 0 : _c['.profile']) {
|
|
103
|
-
delete profiledTransaction.contexts.profile;
|
|
104
|
-
}
|
|
105
|
-
const profile = PROFILE_QUEUE.get(profile_id);
|
|
106
|
-
PROFILE_QUEUE.delete(profile_id);
|
|
107
|
-
if (!profile) {
|
|
108
|
-
logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);
|
|
112
|
-
logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);
|
|
113
|
-
return profileWithEvent;
|
|
114
|
-
};
|
|
115
|
-
this._clearCurrentProfileTimeout = () => {
|
|
116
|
-
this._currentProfileTimeout !== undefined && clearTimeout(this._currentProfileTimeout);
|
|
117
|
-
this._currentProfileTimeout = undefined;
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* @inheritDoc
|
|
122
|
-
*/
|
|
123
|
-
setupOnce(_, getCurrentHub) {
|
|
18
|
+
export const hermesProfilingIntegration = () => {
|
|
19
|
+
let _currentProfile;
|
|
20
|
+
let _currentProfileTimeout;
|
|
21
|
+
const setupOnce = () => {
|
|
124
22
|
if (!isHermesEnabled()) {
|
|
125
23
|
logger.log('[Profiling] Hermes is not enabled, not adding profiling integration.');
|
|
126
24
|
return;
|
|
127
25
|
}
|
|
128
|
-
|
|
129
|
-
const client = getCurrentHub().getClient();
|
|
26
|
+
const client = getClient();
|
|
130
27
|
if (!client || typeof client.on !== 'function') {
|
|
131
28
|
return;
|
|
132
29
|
}
|
|
133
|
-
|
|
134
|
-
client.on('startTransaction',
|
|
135
|
-
client.on('finishTransaction',
|
|
30
|
+
_startCurrentProfileForActiveTransaction();
|
|
31
|
+
client.on('startTransaction', _startCurrentProfile);
|
|
32
|
+
client.on('finishTransaction', _finishCurrentProfile);
|
|
136
33
|
client.on('beforeEnvelope', (envelope) => {
|
|
137
34
|
if (!PROFILE_QUEUE.size()) {
|
|
138
35
|
return;
|
|
@@ -144,19 +41,123 @@ export class HermesProfiling {
|
|
|
144
41
|
}
|
|
145
42
|
const profilesToAddToEnvelope = [];
|
|
146
43
|
for (const profiledTransaction of profiledTransactions) {
|
|
147
|
-
const profile =
|
|
44
|
+
const profile = _createProfileEventFor(profiledTransaction);
|
|
148
45
|
if (profile) {
|
|
149
46
|
profilesToAddToEnvelope.push(profile);
|
|
150
47
|
}
|
|
151
48
|
}
|
|
152
49
|
addProfilesToEnvelope(envelope, profilesToAddToEnvelope);
|
|
153
50
|
});
|
|
154
|
-
}
|
|
155
|
-
|
|
51
|
+
};
|
|
52
|
+
const _startCurrentProfileForActiveTransaction = () => {
|
|
53
|
+
if (_currentProfile) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const transaction = getActiveTransaction(getCurrentHub());
|
|
57
|
+
transaction && _startCurrentProfile(transaction);
|
|
58
|
+
};
|
|
59
|
+
const _startCurrentProfile = (transaction) => {
|
|
60
|
+
_finishCurrentProfile();
|
|
61
|
+
const shouldStartProfiling = _shouldStartProfiling(transaction);
|
|
62
|
+
if (!shouldStartProfiling) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
_currentProfileTimeout = setTimeout(_finishCurrentProfile, MAX_PROFILE_DURATION_MS);
|
|
66
|
+
_startNewProfile(transaction);
|
|
67
|
+
};
|
|
68
|
+
const _shouldStartProfiling = (transaction) => {
|
|
69
|
+
if (!transaction.sampled) {
|
|
70
|
+
logger.log('[Profiling] Transaction is not sampled, skipping profiling');
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const client = getClient();
|
|
74
|
+
const options = client && client.getOptions();
|
|
75
|
+
const profilesSampleRate = options && options._experiments && typeof options._experiments.profilesSampleRate === 'number'
|
|
76
|
+
? options._experiments.profilesSampleRate
|
|
77
|
+
: undefined;
|
|
78
|
+
if (profilesSampleRate === undefined) {
|
|
79
|
+
logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
// Check if we should sample this profile
|
|
83
|
+
if (Math.random() > profilesSampleRate) {
|
|
84
|
+
logger.log('[Profiling] Skip profiling transaction due to sampling.');
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Starts a new profile and links it to the transaction.
|
|
91
|
+
*/
|
|
92
|
+
const _startNewProfile = (transaction) => {
|
|
93
|
+
const profileStartTimestampNs = startProfiling();
|
|
94
|
+
if (!profileStartTimestampNs) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
_currentProfile = {
|
|
98
|
+
profile_id: uuid4(),
|
|
99
|
+
startTimestampNs: profileStartTimestampNs,
|
|
100
|
+
};
|
|
101
|
+
transaction.setContext('profile', { profile_id: _currentProfile.profile_id });
|
|
102
|
+
// @ts-expect-error profile_id is not part of the metadata type
|
|
103
|
+
transaction.setMetadata({ profile_id: _currentProfile.profile_id });
|
|
104
|
+
logger.log('[Profiling] started profiling: ', _currentProfile.profile_id);
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.
|
|
108
|
+
*/
|
|
109
|
+
const _finishCurrentProfile = () => {
|
|
110
|
+
_clearCurrentProfileTimeout();
|
|
111
|
+
if (_currentProfile === undefined) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const profile = stopProfiling(_currentProfile.startTimestampNs);
|
|
115
|
+
if (!profile) {
|
|
116
|
+
logger.warn('[Profiling] Stop failed. Cleaning up...');
|
|
117
|
+
_currentProfile = undefined;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
PROFILE_QUEUE.add(_currentProfile.profile_id, profile);
|
|
121
|
+
logger.log('[Profiling] finished profiling: ', _currentProfile.profile_id);
|
|
122
|
+
_currentProfile = undefined;
|
|
123
|
+
};
|
|
124
|
+
const _createProfileEventFor = (profiledTransaction) => {
|
|
125
|
+
var _a, _b, _c;
|
|
126
|
+
const profile_id = (_b = (_a = profiledTransaction === null || profiledTransaction === void 0 ? void 0 : profiledTransaction.contexts) === null || _a === void 0 ? void 0 : _a['profile']) === null || _b === void 0 ? void 0 : _b['profile_id'];
|
|
127
|
+
if (typeof profile_id !== 'string') {
|
|
128
|
+
logger.log('[Profiling] cannot find profile for a transaction without a profile context');
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
// Remove the profile from the transaction context before sending, relay will take care of the rest.
|
|
132
|
+
if ((_c = profiledTransaction === null || profiledTransaction === void 0 ? void 0 : profiledTransaction.contexts) === null || _c === void 0 ? void 0 : _c['.profile']) {
|
|
133
|
+
delete profiledTransaction.contexts.profile;
|
|
134
|
+
}
|
|
135
|
+
const profile = PROFILE_QUEUE.get(profile_id);
|
|
136
|
+
PROFILE_QUEUE.delete(profile_id);
|
|
137
|
+
if (!profile) {
|
|
138
|
+
logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);
|
|
142
|
+
logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);
|
|
143
|
+
return profileWithEvent;
|
|
144
|
+
};
|
|
145
|
+
const _clearCurrentProfileTimeout = () => {
|
|
146
|
+
_currentProfileTimeout !== undefined && clearTimeout(_currentProfileTimeout);
|
|
147
|
+
_currentProfileTimeout = undefined;
|
|
148
|
+
};
|
|
149
|
+
return {
|
|
150
|
+
name: INTEGRATION_NAME,
|
|
151
|
+
setupOnce,
|
|
152
|
+
};
|
|
153
|
+
};
|
|
156
154
|
/**
|
|
157
|
-
*
|
|
155
|
+
* Profiling integration creates a profile for each transaction and adds it to the event envelope.
|
|
156
|
+
*
|
|
157
|
+
* @deprecated Use `hermesProfilingIntegration()` instead.
|
|
158
158
|
*/
|
|
159
|
-
|
|
159
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
160
|
+
export const HermesProfiling = convertIntegrationFnToClass(INTEGRATION_NAME, hermesProfilingIntegration);
|
|
160
161
|
/**
|
|
161
162
|
* Starts Profilers and returns the timestamp when profiling started in nanoseconds.
|
|
162
163
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/profiling/integration.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Hub } from '@sentry/core';\nimport { getActiveTransaction } from '@sentry/core';\nimport type { Envelope, Event, EventProcessor, Integration, ThreadCpuProfile, Transaction } from '@sentry/types';\nimport { logger, uuid4 } from '@sentry/utils';\nimport { Platform } from 'react-native';\n\nimport { isHermesEnabled } from '../utils/environment';\nimport { NATIVE } from '../wrapper';\nimport { PROFILE_QUEUE } from './cache';\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport { convertToSentryProfile } from './convertHermesProfile';\nimport type { NativeAndroidProfileEvent, NativeProfileEvent } from './nativeTypes';\nimport type { AndroidCombinedProfileEvent, CombinedProfileEvent, HermesProfileEvent, ProfileEvent } from './types';\nimport {\n addProfilesToEnvelope,\n createHermesProfilingEvent,\n enrichCombinedProfileWithEventContext,\n findProfiledTransactionsFromEnvelope,\n} from './utils';\n\nconst MS_TO_NS: number = 1e6;\n\n/**\n * Profiling integration creates a profile for each transaction and adds it to the event envelope.\n *\n * @experimental\n */\nexport class HermesProfiling implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'HermesProfiling';\n\n /**\n * @inheritDoc\n */\n public name: string = HermesProfiling.id;\n\n private _getCurrentHub?: () => Hub;\n\n private _currentProfile:\n | {\n profile_id: string;\n startTimestampNs: number;\n }\n | undefined;\n\n private _currentProfileTimeout: number | undefined;\n\n /**\n * @inheritDoc\n */\n public setupOnce(_: (e: EventProcessor) => void, getCurrentHub: () => Hub): void {\n if (!isHermesEnabled()) {\n logger.log('[Profiling] Hermes is not enabled, not adding profiling integration.');\n return;\n }\n\n this._getCurrentHub = getCurrentHub;\n const client = getCurrentHub().getClient();\n\n if (!client || typeof client.on !== 'function') {\n return;\n }\n\n this._startCurrentProfileForActiveTransaction();\n client.on('startTransaction', this._startCurrentProfile);\n\n client.on('finishTransaction', this._finishCurrentProfile);\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (!PROFILE_QUEUE.size()) {\n return;\n }\n\n const profiledTransactions = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactions.length) {\n logger.log('[Profiling] no profiled transactions found in envelope');\n return;\n }\n\n const profilesToAddToEnvelope: ProfileEvent[] = [];\n for (const profiledTransaction of profiledTransactions) {\n const profile = this._createProfileEventFor(profiledTransaction);\n if (profile) {\n profilesToAddToEnvelope.push(profile);\n }\n }\n addProfilesToEnvelope(envelope, profilesToAddToEnvelope);\n });\n }\n\n private _startCurrentProfileForActiveTransaction = (): void => {\n if (this._currentProfile) {\n return;\n }\n const transaction = this._getCurrentHub && getActiveTransaction(this._getCurrentHub());\n transaction && this._startCurrentProfile(transaction);\n };\n\n private _startCurrentProfile = (transaction: Transaction): void => {\n this._finishCurrentProfile();\n\n const shouldStartProfiling = this._shouldStartProfiling(transaction);\n if (!shouldStartProfiling) {\n return;\n }\n\n this._currentProfileTimeout = setTimeout(this._finishCurrentProfile, MAX_PROFILE_DURATION_MS);\n this._startNewProfile(transaction);\n };\n\n private _shouldStartProfiling = (transaction: Transaction): boolean => {\n if (!transaction.sampled) {\n logger.log('[Profiling] Transaction is not sampled, skipping profiling');\n return false;\n }\n\n const client = this._getCurrentHub && this._getCurrentHub().getClient();\n const options = client && client.getOptions();\n\n const profilesSampleRate =\n options && options._experiments && typeof options._experiments.profilesSampleRate === 'number'\n ? options._experiments.profilesSampleRate\n : undefined;\n if (profilesSampleRate === undefined) {\n logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');\n return false;\n }\n\n // Check if we should sample this profile\n if (Math.random() > profilesSampleRate) {\n logger.log('[Profiling] Skip profiling transaction due to sampling.');\n return false;\n }\n\n return true;\n };\n\n /**\n * Starts a new profile and links it to the transaction.\n */\n private _startNewProfile = (transaction: Transaction): void => {\n const profileStartTimestampNs = startProfiling();\n if (!profileStartTimestampNs) {\n return;\n }\n\n this._currentProfile = {\n profile_id: uuid4(),\n startTimestampNs: profileStartTimestampNs,\n };\n transaction.setContext('profile', { profile_id: this._currentProfile.profile_id });\n // @ts-expect-error profile_id is not part of the metadata type\n transaction.setMetadata({ profile_id: this._currentProfile.profile_id });\n logger.log('[Profiling] started profiling: ', this._currentProfile.profile_id);\n };\n\n /**\n * Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.\n */\n private _finishCurrentProfile = (): void => {\n this._clearCurrentProfileTimeout();\n if (this._currentProfile === undefined) {\n return;\n }\n\n const profile = stopProfiling(this._currentProfile.startTimestampNs);\n if (!profile) {\n logger.warn('[Profiling] Stop failed. Cleaning up...');\n this._currentProfile = undefined;\n return;\n }\n\n PROFILE_QUEUE.add(this._currentProfile.profile_id, profile);\n\n logger.log('[Profiling] finished profiling: ', this._currentProfile.profile_id);\n this._currentProfile = undefined;\n };\n\n private _createProfileEventFor = (profiledTransaction: Event): ProfileEvent | null => {\n const profile_id = profiledTransaction?.contexts?.['profile']?.['profile_id'];\n\n if (typeof profile_id !== 'string') {\n logger.log('[Profiling] cannot find profile for a transaction without a profile context');\n return null;\n }\n\n // Remove the profile from the transaction context before sending, relay will take care of the rest.\n if (profiledTransaction?.contexts?.['.profile']) {\n delete profiledTransaction.contexts.profile;\n }\n\n const profile = PROFILE_QUEUE.get(profile_id);\n PROFILE_QUEUE.delete(profile_id);\n\n if (!profile) {\n logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n return null;\n }\n\n const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);\n logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n\n return profileWithEvent;\n };\n\n private _clearCurrentProfileTimeout = (): void => {\n this._currentProfileTimeout !== undefined && clearTimeout(this._currentProfileTimeout);\n this._currentProfileTimeout = undefined;\n };\n}\n\n/**\n * Starts Profilers and returns the timestamp when profiling started in nanoseconds.\n */\nexport function startProfiling(): number | null {\n const started = NATIVE.startProfiling();\n if (!started) {\n return null;\n }\n\n return Date.now() * MS_TO_NS;\n}\n\n/**\n * Stops Profilers and returns collected combined profile.\n */\nexport function stopProfiling(\n profileStartTimestampNs: number,\n): CombinedProfileEvent | AndroidCombinedProfileEvent | null {\n const collectedProfiles = NATIVE.stopProfiling();\n if (!collectedProfiles) {\n return null;\n }\n const profileEndTimestampNs = Date.now() * MS_TO_NS;\n\n const hermesProfile = convertToSentryProfile(collectedProfiles.hermesProfile);\n if (!hermesProfile) {\n return null;\n }\n\n const hermesProfileEvent = createHermesProfilingEvent(hermesProfile);\n if (!hermesProfileEvent) {\n return null;\n }\n\n if (collectedProfiles.androidProfile) {\n const durationNs = profileEndTimestampNs - profileStartTimestampNs;\n return createAndroidWithHermesProfile(hermesProfileEvent, collectedProfiles.androidProfile, durationNs);\n } else if (collectedProfiles.nativeProfile) {\n return addNativeProfileToHermesProfile(hermesProfileEvent, collectedProfiles.nativeProfile);\n }\n\n return hermesProfileEvent;\n}\n\n/**\n * Creates Android profile event with attached javascript profile.\n */\nexport function createAndroidWithHermesProfile(\n hermes: HermesProfileEvent,\n nativeAndroid: NativeAndroidProfileEvent,\n durationNs: number,\n): AndroidCombinedProfileEvent {\n return {\n ...nativeAndroid,\n platform: 'android',\n js_profile: hermes.profile,\n duration_ns: durationNs.toString(10),\n active_thread_id: hermes.transaction.active_thread_id,\n };\n}\n\n/**\n * Merges Hermes and Native profile events into one.\n */\nexport function addNativeProfileToHermesProfile(\n hermes: HermesProfileEvent,\n native: NativeProfileEvent,\n): CombinedProfileEvent {\n return {\n ...hermes,\n profile: addNativeThreadCpuProfileToHermes(hermes.profile, native.profile, hermes.transaction.active_thread_id),\n debug_meta: {\n images: native.debug_meta.images,\n },\n measurements: native.measurements,\n };\n}\n\n/**\n * Merges Hermes And Native profiles into one.\n */\nexport function addNativeThreadCpuProfileToHermes(\n hermes: ThreadCpuProfile,\n native: ThreadCpuProfile,\n hermes_active_thread_id: string | undefined,\n): CombinedProfileEvent['profile'] {\n // assumes thread ids are unique\n hermes.thread_metadata = { ...native.thread_metadata, ...hermes.thread_metadata };\n // assumes queue ids are unique\n hermes.queue_metadata = { ...native.queue_metadata, ...hermes.queue_metadata };\n\n // recalculate frames and stacks using offset\n const framesOffset = hermes.frames.length;\n const stacksOffset = hermes.stacks.length;\n\n if (native.frames) {\n for (const frame of native.frames) {\n hermes.frames.push({\n function: frame.function,\n instruction_addr: frame.instruction_addr,\n platform: Platform.OS === 'ios' ? 'cocoa' : undefined,\n });\n }\n }\n hermes.stacks = [\n ...(hermes.stacks || []),\n ...(native.stacks || []).map(stack => stack.map(frameId => frameId + framesOffset)),\n ];\n hermes.samples = [\n ...(hermes.samples || []),\n ...(native.samples || [])\n .filter(sample => sample.thread_id !== hermes_active_thread_id)\n .map(sample => ({\n ...sample,\n stack_id: stacksOffset + sample.stack_id,\n })),\n ];\n\n return hermes;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../src/js/profiling/integration.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport { convertIntegrationFnToClass, getActiveTransaction, getClient, getCurrentHub } from '@sentry/core';\nimport type {\n Envelope,\n Event,\n Integration,\n IntegrationClass,\n IntegrationFn,\n ThreadCpuProfile,\n Transaction,\n} from '@sentry/types';\nimport { logger, uuid4 } from '@sentry/utils';\nimport { Platform } from 'react-native';\n\nimport { isHermesEnabled } from '../utils/environment';\nimport { NATIVE } from '../wrapper';\nimport { PROFILE_QUEUE } from './cache';\nimport { MAX_PROFILE_DURATION_MS } from './constants';\nimport { convertToSentryProfile } from './convertHermesProfile';\nimport type { NativeAndroidProfileEvent, NativeProfileEvent } from './nativeTypes';\nimport type { AndroidCombinedProfileEvent, CombinedProfileEvent, HermesProfileEvent, ProfileEvent } from './types';\nimport {\n addProfilesToEnvelope,\n createHermesProfilingEvent,\n enrichCombinedProfileWithEventContext,\n findProfiledTransactionsFromEnvelope,\n} from './utils';\n\nconst INTEGRATION_NAME = 'HermesProfiling';\n\nconst MS_TO_NS: number = 1e6;\n\n/**\n * Profiling integration creates a profile for each transaction and adds it to the event envelope.\n *\n * @experimental\n */\nexport const hermesProfilingIntegration: IntegrationFn = () => {\n let _currentProfile:\n | {\n profile_id: string;\n startTimestampNs: number;\n }\n | undefined;\n let _currentProfileTimeout: number | undefined;\n\n const setupOnce = (): void => {\n if (!isHermesEnabled()) {\n logger.log('[Profiling] Hermes is not enabled, not adding profiling integration.');\n return;\n }\n\n const client = getClient();\n\n if (!client || typeof client.on !== 'function') {\n return;\n }\n\n _startCurrentProfileForActiveTransaction();\n client.on('startTransaction', _startCurrentProfile);\n\n client.on('finishTransaction', _finishCurrentProfile);\n\n client.on('beforeEnvelope', (envelope: Envelope) => {\n if (!PROFILE_QUEUE.size()) {\n return;\n }\n\n const profiledTransactions = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactions.length) {\n logger.log('[Profiling] no profiled transactions found in envelope');\n return;\n }\n\n const profilesToAddToEnvelope: ProfileEvent[] = [];\n for (const profiledTransaction of profiledTransactions) {\n const profile = _createProfileEventFor(profiledTransaction);\n if (profile) {\n profilesToAddToEnvelope.push(profile);\n }\n }\n addProfilesToEnvelope(envelope, profilesToAddToEnvelope);\n });\n };\n\n const _startCurrentProfileForActiveTransaction = (): void => {\n if (_currentProfile) {\n return;\n }\n const transaction = getActiveTransaction(getCurrentHub());\n transaction && _startCurrentProfile(transaction);\n };\n\n const _startCurrentProfile = (transaction: Transaction): void => {\n _finishCurrentProfile();\n\n const shouldStartProfiling = _shouldStartProfiling(transaction);\n if (!shouldStartProfiling) {\n return;\n }\n\n _currentProfileTimeout = setTimeout(_finishCurrentProfile, MAX_PROFILE_DURATION_MS);\n _startNewProfile(transaction);\n };\n\n const _shouldStartProfiling = (transaction: Transaction): boolean => {\n if (!transaction.sampled) {\n logger.log('[Profiling] Transaction is not sampled, skipping profiling');\n return false;\n }\n\n const client = getClient();\n const options = client && client.getOptions();\n\n const profilesSampleRate =\n options && options._experiments && typeof options._experiments.profilesSampleRate === 'number'\n ? options._experiments.profilesSampleRate\n : undefined;\n if (profilesSampleRate === undefined) {\n logger.log('[Profiling] Profiling disabled, enable it by setting `profilesSampleRate` option to SDK init call.');\n return false;\n }\n\n // Check if we should sample this profile\n if (Math.random() > profilesSampleRate) {\n logger.log('[Profiling] Skip profiling transaction due to sampling.');\n return false;\n }\n\n return true;\n };\n\n /**\n * Starts a new profile and links it to the transaction.\n */\n const _startNewProfile = (transaction: Transaction): void => {\n const profileStartTimestampNs = startProfiling();\n if (!profileStartTimestampNs) {\n return;\n }\n\n _currentProfile = {\n profile_id: uuid4(),\n startTimestampNs: profileStartTimestampNs,\n };\n transaction.setContext('profile', { profile_id: _currentProfile.profile_id });\n // @ts-expect-error profile_id is not part of the metadata type\n transaction.setMetadata({ profile_id: _currentProfile.profile_id });\n logger.log('[Profiling] started profiling: ', _currentProfile.profile_id);\n };\n\n /**\n * Stops profiling and adds the profile to the queue to be processed on beforeEnvelope.\n */\n const _finishCurrentProfile = (): void => {\n _clearCurrentProfileTimeout();\n if (_currentProfile === undefined) {\n return;\n }\n\n const profile = stopProfiling(_currentProfile.startTimestampNs);\n if (!profile) {\n logger.warn('[Profiling] Stop failed. Cleaning up...');\n _currentProfile = undefined;\n return;\n }\n\n PROFILE_QUEUE.add(_currentProfile.profile_id, profile);\n\n logger.log('[Profiling] finished profiling: ', _currentProfile.profile_id);\n _currentProfile = undefined;\n };\n\n const _createProfileEventFor = (profiledTransaction: Event): ProfileEvent | null => {\n const profile_id = profiledTransaction?.contexts?.['profile']?.['profile_id'];\n\n if (typeof profile_id !== 'string') {\n logger.log('[Profiling] cannot find profile for a transaction without a profile context');\n return null;\n }\n\n // Remove the profile from the transaction context before sending, relay will take care of the rest.\n if (profiledTransaction?.contexts?.['.profile']) {\n delete profiledTransaction.contexts.profile;\n }\n\n const profile = PROFILE_QUEUE.get(profile_id);\n PROFILE_QUEUE.delete(profile_id);\n\n if (!profile) {\n logger.log(`[Profiling] cannot find profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n return null;\n }\n\n const profileWithEvent = enrichCombinedProfileWithEventContext(profile_id, profile, profiledTransaction);\n logger.log(`[Profiling] Created profile ${profile_id} for transaction ${profiledTransaction.event_id}`);\n\n return profileWithEvent;\n };\n\n const _clearCurrentProfileTimeout = (): void => {\n _currentProfileTimeout !== undefined && clearTimeout(_currentProfileTimeout);\n _currentProfileTimeout = undefined;\n };\n\n return {\n name: INTEGRATION_NAME,\n setupOnce,\n };\n};\n\n/**\n * Profiling integration creates a profile for each transaction and adds it to the event envelope.\n *\n * @deprecated Use `hermesProfilingIntegration()` instead.\n */\n// eslint-disable-next-line deprecation/deprecation\nexport const HermesProfiling = convertIntegrationFnToClass(\n INTEGRATION_NAME,\n hermesProfilingIntegration,\n) as IntegrationClass<Integration>;\n\n/**\n * Starts Profilers and returns the timestamp when profiling started in nanoseconds.\n */\nexport function startProfiling(): number | null {\n const started = NATIVE.startProfiling();\n if (!started) {\n return null;\n }\n\n return Date.now() * MS_TO_NS;\n}\n\n/**\n * Stops Profilers and returns collected combined profile.\n */\nexport function stopProfiling(\n profileStartTimestampNs: number,\n): CombinedProfileEvent | AndroidCombinedProfileEvent | null {\n const collectedProfiles = NATIVE.stopProfiling();\n if (!collectedProfiles) {\n return null;\n }\n const profileEndTimestampNs = Date.now() * MS_TO_NS;\n\n const hermesProfile = convertToSentryProfile(collectedProfiles.hermesProfile);\n if (!hermesProfile) {\n return null;\n }\n\n const hermesProfileEvent = createHermesProfilingEvent(hermesProfile);\n if (!hermesProfileEvent) {\n return null;\n }\n\n if (collectedProfiles.androidProfile) {\n const durationNs = profileEndTimestampNs - profileStartTimestampNs;\n return createAndroidWithHermesProfile(hermesProfileEvent, collectedProfiles.androidProfile, durationNs);\n } else if (collectedProfiles.nativeProfile) {\n return addNativeProfileToHermesProfile(hermesProfileEvent, collectedProfiles.nativeProfile);\n }\n\n return hermesProfileEvent;\n}\n\n/**\n * Creates Android profile event with attached javascript profile.\n */\nexport function createAndroidWithHermesProfile(\n hermes: HermesProfileEvent,\n nativeAndroid: NativeAndroidProfileEvent,\n durationNs: number,\n): AndroidCombinedProfileEvent {\n return {\n ...nativeAndroid,\n platform: 'android',\n js_profile: hermes.profile,\n duration_ns: durationNs.toString(10),\n active_thread_id: hermes.transaction.active_thread_id,\n };\n}\n\n/**\n * Merges Hermes and Native profile events into one.\n */\nexport function addNativeProfileToHermesProfile(\n hermes: HermesProfileEvent,\n native: NativeProfileEvent,\n): CombinedProfileEvent {\n return {\n ...hermes,\n profile: addNativeThreadCpuProfileToHermes(hermes.profile, native.profile, hermes.transaction.active_thread_id),\n debug_meta: {\n images: native.debug_meta.images,\n },\n measurements: native.measurements,\n };\n}\n\n/**\n * Merges Hermes And Native profiles into one.\n */\nexport function addNativeThreadCpuProfileToHermes(\n hermes: ThreadCpuProfile,\n native: ThreadCpuProfile,\n hermes_active_thread_id: string | undefined,\n): CombinedProfileEvent['profile'] {\n // assumes thread ids are unique\n hermes.thread_metadata = { ...native.thread_metadata, ...hermes.thread_metadata };\n // assumes queue ids are unique\n hermes.queue_metadata = { ...native.queue_metadata, ...hermes.queue_metadata };\n\n // recalculate frames and stacks using offset\n const framesOffset = hermes.frames.length;\n const stacksOffset = hermes.stacks.length;\n\n if (native.frames) {\n for (const frame of native.frames) {\n hermes.frames.push({\n function: frame.function,\n instruction_addr: frame.instruction_addr,\n platform: Platform.OS === 'ios' ? 'cocoa' : undefined,\n });\n }\n }\n hermes.stacks = [\n ...(hermes.stacks || []),\n ...(native.stacks || []).map(stack => stack.map(frameId => frameId + framesOffset)),\n ];\n hermes.samples = [\n ...(hermes.samples || []),\n ...(native.samples || [])\n .filter(sample => sample.thread_id !== hermes_active_thread_id)\n .map(sample => ({\n ...sample,\n stack_id: stacksOffset + sample.stack_id,\n })),\n ];\n\n return hermes;\n}\n"]}
|
|
@@ -18,10 +18,6 @@ export interface FramesMeasurements extends Measurements {
|
|
|
18
18
|
* Instrumentation to add native slow/frozen frames measurements onto transactions.
|
|
19
19
|
*/
|
|
20
20
|
export declare class NativeFramesInstrumentation {
|
|
21
|
-
/** The native frames at the transaction finish time, keyed by traceId. */
|
|
22
|
-
private _finishFrames;
|
|
23
|
-
/** The listeners for each native frames response, keyed by traceId */
|
|
24
|
-
private _framesListeners;
|
|
25
21
|
/** The native frames at the finish time of the most recent span. */
|
|
26
22
|
private _lastSpanFinishFrames?;
|
|
27
23
|
constructor(addGlobalEventProcessor: (e: EventProcessor) => void, doesExist: () => boolean);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeframes.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/nativeframes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAS,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAO1F,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACvD,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACtD,aAAa,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CACzD;
|
|
1
|
+
{"version":3,"file":"nativeframes.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/nativeframes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAS,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAO1F,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACvD,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACtD,aAAa,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CACzD;AAcD;;GAEG;AACH,qBAAa,2BAA2B;IACtC,oEAAoE;IACpE,OAAO,CAAC,qBAAqB,CAAC,CAG5B;gBAEiB,uBAAuB,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,EAAE,SAAS,EAAE,MAAM,OAAO;IAMjG;;;OAGG;IACI,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAkBzD;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAM1D;;;OAGG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;YACW,sBAAsB;IAyBpC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA4C5B;;OAEG;YACW,0BAA0B;IAoBxC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAU3B;;;OAGG;YACW,aAAa;CA+C5B"}
|
|
@@ -2,6 +2,10 @@ import { __awaiter } from "tslib";
|
|
|
2
2
|
import { logger, timestampInSeconds } from '@sentry/utils';
|
|
3
3
|
import { NATIVE } from '../wrapper';
|
|
4
4
|
import { instrumentChildSpanFinish } from './utils';
|
|
5
|
+
/** The listeners for each native frames response, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */
|
|
6
|
+
const _framesListeners = new Map();
|
|
7
|
+
/** The native frames at the transaction finish time, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */
|
|
8
|
+
const _finishFrames = new Map();
|
|
5
9
|
/**
|
|
6
10
|
* A margin of error of 50ms is allowed for the async native bridge call.
|
|
7
11
|
* Anything larger would reduce the accuracy of our frames measurements.
|
|
@@ -12,10 +16,6 @@ const MARGIN_OF_ERROR_SECONDS = 0.05;
|
|
|
12
16
|
*/
|
|
13
17
|
export class NativeFramesInstrumentation {
|
|
14
18
|
constructor(addGlobalEventProcessor, doesExist) {
|
|
15
|
-
/** The native frames at the transaction finish time, keyed by traceId. */
|
|
16
|
-
this._finishFrames = new Map();
|
|
17
|
-
/** The listeners for each native frames response, keyed by traceId */
|
|
18
|
-
this._framesListeners = new Map();
|
|
19
19
|
logger.log('[ReactNativeTracing] Native frames instrumentation initialized.');
|
|
20
20
|
addGlobalEventProcessor(event => this._processEvent(event, doesExist));
|
|
21
21
|
}
|
|
@@ -71,18 +71,18 @@ export class NativeFramesInstrumentation {
|
|
|
71
71
|
*/
|
|
72
72
|
_getFramesMeasurements(traceId, finalEndTimestamp, startFrames) {
|
|
73
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
-
if (
|
|
74
|
+
if (_finishFrames.has(traceId)) {
|
|
75
75
|
return this._prepareMeasurements(traceId, finalEndTimestamp, startFrames);
|
|
76
76
|
}
|
|
77
77
|
return new Promise(resolve => {
|
|
78
78
|
const timeout = setTimeout(() => {
|
|
79
|
-
|
|
79
|
+
_framesListeners.delete(traceId);
|
|
80
80
|
resolve(null);
|
|
81
81
|
}, 2000);
|
|
82
|
-
|
|
82
|
+
_framesListeners.set(traceId, () => {
|
|
83
83
|
resolve(this._prepareMeasurements(traceId, finalEndTimestamp, startFrames));
|
|
84
84
|
clearTimeout(timeout);
|
|
85
|
-
|
|
85
|
+
_framesListeners.delete(traceId);
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
});
|
|
@@ -93,7 +93,7 @@ export class NativeFramesInstrumentation {
|
|
|
93
93
|
_prepareMeasurements(traceId, finalEndTimestamp, // The actual transaction finish time.
|
|
94
94
|
startFrames) {
|
|
95
95
|
let finalFinishFrames;
|
|
96
|
-
const finish =
|
|
96
|
+
const finish = _finishFrames.get(traceId);
|
|
97
97
|
if (finish &&
|
|
98
98
|
finish.nativeFrames &&
|
|
99
99
|
// Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)
|
|
@@ -138,11 +138,11 @@ export class NativeFramesInstrumentation {
|
|
|
138
138
|
if (startFrames) {
|
|
139
139
|
finishFrames = yield NATIVE.fetchNativeFrames();
|
|
140
140
|
}
|
|
141
|
-
|
|
141
|
+
_finishFrames.set(transaction.traceId, {
|
|
142
142
|
nativeFrames: finishFrames,
|
|
143
143
|
timestamp,
|
|
144
144
|
});
|
|
145
|
-
(_a =
|
|
145
|
+
(_a = _framesListeners.get(transaction.traceId)) === null || _a === void 0 ? void 0 : _a();
|
|
146
146
|
setTimeout(() => this._cancelFinishFrames(transaction), 2000);
|
|
147
147
|
});
|
|
148
148
|
}
|
|
@@ -150,8 +150,8 @@ export class NativeFramesInstrumentation {
|
|
|
150
150
|
* On a finish frames failure, we cancel the await.
|
|
151
151
|
*/
|
|
152
152
|
_cancelFinishFrames(transaction) {
|
|
153
|
-
if (
|
|
154
|
-
|
|
153
|
+
if (_finishFrames.has(transaction.traceId)) {
|
|
154
|
+
_finishFrames.delete(transaction.traceId);
|
|
155
155
|
logger.log(`[NativeFrames] Native frames timed out for ${transaction.op} transaction ${transaction.name}. Not adding native frames measurements.`);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
@@ -176,7 +176,7 @@ export class NativeFramesInstrumentation {
|
|
|
176
176
|
else {
|
|
177
177
|
logger.log(`[Measurements] Adding measurements to ${traceContext.op} transaction ${event.transaction}: ${JSON.stringify(measurements, undefined, 2)}`);
|
|
178
178
|
event.measurements = Object.assign(Object.assign({}, ((_b = event.measurements) !== null && _b !== void 0 ? _b : {})), measurements);
|
|
179
|
-
|
|
179
|
+
_finishFrames.delete(traceId);
|
|
180
180
|
}
|
|
181
181
|
delete traceContext.data.__startFrames;
|
|
182
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeframes.js","sourceRoot":"","sources":["../../../src/js/tracing/nativeframes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Span, Transaction } from '@sentry/core';\nimport type { Event, EventProcessor, Measurements, MeasurementUnit } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nimport type { NativeFramesResponse } from '../NativeRNSentry';\nimport { NATIVE } from '../wrapper';\nimport { instrumentChildSpanFinish } from './utils';\n\nexport interface FramesMeasurements extends Measurements {\n frames_total: { value: number; unit: MeasurementUnit };\n frames_slow: { value: number; unit: MeasurementUnit };\n frames_frozen: { value: number; unit: MeasurementUnit };\n}\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nconst MARGIN_OF_ERROR_SECONDS = 0.05;\n\n/**\n * Instrumentation to add native slow/frozen frames measurements onto transactions.\n */\nexport class NativeFramesInstrumentation {\n /** The native frames at the transaction finish time, keyed by traceId. */\n private _finishFrames: Map<string, { timestamp: number; nativeFrames: NativeFramesResponse | null }> = new Map();\n /** The listeners for each native frames response, keyed by traceId */\n private _framesListeners: Map<string, () => void> = new Map();\n /** The native frames at the finish time of the most recent span. */\n private _lastSpanFinishFrames?: {\n timestamp: number;\n nativeFrames: NativeFramesResponse;\n };\n\n public constructor(addGlobalEventProcessor: (e: EventProcessor) => void, doesExist: () => boolean) {\n logger.log('[ReactNativeTracing] Native frames instrumentation initialized.');\n\n addGlobalEventProcessor(event => this._processEvent(event, doesExist));\n }\n\n /**\n * To be called when a transaction is started.\n * Logs the native frames at this start point and instruments child span finishes.\n */\n public onTransactionStart(transaction: Transaction): void {\n void NATIVE.fetchNativeFrames()\n .then(framesMetrics => {\n if (framesMetrics) {\n transaction.setData('__startFrames', framesMetrics);\n }\n })\n .then(undefined, error => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames: ${error}`);\n });\n\n instrumentChildSpanFinish(transaction, (_: Span, endTimestamp?: number) => {\n if (!endTimestamp) {\n this._onSpanFinish();\n }\n });\n }\n\n /**\n * To be called when a transaction is finished\n */\n public onTransactionFinish(transaction: Transaction): void {\n this._fetchFramesForTransaction(transaction).then(undefined, (reason: unknown) => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames:`, reason);\n });\n }\n\n /**\n * Called on a span finish to fetch native frames to support transactions with trimEnd.\n * Only to be called when a span does not have an end timestamp.\n */\n private _onSpanFinish(): void {\n const timestamp = timestampInSeconds();\n\n void NATIVE.fetchNativeFrames()\n .then(nativeFrames => {\n if (nativeFrames) {\n this._lastSpanFinishFrames = {\n timestamp,\n nativeFrames,\n };\n }\n })\n .then(undefined, error => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames: ${error}`);\n });\n }\n\n /**\n * Returns the computed frames measurements and awaits for them if they are not ready yet.\n */\n private async _getFramesMeasurements(\n traceId: string,\n finalEndTimestamp: number,\n startFrames: NativeFramesResponse,\n ): Promise<FramesMeasurements | null> {\n if (this._finishFrames.has(traceId)) {\n return this._prepareMeasurements(traceId, finalEndTimestamp, startFrames);\n }\n\n return new Promise(resolve => {\n const timeout = setTimeout(() => {\n this._framesListeners.delete(traceId);\n\n resolve(null);\n }, 2000);\n\n this._framesListeners.set(traceId, () => {\n resolve(this._prepareMeasurements(traceId, finalEndTimestamp, startFrames));\n\n clearTimeout(timeout);\n this._framesListeners.delete(traceId);\n });\n });\n }\n\n /**\n * Returns the computed frames measurements given ready data\n */\n private _prepareMeasurements(\n traceId: string,\n finalEndTimestamp: number, // The actual transaction finish time.\n startFrames: NativeFramesResponse,\n ): FramesMeasurements | null {\n let finalFinishFrames: NativeFramesResponse | undefined;\n\n const finish = this._finishFrames.get(traceId);\n if (\n finish &&\n finish.nativeFrames &&\n // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)\n Math.abs(finish.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n finalFinishFrames = finish.nativeFrames;\n } else if (\n this._lastSpanFinishFrames &&\n Math.abs(this._lastSpanFinishFrames.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.\n // This should be the case for trimEnd.\n finalFinishFrames = this._lastSpanFinishFrames.nativeFrames;\n } else {\n return null;\n }\n\n const measurements = {\n frames_total: {\n value: finalFinishFrames.totalFrames - startFrames.totalFrames,\n unit: 'none',\n },\n frames_frozen: {\n value: finalFinishFrames.frozenFrames - startFrames.frozenFrames,\n unit: 'none',\n },\n frames_slow: {\n value: finalFinishFrames.slowFrames - startFrames.slowFrames,\n unit: 'none',\n },\n };\n\n return measurements;\n }\n\n /**\n * Fetch finish frames for a transaction at the current time. Calls any awaiting listeners.\n */\n private async _fetchFramesForTransaction(transaction: Transaction): Promise<void> {\n const startFrames = transaction.data.__startFrames as NativeFramesResponse | undefined;\n\n // This timestamp marks when the finish frames were retrieved. It should be pretty close to the transaction finish.\n const timestamp = timestampInSeconds();\n let finishFrames: NativeFramesResponse | null = null;\n if (startFrames) {\n finishFrames = await NATIVE.fetchNativeFrames();\n }\n\n this._finishFrames.set(transaction.traceId, {\n nativeFrames: finishFrames,\n timestamp,\n });\n\n this._framesListeners.get(transaction.traceId)?.();\n\n setTimeout(() => this._cancelFinishFrames(transaction), 2000);\n }\n\n /**\n * On a finish frames failure, we cancel the await.\n */\n private _cancelFinishFrames(transaction: Transaction): void {\n if (this._finishFrames.has(transaction.traceId)) {\n this._finishFrames.delete(transaction.traceId);\n\n logger.log(\n `[NativeFrames] Native frames timed out for ${transaction.op} transaction ${transaction.name}. Not adding native frames measurements.`,\n );\n }\n }\n\n /**\n * Adds frames measurements to an event. Called from a valid event processor.\n * Awaits for finish frames if needed.\n */\n private async _processEvent(event: Event, doesExist: () => boolean): Promise<Event> {\n if (!doesExist()) {\n return event;\n }\n\n if (event.type === 'transaction' && event.transaction && event.contexts && event.contexts.trace) {\n const traceContext = event.contexts.trace as {\n data?: { [key: string]: unknown };\n trace_id: string;\n name?: string;\n op?: string;\n };\n\n const traceId = traceContext.trace_id;\n\n if (traceId && traceContext.data?.__startFrames && event.timestamp) {\n const measurements = await this._getFramesMeasurements(\n traceId,\n event.timestamp,\n traceContext.data.__startFrames as NativeFramesResponse,\n );\n\n if (!measurements) {\n logger.log(\n `[NativeFrames] Could not fetch native frames for ${traceContext.op} transaction ${event.transaction}. Not adding native frames measurements.`,\n );\n } else {\n logger.log(\n `[Measurements] Adding measurements to ${traceContext.op} transaction ${\n event.transaction\n }: ${JSON.stringify(measurements, undefined, 2)}`,\n );\n\n event.measurements = {\n ...(event.measurements ?? {}),\n ...measurements,\n };\n\n this._finishFrames.delete(traceId);\n }\n\n delete traceContext.data.__startFrames;\n }\n }\n\n return event;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"nativeframes.js","sourceRoot":"","sources":["../../../src/js/tracing/nativeframes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Span, Transaction } from '@sentry/core';\nimport type { Event, EventProcessor, Measurements, MeasurementUnit } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nimport type { NativeFramesResponse } from '../NativeRNSentry';\nimport { NATIVE } from '../wrapper';\nimport { instrumentChildSpanFinish } from './utils';\n\nexport interface FramesMeasurements extends Measurements {\n frames_total: { value: number; unit: MeasurementUnit };\n frames_slow: { value: number; unit: MeasurementUnit };\n frames_frozen: { value: number; unit: MeasurementUnit };\n}\n\n/** The listeners for each native frames response, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */\nconst _framesListeners: Map<string, () => void> = new Map();\n\n/** The native frames at the transaction finish time, keyed by traceId. This must be global to avoid closure issues and reading outdated values. */\nconst _finishFrames: Map<string, { timestamp: number; nativeFrames: NativeFramesResponse | null }> = new Map();\n\n/**\n * A margin of error of 50ms is allowed for the async native bridge call.\n * Anything larger would reduce the accuracy of our frames measurements.\n */\nconst MARGIN_OF_ERROR_SECONDS = 0.05;\n\n/**\n * Instrumentation to add native slow/frozen frames measurements onto transactions.\n */\nexport class NativeFramesInstrumentation {\n /** The native frames at the finish time of the most recent span. */\n private _lastSpanFinishFrames?: {\n timestamp: number;\n nativeFrames: NativeFramesResponse;\n };\n\n public constructor(addGlobalEventProcessor: (e: EventProcessor) => void, doesExist: () => boolean) {\n logger.log('[ReactNativeTracing] Native frames instrumentation initialized.');\n\n addGlobalEventProcessor(event => this._processEvent(event, doesExist));\n }\n\n /**\n * To be called when a transaction is started.\n * Logs the native frames at this start point and instruments child span finishes.\n */\n public onTransactionStart(transaction: Transaction): void {\n void NATIVE.fetchNativeFrames()\n .then(framesMetrics => {\n if (framesMetrics) {\n transaction.setData('__startFrames', framesMetrics);\n }\n })\n .then(undefined, error => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames: ${error}`);\n });\n\n instrumentChildSpanFinish(transaction, (_: Span, endTimestamp?: number) => {\n if (!endTimestamp) {\n this._onSpanFinish();\n }\n });\n }\n\n /**\n * To be called when a transaction is finished\n */\n public onTransactionFinish(transaction: Transaction): void {\n this._fetchFramesForTransaction(transaction).then(undefined, (reason: unknown) => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames:`, reason);\n });\n }\n\n /**\n * Called on a span finish to fetch native frames to support transactions with trimEnd.\n * Only to be called when a span does not have an end timestamp.\n */\n private _onSpanFinish(): void {\n const timestamp = timestampInSeconds();\n\n void NATIVE.fetchNativeFrames()\n .then(nativeFrames => {\n if (nativeFrames) {\n this._lastSpanFinishFrames = {\n timestamp,\n nativeFrames,\n };\n }\n })\n .then(undefined, error => {\n logger.error(`[ReactNativeTracing] Error while fetching native frames: ${error}`);\n });\n }\n\n /**\n * Returns the computed frames measurements and awaits for them if they are not ready yet.\n */\n private async _getFramesMeasurements(\n traceId: string,\n finalEndTimestamp: number,\n startFrames: NativeFramesResponse,\n ): Promise<FramesMeasurements | null> {\n if (_finishFrames.has(traceId)) {\n return this._prepareMeasurements(traceId, finalEndTimestamp, startFrames);\n }\n\n return new Promise(resolve => {\n const timeout = setTimeout(() => {\n _framesListeners.delete(traceId);\n\n resolve(null);\n }, 2000);\n\n _framesListeners.set(traceId, () => {\n resolve(this._prepareMeasurements(traceId, finalEndTimestamp, startFrames));\n\n clearTimeout(timeout);\n _framesListeners.delete(traceId);\n });\n });\n }\n\n /**\n * Returns the computed frames measurements given ready data\n */\n private _prepareMeasurements(\n traceId: string,\n finalEndTimestamp: number, // The actual transaction finish time.\n startFrames: NativeFramesResponse,\n ): FramesMeasurements | null {\n let finalFinishFrames: NativeFramesResponse | undefined;\n\n const finish = _finishFrames.get(traceId);\n if (\n finish &&\n finish.nativeFrames &&\n // Must be in the margin of error of the actual transaction finish time (finalEndTimestamp)\n Math.abs(finish.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n finalFinishFrames = finish.nativeFrames;\n } else if (\n this._lastSpanFinishFrames &&\n Math.abs(this._lastSpanFinishFrames.timestamp - finalEndTimestamp) < MARGIN_OF_ERROR_SECONDS\n ) {\n // Fallback to the last span finish if it is within the margin of error of the actual finish timestamp.\n // This should be the case for trimEnd.\n finalFinishFrames = this._lastSpanFinishFrames.nativeFrames;\n } else {\n return null;\n }\n\n const measurements = {\n frames_total: {\n value: finalFinishFrames.totalFrames - startFrames.totalFrames,\n unit: 'none',\n },\n frames_frozen: {\n value: finalFinishFrames.frozenFrames - startFrames.frozenFrames,\n unit: 'none',\n },\n frames_slow: {\n value: finalFinishFrames.slowFrames - startFrames.slowFrames,\n unit: 'none',\n },\n };\n\n return measurements;\n }\n\n /**\n * Fetch finish frames for a transaction at the current time. Calls any awaiting listeners.\n */\n private async _fetchFramesForTransaction(transaction: Transaction): Promise<void> {\n const startFrames = transaction.data.__startFrames as NativeFramesResponse | undefined;\n\n // This timestamp marks when the finish frames were retrieved. It should be pretty close to the transaction finish.\n const timestamp = timestampInSeconds();\n let finishFrames: NativeFramesResponse | null = null;\n if (startFrames) {\n finishFrames = await NATIVE.fetchNativeFrames();\n }\n\n _finishFrames.set(transaction.traceId, {\n nativeFrames: finishFrames,\n timestamp,\n });\n\n _framesListeners.get(transaction.traceId)?.();\n\n setTimeout(() => this._cancelFinishFrames(transaction), 2000);\n }\n\n /**\n * On a finish frames failure, we cancel the await.\n */\n private _cancelFinishFrames(transaction: Transaction): void {\n if (_finishFrames.has(transaction.traceId)) {\n _finishFrames.delete(transaction.traceId);\n\n logger.log(\n `[NativeFrames] Native frames timed out for ${transaction.op} transaction ${transaction.name}. Not adding native frames measurements.`,\n );\n }\n }\n\n /**\n * Adds frames measurements to an event. Called from a valid event processor.\n * Awaits for finish frames if needed.\n */\n private async _processEvent(event: Event, doesExist: () => boolean): Promise<Event> {\n if (!doesExist()) {\n return event;\n }\n\n if (event.type === 'transaction' && event.transaction && event.contexts && event.contexts.trace) {\n const traceContext = event.contexts.trace as {\n data?: { [key: string]: unknown };\n trace_id: string;\n name?: string;\n op?: string;\n };\n\n const traceId = traceContext.trace_id;\n\n if (traceId && traceContext.data?.__startFrames && event.timestamp) {\n const measurements = await this._getFramesMeasurements(\n traceId,\n event.timestamp,\n traceContext.data.__startFrames as NativeFramesResponse,\n );\n\n if (!measurements) {\n logger.log(\n `[NativeFrames] Could not fetch native frames for ${traceContext.op} transaction ${event.transaction}. Not adding native frames measurements.`,\n );\n } else {\n logger.log(\n `[Measurements] Adding measurements to ${traceContext.op} transaction ${\n event.transaction\n }: ${JSON.stringify(measurements, undefined, 2)}`,\n );\n\n event.measurements = {\n ...(event.measurements ?? {}),\n ...measurements,\n };\n\n _finishFrames.delete(traceId);\n }\n\n delete traceContext.data.__startFrames;\n }\n }\n\n return event;\n }\n}\n"]}
|
|
@@ -16,10 +16,6 @@ export declare function getExpoGoVersion(): string | undefined;
|
|
|
16
16
|
export declare function getExpoSdkVersion(): string | undefined;
|
|
17
17
|
/** Checks if the current platform is not web */
|
|
18
18
|
export declare function notWeb(): boolean;
|
|
19
|
-
/** Checks if the current platform is supported mobile platform (iOS or Android) */
|
|
20
|
-
export declare function isMobileOs(): boolean;
|
|
21
|
-
/** Checks if the current platform is not supported mobile platform (iOS or Android) */
|
|
22
|
-
export declare function notMobileOs(): boolean;
|
|
23
19
|
/** Returns Hermes Version if hermes is present in the runtime */
|
|
24
20
|
export declare function getHermesVersion(): string | undefined;
|
|
25
21
|
/** Returns default environment based on __DEV__ */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/js/utils/environment.ts"],"names":[],"mappings":"AAMA,0DAA0D;AAC1D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,oDAAoD;AACpD,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAM1D;AAED,+CAA+C;AAC/C,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,kCAAkC;AAClC,wBAAgB,QAAQ,IAAI,OAAO,CAGlC;AAED,yCAAyC;AACzC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAKtD;AAED,gDAAgD;AAChD,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../../src/js/utils/environment.ts"],"names":[],"mappings":"AAMA,0DAA0D;AAC1D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,oDAAoD;AACpD,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,SAAS,CAM1D;AAED,+CAA+C;AAC/C,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,kCAAkC;AAClC,wBAAgB,QAAQ,IAAI,OAAO,CAGlC;AAED,yCAAyC;AACzC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAKtD;AAED,gDAAgD;AAChD,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAMrD;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,IAAI,aAAa,GAAG,YAAY,CAEpE;AAED,iDAAiD;AACjD,wBAAgB,yBAAyB,IAAI,OAAO,CASnD"}
|
|
@@ -47,14 +47,6 @@ export function getExpoSdkVersion() {
|
|
|
47
47
|
export function notWeb() {
|
|
48
48
|
return Platform.OS !== 'web';
|
|
49
49
|
}
|
|
50
|
-
/** Checks if the current platform is supported mobile platform (iOS or Android) */
|
|
51
|
-
export function isMobileOs() {
|
|
52
|
-
return Platform.OS === 'ios' || Platform.OS === 'android';
|
|
53
|
-
}
|
|
54
|
-
/** Checks if the current platform is not supported mobile platform (iOS or Android) */
|
|
55
|
-
export function notMobileOs() {
|
|
56
|
-
return !isMobileOs();
|
|
57
|
-
}
|
|
58
50
|
/** Returns Hermes Version if hermes is present in the runtime */
|
|
59
51
|
export function getHermesVersion() {
|
|
60
52
|
return (RN_GLOBAL_OBJ.HermesInternal &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/js/utils/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,0DAA0D;AAC1D,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,aAAa,CAAC,cAAc,CAAC;AACxC,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,oBAAoB;IAClC,OAAO,aAAa,CAAC,kBAAkB,IAAI,IAAI,CAAC;AAClD,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,eAAe;IAC7B,OAAO,aAAa,CAAC,qBAAqB,IAAI,IAAI,CAAC;AACrD,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,EAAE;QAC5C,OAAO,SAAS,CAAC;KAClB;IACD,MAAM,GAAG,GAAG,oBAAoB,CAAC,kBAAkB,CAAC,OAAO,CAAC;IAC5D,OAAO,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACvG,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,MAAM;IACpB,OAAO,aAAa,CAAC,IAAI,IAAI,IAAI,CAAC;AACpC,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,QAAQ;IACtB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;AAClE,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,OAAO,OAAO,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,WAAW,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAChG,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,iBAAiB;;IAC/B,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,MAAM,CAAC,EAAE,cAAc,CAAC,GACtB,OAAO,CAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,QAAQ,0CAAE,cAAc,CAAA,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtH,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,MAAM;IACpB,OAAO,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC;AAC/B,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/js/utils/environment.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from 'react-native';\n\nimport { RN_GLOBAL_OBJ } from '../utils/worldwide';\nimport { getExpoConstants } from './expomodules';\nimport { ReactNativeLibraries } from './rnlibraries';\n\n/** Checks if the React Native Hermes engine is running */\nexport function isHermesEnabled(): boolean {\n return !!RN_GLOBAL_OBJ.HermesInternal;\n}\n\n/** Checks if the React Native TurboModules are enabled */\nexport function isTurboModuleEnabled(): boolean {\n return RN_GLOBAL_OBJ.__turboModuleProxy != null;\n}\n\n/** Checks if the React Native Fabric renderer is running */\nexport function isFabricEnabled(): boolean {\n return RN_GLOBAL_OBJ.nativeFabricUIManager != null;\n}\n\n/** Returns React Native Version as semver string */\nexport function getReactNativeVersion(): string | undefined {\n if (!ReactNativeLibraries.ReactNativeVersion) {\n return undefined;\n }\n const RNV = ReactNativeLibraries.ReactNativeVersion.version;\n return `${RNV.major}.${RNV.minor}.${RNV.patch}${RNV.prerelease != null ? `-${RNV.prerelease}` : ''}`;\n}\n\n/** Checks if Expo is present in the runtime */\nexport function isExpo(): boolean {\n return RN_GLOBAL_OBJ.expo != null;\n}\n\n/** Check if JS runs in Expo Go */\nexport function isExpoGo(): boolean {\n const expoConstants = getExpoConstants();\n return (expoConstants && expoConstants.appOwnership) === 'expo';\n}\n\n/** Check Expo Go version if available */\nexport function getExpoGoVersion(): string | undefined {\n const expoConstants = getExpoConstants();\n return typeof expoConstants?.expoVersion === 'string' ? expoConstants.expoVersion : undefined;\n}\n\n/** Returns Expo SDK version if available */\nexport function getExpoSdkVersion(): string | undefined {\n const expoConstants = getExpoConstants();\n const [, expoSdkVersion] =\n typeof expoConstants?.manifest?.runtimeVersion === 'string' ? expoConstants.manifest.runtimeVersion.split(':') : [];\n return expoSdkVersion;\n}\n\n/** Checks if the current platform is not web */\nexport function notWeb(): boolean {\n return Platform.OS !== 'web';\n}\n\n/** Returns Hermes Version if hermes is present in the runtime */\nexport function getHermesVersion(): string | undefined {\n return (\n RN_GLOBAL_OBJ.HermesInternal &&\n RN_GLOBAL_OBJ.HermesInternal.getRuntimeProperties &&\n RN_GLOBAL_OBJ.HermesInternal.getRuntimeProperties()['OSS Release Version']\n );\n}\n\n/** Returns default environment based on __DEV__ */\nexport function getDefaultEnvironment(): 'development' | 'production' {\n return typeof __DEV__ !== 'undefined' && __DEV__ ? 'development' : 'production';\n}\n\n/** Check if SDK runs in Metro Dev Server side */\nexport function isRunningInMetroDevServer(): boolean {\n if (\n typeof RN_GLOBAL_OBJ.process !== 'undefined' &&\n RN_GLOBAL_OBJ.process.env &&\n RN_GLOBAL_OBJ.process.env.___SENTRY_METRO_DEV_SERVER___ === 'true'\n ) {\n return true;\n }\n return false;\n}\n"]}
|
package/dist/js/version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const SDK_PACKAGE_NAME = "npm:@sentry/react-native";
|
|
2
2
|
export declare const SDK_NAME = "sentry.javascript.react-native";
|
|
3
|
-
export declare const SDK_VERSION = "5.23.0
|
|
3
|
+
export declare const SDK_VERSION = "5.23.0";
|
|
4
4
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/js/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,QAAQ,mCAAmC,CAAC;AACzD,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAC3D,eAAO,MAAM,QAAQ,mCAAmC,CAAC;AACzD,eAAO,MAAM,WAAW,WAAW,CAAC"}
|
package/dist/js/version.js
CHANGED