@sentry/react-native 5.0.0 → 5.1.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 +27 -0
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/dist/js/integrations/devicecontext.d.ts.map +1 -1
- package/dist/js/integrations/devicecontext.js +6 -1
- package/dist/js/integrations/devicecontext.js.map +1 -1
- package/dist/js/measurements.d.ts +5 -0
- package/dist/js/measurements.d.ts.map +1 -1
- package/dist/js/measurements.js +8 -4
- package/dist/js/measurements.js.map +1 -1
- package/dist/js/tracing/index.d.ts +1 -0
- package/dist/js/tracing/index.d.ts.map +1 -1
- package/dist/js/tracing/index.js +1 -0
- package/dist/js/tracing/index.js.map +1 -1
- package/dist/js/tracing/ops.d.ts +6 -0
- package/dist/js/tracing/ops.d.ts.map +1 -0
- package/dist/js/tracing/ops.js +6 -0
- package/dist/js/tracing/ops.js.map +1 -0
- package/dist/js/tracing/reactnativetracing.d.ts.map +1 -1
- package/dist/js/tracing/reactnativetracing.js +7 -4
- package/dist/js/tracing/reactnativetracing.js.map +1 -1
- package/dist/js/tracing/stalltracking.d.ts +4 -3
- package/dist/js/tracing/stalltracking.d.ts.map +1 -1
- package/dist/js/tracing/stalltracking.js +4 -3
- package/dist/js/tracing/stalltracking.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- Add App Context `in_foreground` ([#2826](https://github.com/getsentry/sentry-react-native/pull/2826))
|
|
8
|
+
|
|
9
|
+
### Fixes
|
|
10
|
+
|
|
11
|
+
- Match app start measurements naming with other SDKs ([#2855](https://github.com/getsentry/sentry-react-native/pull/2855))
|
|
12
|
+
- `app.start.cold` to `app_start_cold`
|
|
13
|
+
- `app.start.warm` to `app_start_warm`
|
|
14
|
+
|
|
15
|
+
### Dependencies
|
|
16
|
+
|
|
17
|
+
- Bump Cocoa SDK from v8.0.0 to v8.2.0 ([#2776](https://github.com/getsentry/sentry-react-native/pull/2776))
|
|
18
|
+
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#820)
|
|
19
|
+
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.0.0...8.2.0)
|
|
20
|
+
- Bump JavaScript SDK from v7.37.2 to v7.40.0 ([#2836](https://github.com/getsentry/sentry-react-native/pull/2836), [#2864](https://github.com/getsentry/sentry-react-native/pull/2864))
|
|
21
|
+
- [changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#7400)
|
|
22
|
+
- [diff](https://github.com/getsentry/sentry-javascript/compare/7.37.2...7.40.0)
|
|
23
|
+
- Bump CLI from v2.10.0 to v2.14.3 ([#2848](https://github.com/getsentry/sentry-react-native/pull/2848), [#2869](https://github.com/getsentry/sentry-react-native/pull/2869))
|
|
24
|
+
- [changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md#2143)
|
|
25
|
+
- [diff](https://github.com/getsentry/sentry-cli/compare/2.10.0...2.14.3)
|
|
26
|
+
- Bump Android SDK from v6.14.0 to v6.15.0 ([#2868](https://github.com/getsentry/sentry-react-native/pull/2868))
|
|
27
|
+
- [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#6150)
|
|
28
|
+
- [diff](https://github.com/getsentry/sentry-java/compare/6.14.0...6.15.0)
|
|
29
|
+
|
|
3
30
|
## 5.0.0
|
|
4
31
|
|
|
5
32
|
The React Native SDK version 5 supports both Legacy (from RN 0.65 and above) and New Architecture (from RN 0.69 and above) as well as the new React Native Gradle Plugin (introduced in RN 0.71). For detailed [migration guide visit our docs](https://docs.sentry.io/platforms/react-native/migration/#from-4x-to-5x).
|
package/RNSentry.podspec
CHANGED
package/android/build.gradle
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devicecontext.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAS,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"devicecontext.d.ts","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAS,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQ7E,uCAAuC;AACvC,qBAAa,aAAc,YAAW,WAAW;IAC/C;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAAmB;IAE3C;;OAEG;IACI,IAAI,EAAE,MAAM,CAAoB;IAEvC;;OAEG;IACI,SAAS,CACd,uBAAuB,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,EAC3D,aAAa,EAAE,MAAM,GAAG,GACvB,IAAI;CA0ER"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { logger, severityLevelFromString } from '@sentry/utils';
|
|
3
|
+
import { AppState } from 'react-native';
|
|
3
4
|
import { breadcrumbFromObject } from '../breadcrumb';
|
|
4
5
|
import { NATIVE } from '../wrapper';
|
|
5
6
|
/** Load device context from native. */
|
|
@@ -34,7 +35,11 @@ export class DeviceContext {
|
|
|
34
35
|
if (!event.user && nativeUser) {
|
|
35
36
|
event.user = nativeUser;
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
let nativeContext = native.context;
|
|
39
|
+
if (AppState.currentState !== 'unknown') {
|
|
40
|
+
nativeContext = nativeContext || {};
|
|
41
|
+
nativeContext.app = Object.assign(Object.assign({}, nativeContext.app), { in_foreground: AppState.currentState === 'active' });
|
|
42
|
+
}
|
|
38
43
|
if (nativeContext) {
|
|
39
44
|
event.contexts = Object.assign(Object.assign({}, nativeContext), event.contexts);
|
|
40
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devicecontext.js","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"devicecontext.js","sourceRoot":"","sources":["../../../src/js/integrations/devicecontext.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable complexity */\nimport type { Event, EventProcessor, Hub, Integration } from '@sentry/types';\nimport { logger, severityLevelFromString } from '@sentry/utils';\nimport { AppState } from 'react-native';\n\nimport { breadcrumbFromObject } from '../breadcrumb';\nimport type { NativeDeviceContextsResponse } from '../NativeRNSentry';\nimport { NATIVE } from '../wrapper';\n\n/** Load device context from native. */\nexport class DeviceContext implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'DeviceContext';\n\n /**\n * @inheritDoc\n */\n public name: string = DeviceContext.id;\n\n /**\n * @inheritDoc\n */\n public setupOnce(\n addGlobalEventProcessor: (callback: EventProcessor) => void,\n getCurrentHub: () => Hub,\n ): void {\n addGlobalEventProcessor(async (event: Event) => {\n const self = getCurrentHub().getIntegration(DeviceContext);\n if (!self) {\n return event;\n }\n\n let native: NativeDeviceContextsResponse | null = null;\n try {\n native = await NATIVE.fetchNativeDeviceContexts();\n } catch (e) {\n logger.log(`Failed to get device context from native: ${e}`);\n }\n\n if (!native) {\n return event;\n }\n\n const nativeUser = native.user;\n if (!event.user && nativeUser) {\n event.user = nativeUser;\n }\n\n let nativeContext = native.context;\n if (AppState.currentState !== 'unknown') {\n nativeContext = nativeContext || {};\n nativeContext.app = {\n ...nativeContext.app,\n in_foreground: AppState.currentState === 'active',\n }\n }\n if (nativeContext) {\n event.contexts = { ...nativeContext, ...event.contexts };\n }\n\n const nativeTags = native.tags;\n if (nativeTags) {\n event.tags = { ...nativeTags, ...event.tags };\n }\n\n const nativeExtra = native.extra;\n if (nativeExtra) {\n event.extra = { ...nativeExtra, ...event.extra };\n }\n\n const nativeFingerprint = native.fingerprint;\n if (nativeFingerprint) {\n event.fingerprint = (event.fingerprint ?? []).concat(\n nativeFingerprint.filter((item) => (event.fingerprint ?? []).indexOf(item) < 0),\n )\n }\n\n const nativeLevel = typeof native['level'] === 'string'\n ? severityLevelFromString(native['level'])\n : undefined;\n if (!event.level && nativeLevel) {\n event.level = nativeLevel;\n }\n\n const nativeEnvironment = native['environment'];\n if (!event.environment && nativeEnvironment) {\n event.environment = nativeEnvironment;\n }\n\n const nativeBreadcrumbs = Array.isArray(native['breadcrumbs'])\n ? native['breadcrumbs'].map(breadcrumbFromObject)\n : undefined;\n if (nativeBreadcrumbs) {\n event.breadcrumbs = nativeBreadcrumbs;\n }\n\n return event;\n });\n }\n}\n"]}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Hub } from '@sentry/core';
|
|
2
2
|
import type { Transaction } from '@sentry/tracing';
|
|
3
3
|
import type { CustomSamplingContext, TransactionContext } from '@sentry/types';
|
|
4
|
+
export declare const APP_START_WARM = "app_start_warm";
|
|
5
|
+
export declare const APP_START_COLD = "app_start_cold";
|
|
6
|
+
export declare const STALL_COUNT = "stall_count";
|
|
7
|
+
export declare const STALL_TOTAL_TIME = "stall_total_time";
|
|
8
|
+
export declare const STALL_LONGEST_TIME = "stall_longest_time";
|
|
4
9
|
/**
|
|
5
10
|
* Adds React Native's extensions. Needs to be called after @sentry/tracing's extension methods are added
|
|
6
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measurements.d.ts","sourceRoot":"","sources":["../../src/js/measurements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAqB,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"measurements.d.ts","sourceRoot":"","sources":["../../src/js/measurements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAqB,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIlG,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAmB5C;AAED,oBAAY,wBAAwB,GAAG,CACrC,IAAI,EAAE,GAAG,EACT,kBAAkB,EAAE,kBAAkB,EACtC,qBAAqB,CAAC,EAAE,qBAAqB,KAC1C,WAAW,CAAC"}
|
package/dist/js/measurements.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { getCurrentHub, getMainCarrier } from '@sentry/core';
|
|
2
|
-
import { ReactNativeTracing } from './tracing';
|
|
3
|
-
const
|
|
2
|
+
import { DEFAULT, ReactNativeTracing } from './tracing';
|
|
3
|
+
export const APP_START_WARM = 'app_start_warm';
|
|
4
|
+
export const APP_START_COLD = 'app_start_cold';
|
|
5
|
+
export const STALL_COUNT = 'stall_count';
|
|
6
|
+
export const STALL_TOTAL_TIME = 'stall_total_time';
|
|
7
|
+
export const STALL_LONGEST_TIME = 'stall_longest_time';
|
|
4
8
|
/**
|
|
5
9
|
* Adds React Native's extensions. Needs to be called after @sentry/tracing's extension methods are added
|
|
6
10
|
*/
|
|
@@ -30,7 +34,7 @@ const _patchStartTransaction = (originalStartTransaction) => {
|
|
|
30
34
|
function _startTransaction(transactionContext, customSamplingContext) {
|
|
31
35
|
// Native SDKs require op to be set - for JS Relay sets `default`
|
|
32
36
|
if (!transactionContext.op) {
|
|
33
|
-
transactionContext.op =
|
|
37
|
+
transactionContext.op = DEFAULT;
|
|
34
38
|
}
|
|
35
39
|
const transaction = originalStartTransaction.apply(this, [
|
|
36
40
|
transactionContext,
|
|
@@ -40,7 +44,7 @@ const _patchStartTransaction = (originalStartTransaction) => {
|
|
|
40
44
|
transaction.startChild = (spanContext) => {
|
|
41
45
|
return originalStartChild(Object.assign(Object.assign({}, spanContext), {
|
|
42
46
|
// Native SDKs require op to be set
|
|
43
|
-
op: (spanContext === null || spanContext === void 0 ? void 0 : spanContext.op) ||
|
|
47
|
+
op: (spanContext === null || spanContext === void 0 ? void 0 : spanContext.op) || DEFAULT }));
|
|
44
48
|
};
|
|
45
49
|
const reactNativeTracing = getCurrentHub().getIntegration(ReactNativeTracing);
|
|
46
50
|
if (reactNativeTracing) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measurements.js","sourceRoot":"","sources":["../../src/js/measurements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,
|
|
1
|
+
{"version":3,"file":"measurements.js","sourceRoot":"","sources":["../../src/js/measurements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI7D,OAAO,EAAE,OAAO,EAAC,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,UAAU,EAAE;QACtB,OAAO,CAAC,UAAU,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;QACpE,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAClD,MAAM,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,UAAU;iBAC3D,gBAA4C,CAAC;YAEhD;;;cAGE;YACF,MAAM,iBAAiB,GAAG,sBAAsB,CAC9C,wBAAwB,CACzB,CAAC;YAEF,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,gBAAgB,GAAG,iBAAiB,CAAC;SACpE;KACF;AACH,CAAC;AAQD;;GAEG;AACH,MAAM,sBAAsB,GAAG,CAC7B,wBAAkD,EACxB,EAAE;IAC5B;;OAEG;IACH,SAAS,iBAAiB,CAExB,kBAAsC,EACtC,qBAA6C;QAE7C,iEAAiE;QACjE,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE;YAC1B,kBAAkB,CAAC,EAAE,GAAG,OAAO,CAAC;SACjC;QAED,MAAM,WAAW,GAAgB,wBAAwB,CAAC,KAAK,CAAC,IAAI,EAAE;YACpE,kBAAkB;YAClB,qBAAqB;SACtB,CAAC,CAAC;QACH,MAAM,kBAAkB,GAA8B,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/F,WAAW,CAAC,UAAU,GAAG,CACvB,WAAmG,EAC7F,EAAE;YACR,OAAO,kBAAkB,iCACpB,WAAW;gBACd,mCAAmC;gBACnC,EAAE,EAAE,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,EAAE,KAAI,OAAO,IAC9B,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAG,aAAa,EAAE,CAAC,cAAc,CACvD,kBAAkB,CACnB,CAAC;QAEF,IAAI,kBAAkB,EAAE;YACtB,kBAAkB,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YAEnD,6DAA6D;YAC7D,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC;YAE1C,WAAW,CAAC,MAAM,GAAG,CAAC,YAAgC,EAAE,EAAE;gBACxD,IAAI,kBAAkB,EAAE;oBACtB,kBAAkB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;iBACrD;gBAED,OAAO,cAAc,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC3D,CAAC,CAAC;SACH;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["import type { Hub } from '@sentry/core';\nimport { getCurrentHub, getMainCarrier } from '@sentry/core';\nimport type { Transaction } from '@sentry/tracing';\nimport type { CustomSamplingContext, Span, SpanContext, TransactionContext } from '@sentry/types';\n\nimport { DEFAULT,ReactNativeTracing } from './tracing';\n\nexport const APP_START_WARM = 'app_start_warm';\nexport const APP_START_COLD = 'app_start_cold';\n\nexport const STALL_COUNT = 'stall_count';\nexport const STALL_TOTAL_TIME = 'stall_total_time';\nexport const STALL_LONGEST_TIME = 'stall_longest_time';\n\n/**\n * Adds React Native's extensions. Needs to be called after @sentry/tracing's extension methods are added\n */\nexport function _addTracingExtensions(): void {\n const carrier = getMainCarrier();\n if (carrier.__SENTRY__) {\n carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};\n if (carrier.__SENTRY__.extensions.startTransaction) {\n const originalStartTransaction = carrier.__SENTRY__.extensions\n .startTransaction as StartTransactionFunction;\n\n /*\n Overwrites the transaction start and finish to start and finish stall tracking.\n Preferably instead of overwriting add a callback method for this in the Transaction itself.\n */\n const _startTransaction = _patchStartTransaction(\n originalStartTransaction\n );\n\n carrier.__SENTRY__.extensions.startTransaction = _startTransaction;\n }\n }\n}\n\nexport type StartTransactionFunction = (\n this: Hub,\n transactionContext: TransactionContext,\n customSamplingContext?: CustomSamplingContext\n) => Transaction;\n\n/**\n * Overwrite the startTransaction extension method to start and end stall tracking.\n */\nconst _patchStartTransaction = (\n originalStartTransaction: StartTransactionFunction\n): StartTransactionFunction => {\n /**\n * Method to overwrite with\n */\n function _startTransaction(\n this: Hub,\n transactionContext: TransactionContext,\n customSamplingContext?: CustomSamplingContext\n ): Transaction {\n // Native SDKs require op to be set - for JS Relay sets `default`\n if (!transactionContext.op) {\n transactionContext.op = DEFAULT;\n }\n\n const transaction: Transaction = originalStartTransaction.apply(this, [\n transactionContext,\n customSamplingContext,\n ]);\n const originalStartChild: Transaction['startChild'] = transaction.startChild.bind(transaction);\n transaction.startChild = (\n spanContext?: Pick<SpanContext, Exclude<keyof SpanContext, 'sampled' | 'traceId' | 'parentSpanId'>>,\n ): Span => {\n return originalStartChild({\n ...spanContext,\n // Native SDKs require op to be set\n op: spanContext?.op || DEFAULT,\n });\n };\n\n const reactNativeTracing = getCurrentHub().getIntegration(\n ReactNativeTracing\n );\n\n if (reactNativeTracing) {\n reactNativeTracing.onTransactionStart(transaction);\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalFinish = transaction.finish;\n\n transaction.finish = (endTimestamp: number | undefined) => {\n if (reactNativeTracing) {\n reactNativeTracing.onTransactionFinish(transaction);\n }\n\n return originalFinish.apply(transaction, [endTimestamp]);\n };\n }\n\n return transaction;\n }\n\n return _startTransaction;\n};\n"]}
|
|
@@ -5,4 +5,5 @@ export { ReactNavigationV4Instrumentation } from './reactnavigationv4';
|
|
|
5
5
|
export { ReactNativeNavigationInstrumentation } from './reactnativenavigation';
|
|
6
6
|
export { ReactNavigationCurrentRoute, ReactNavigationRoute, ReactNavigationTransactionContext, } from './types';
|
|
7
7
|
export { ReactNativeProfiler } from './reactnativeprofiler';
|
|
8
|
+
export * from './ops';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,8BAA8B,EAE9B,gCAAgC,GACjC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,iCAAiC,GAClC,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,8BAA8B,EAE9B,gCAAgC,GACjC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,iCAAiC,GAClC,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,cAAc,OAAO,CAAC"}
|
package/dist/js/tracing/index.js
CHANGED
|
@@ -6,4 +6,5 @@ ReactNavigationV5Instrumentation, } from './reactnavigation';
|
|
|
6
6
|
export { ReactNavigationV4Instrumentation } from './reactnavigationv4';
|
|
7
7
|
export { ReactNativeNavigationInstrumentation } from './reactnativenavigation';
|
|
8
8
|
export { ReactNativeProfiler } from './reactnativeprofiler';
|
|
9
|
+
export * from './ops';
|
|
9
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,sBAAsB,GAEvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,8BAA8B;AAC9B,mDAAmD;AACnD,gCAAgC,GACjC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAQ/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["export { ReactNativeTracing } from './reactnativetracing';\n\nexport {\n RoutingInstrumentation,\n RoutingInstrumentationInstance,\n} from './routingInstrumentation';\n\nexport {\n ReactNavigationInstrumentation,\n // eslint-disable-next-line deprecation/deprecation\n ReactNavigationV5Instrumentation,\n} from './reactnavigation';\nexport { ReactNavigationV4Instrumentation } from './reactnavigationv4';\nexport { ReactNativeNavigationInstrumentation } from './reactnativenavigation';\n\nexport {\n ReactNavigationCurrentRoute,\n ReactNavigationRoute,\n ReactNavigationTransactionContext,\n} from './types';\n\nexport { ReactNativeProfiler } from './reactnativeprofiler';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/js/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EACL,sBAAsB,GAEvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,8BAA8B;AAC9B,mDAAmD;AACnD,gCAAgC,GACjC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAQ/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,cAAc,OAAO,CAAC","sourcesContent":["export { ReactNativeTracing } from './reactnativetracing';\n\nexport {\n RoutingInstrumentation,\n RoutingInstrumentationInstance,\n} from './routingInstrumentation';\n\nexport {\n ReactNavigationInstrumentation,\n // eslint-disable-next-line deprecation/deprecation\n ReactNavigationV5Instrumentation,\n} from './reactnavigation';\nexport { ReactNavigationV4Instrumentation } from './reactnavigationv4';\nexport { ReactNativeNavigationInstrumentation } from './reactnativenavigation';\n\nexport {\n ReactNavigationCurrentRoute,\n ReactNavigationRoute,\n ReactNavigationTransactionContext,\n} from './types';\n\nexport { ReactNativeProfiler } from './reactnativeprofiler';\n\nexport * from './ops';\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DEFAULT = "default";
|
|
2
|
+
export declare const UI_LOAD = "ui.load";
|
|
3
|
+
export declare const NAVIGATION = "navigation";
|
|
4
|
+
export declare const APP_START_COLD = "app.start.cold";
|
|
5
|
+
export declare const APP_START_WARM = "app.start.warm";
|
|
6
|
+
//# sourceMappingURL=ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/ops.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,UAAU,eAAe,CAAC;AAEvC,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,eAAO,MAAM,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.js","sourceRoot":"","sources":["../../../src/js/tracing/ops.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AAEvC,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC","sourcesContent":["\nexport const DEFAULT = 'default';\nexport const UI_LOAD = 'ui.load';\nexport const NAVIGATION = 'navigation';\n\nexport const APP_START_COLD = 'app.start.cold';\nexport const APP_START_WARM = 'app.start.warm';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAEV,6BAA6B,EAC7B,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAGZ,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"reactnativetracing.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,EAEV,6BAA6B,EAC7B,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAGZ,MAAM,eAAe,CAAC;AAKvB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAM7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,SAAS,CAAC;AAOtE,MAAM,WAAW,yBACf,SAAQ,6BAA6B;IACrC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,8BAA8B,CAAC;IAExD;;;;;OAKG;IACH,qCAAqC,EAAE,OAAO,CAAC;IAE/C;;;;;;;OAOG;IACH,cAAc,EAAE,cAAc,CAAC;IAE/B;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAEhC;;OAEG;IACH,0BAA0B,EAAE,OAAO,CAAC;IAEpC;;OAEG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAeD;;GAEG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD;;OAEG;IACH,OAAc,EAAE,EAAE,MAAM,CAAwB;IAChD,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAC,YAAY,CAAiB;IAC5C;;OAEG;IACI,IAAI,EAAE,MAAM,CAAyB;IAE5C,iCAAiC;IAC1B,OAAO,EAAE,yBAAyB,CAAC;IAEnC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;IAC5D,uBAAuB,EAAE,OAAO,CAAS;IAEhD,OAAO,CAAC,cAAc,CAAC,CAAY;IACnC,OAAO,CAAC,qBAAqB,CAAC,CAAyB;IACvD,OAAO,CAAC,wBAAwB,CAAC,CAAS;gBAEvB,OAAO,GAAE,OAAO,CAAC,yBAAyB,CAAM;IAkBnE;;OAEG;IACI,SAAS,CAEd,uBAAuB,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,EAC3D,aAAa,EAAE,MAAM,GAAG,GACvB,IAAI;IAiEP;;OAEG;IACI,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAQzD;;OAEG;IACI,mBAAmB,CACxB,WAAW,EAAE,WAAW,EACxB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI;IAQP;;OAEG;IACI,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAInD;;;OAGG;YACW,mBAAmB;IAgCjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiCxB,6FAA6F;IAC7F,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB,uCAAuC;IACvC,OAAO,CAAC,uBAAuB;CAkFhC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
2
|
import { defaultRequestInstrumentationOptions, instrumentOutgoingRequests, startIdleTransaction } from '@sentry/tracing';
|
|
3
3
|
import { logger } from '@sentry/utils';
|
|
4
|
+
import { APP_START_COLD, APP_START_WARM } from '../measurements';
|
|
4
5
|
import { NATIVE } from '../wrapper';
|
|
5
6
|
import { NativeFramesInstrumentation } from './nativeframes';
|
|
7
|
+
import { APP_START_COLD as APP_START_COLD_OP, APP_START_WARM as APP_START_WARM_OP, UI_LOAD, } from './ops';
|
|
6
8
|
import { StallTrackingInstrumentation } from './stalltracking';
|
|
7
9
|
import { adjustTransactionDuration, getTimeOriginMilliseconds, isNearToNow, } from './utils';
|
|
8
10
|
const defaultReactNativeTracingOptions = Object.assign(Object.assign({}, defaultRequestInstrumentationOptions), { idleTimeout: 1000, maxTransactionDuration: 600, idleTimeoutMs: 1000, finalTimeoutMs: 600000, ignoreEmptyBackNavigationTransactions: true, beforeNavigate: (context) => context, enableAppStartTracking: true, enableNativeFramesTracking: true, enableStallTracking: true });
|
|
@@ -116,7 +118,7 @@ export class ReactNativeTracing {
|
|
|
116
118
|
const appStartTimeSeconds = appStart.appStartTime / 1000;
|
|
117
119
|
const idleTransaction = this._createRouteTransaction({
|
|
118
120
|
name: 'App Start',
|
|
119
|
-
op:
|
|
121
|
+
op: UI_LOAD,
|
|
120
122
|
startTimestamp: appStartTimeSeconds,
|
|
121
123
|
});
|
|
122
124
|
if (idleTransaction) {
|
|
@@ -134,10 +136,10 @@ export class ReactNativeTracing {
|
|
|
134
136
|
return;
|
|
135
137
|
}
|
|
136
138
|
const appStartTimeSeconds = appStart.appStartTime / 1000;
|
|
137
|
-
const
|
|
139
|
+
const op = appStart.isColdStart ? APP_START_COLD_OP : APP_START_WARM_OP;
|
|
138
140
|
transaction.startChild({
|
|
139
141
|
description: appStart.isColdStart ? 'Cold App Start' : 'Warm App Start',
|
|
140
|
-
op
|
|
142
|
+
op,
|
|
141
143
|
startTimestamp: appStartTimeSeconds,
|
|
142
144
|
endTimestamp: this._appStartFinishTimestamp,
|
|
143
145
|
});
|
|
@@ -148,7 +150,8 @@ export class ReactNativeTracing {
|
|
|
148
150
|
if (appStartDurationMilliseconds >= ReactNativeTracing._maxAppStart) {
|
|
149
151
|
return;
|
|
150
152
|
}
|
|
151
|
-
|
|
153
|
+
const measurement = appStart.isColdStart ? APP_START_COLD : APP_START_WARM;
|
|
154
|
+
transaction.setMeasurement(measurement, appStartDurationMilliseconds, 'millisecond');
|
|
152
155
|
}
|
|
153
156
|
/** To be called when the route changes, but BEFORE the components of the new route mount. */
|
|
154
157
|
_onRouteWillChange(context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactnativetracing.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { Hub } from '@sentry/core';\nimport type {\n IdleTransaction,\n RequestInstrumentationOptions,\n Transaction\n} from '@sentry/tracing';\nimport {\n defaultRequestInstrumentationOptions,\n instrumentOutgoingRequests,\n startIdleTransaction\n} from '@sentry/tracing';\nimport type {\n EventProcessor,\n Integration,\n Transaction as TransactionType,\n TransactionContext,\n} from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport type { NativeAppStartResponse } from '../NativeRNSentry';\nimport type { RoutingInstrumentationInstance } from '../tracing/routingInstrumentation';\nimport { NATIVE } from '../wrapper';\nimport { NativeFramesInstrumentation } from './nativeframes';\nimport { StallTrackingInstrumentation } from './stalltracking';\nimport type { BeforeNavigate, RouteChangeContextData } from './types';\nimport {\n adjustTransactionDuration,\n getTimeOriginMilliseconds,\n isNearToNow,\n} from './utils';\n\nexport interface ReactNativeTracingOptions\n extends RequestInstrumentationOptions {\n /**\n * @deprecated Replaced by idleTimeoutMs\n */\n idleTimeout: number;\n\n /**\n * @deprecated Replaced by maxTransactionDurationMs\n */\n maxTransactionDuration: number;\n\n /**\n * The time to wait in ms until the transaction will be finished. The transaction will use the end timestamp of\n * the last finished span as the endtime for the transaction.\n * Time is in ms.\n *\n * Default: 1000\n */\n idleTimeoutMs: number;\n\n /**\n * The maximum duration (transaction duration + idle timeout) of a transaction\n * before it will be marked as \"deadline_exceeded\".\n * If you never want to mark a transaction set it to 0.\n * Time is in ms.\n *\n * Default: 600000\n */\n finalTimeoutMs: number;\n\n /**\n * The routing instrumentation to be used with the tracing integration.\n * There is no routing instrumentation if nothing is passed.\n */\n routingInstrumentation?: RoutingInstrumentationInstance;\n\n /**\n * Does not sample transactions that are from routes that have been seen any more and don't have any spans.\n * This removes a lot of the clutter as most back navigation transactions are now ignored.\n *\n * Default: true\n */\n ignoreEmptyBackNavigationTransactions: boolean;\n\n /**\n * beforeNavigate is called before a navigation transaction is created and allows users to modify transaction\n * context data, or drop the transaction entirely (by setting `sampled = false` in the context).\n *\n * @param context: The context data which will be passed to `startTransaction` by default\n *\n * @returns A (potentially) modified context object, with `sampled = false` if the transaction should be dropped.\n */\n beforeNavigate: BeforeNavigate;\n\n /**\n * Track the app start time by adding measurements to the first route transaction. If there is no routing instrumentation\n * an app start transaction will be started.\n *\n * Default: true\n */\n enableAppStartTracking: boolean;\n\n /**\n * Track slow/frozen frames from the native layer and adds them as measurements to all transactions.\n */\n enableNativeFramesTracking: boolean;\n\n /**\n * Track when and how long the JS event loop stalls for. Adds stalls as measurements to all transactions.\n */\n enableStallTracking: boolean;\n}\n\nconst defaultReactNativeTracingOptions: ReactNativeTracingOptions = {\n ...defaultRequestInstrumentationOptions,\n idleTimeout: 1000,\n maxTransactionDuration: 600,\n idleTimeoutMs: 1000,\n finalTimeoutMs: 600000,\n ignoreEmptyBackNavigationTransactions: true,\n beforeNavigate: (context) => context,\n enableAppStartTracking: true,\n enableNativeFramesTracking: true,\n enableStallTracking: true,\n};\n\n/**\n * Tracing integration for React Native.\n */\nexport class ReactNativeTracing implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'ReactNativeTracing';\n /** We filter out App starts more than 60s */\n private static _maxAppStart: number = 60000;\n /**\n * @inheritDoc\n */\n public name: string = ReactNativeTracing.id;\n\n /** ReactNativeTracing options */\n public options: ReactNativeTracingOptions;\n\n public nativeFramesInstrumentation?: NativeFramesInstrumentation;\n public stallTrackingInstrumentation?: StallTrackingInstrumentation;\n public useAppStartWithProfiler: boolean = false;\n\n private _getCurrentHub?: () => Hub;\n private _awaitingAppStartData?: NativeAppStartResponse;\n private _appStartFinishTimestamp?: number;\n\n public constructor(options: Partial<ReactNativeTracingOptions> = {}) {\n this.options = {\n ...defaultReactNativeTracingOptions,\n ...options,\n finalTimeoutMs: options.finalTimeoutMs\n // eslint-disable-next-line deprecation/deprecation\n ?? (typeof options.maxTransactionDuration === 'number'\n // eslint-disable-next-line deprecation/deprecation\n ? options.maxTransactionDuration * 1000\n : undefined)\n ?? defaultReactNativeTracingOptions.finalTimeoutMs,\n idleTimeoutMs: options.idleTimeoutMs\n // eslint-disable-next-line deprecation/deprecation\n ?? options.idleTimeout\n ?? defaultReactNativeTracingOptions.idleTimeoutMs,\n };\n }\n\n /**\n * Registers routing and request instrumentation.\n */\n public setupOnce(\n // @ts-ignore TODO\n addGlobalEventProcessor: (callback: EventProcessor) => void,\n getCurrentHub: () => Hub\n ): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const {\n traceFetch,\n traceXHR,\n // eslint-disable-next-line deprecation/deprecation\n tracingOrigins,\n // @ts-ignore TODO\n shouldCreateSpanForRequest,\n tracePropagationTargets,\n routingInstrumentation,\n enableAppStartTracking,\n enableNativeFramesTracking,\n enableStallTracking,\n } = this.options;\n\n this._getCurrentHub = getCurrentHub;\n\n if (enableAppStartTracking) {\n void this._instrumentAppStart();\n }\n\n if (enableNativeFramesTracking) {\n NATIVE.enableNativeFramesTracking();\n this.nativeFramesInstrumentation = new NativeFramesInstrumentation(\n addGlobalEventProcessor,\n () => {\n const self = getCurrentHub().getIntegration(ReactNativeTracing);\n\n if (self) {\n return !!self.nativeFramesInstrumentation;\n }\n\n return false;\n }\n );\n } else {\n NATIVE.disableNativeFramesTracking();\n }\n\n if (enableStallTracking) {\n this.stallTrackingInstrumentation = new StallTrackingInstrumentation();\n }\n\n if (routingInstrumentation) {\n routingInstrumentation.registerRoutingInstrumentation(\n this._onRouteWillChange.bind(this),\n this.options.beforeNavigate,\n this._onConfirmRoute.bind(this)\n );\n } else {\n logger.log(\n '[ReactNativeTracing] Not instrumenting route changes as routingInstrumentation has not been set.'\n );\n }\n\n instrumentOutgoingRequests({\n traceFetch,\n traceXHR,\n tracingOrigins,\n shouldCreateSpanForRequest,\n tracePropagationTargets,\n });\n }\n\n /**\n * To be called on a transaction start. Can have async methods\n */\n public onTransactionStart(transaction: Transaction): void {\n if (isNearToNow(transaction.startTimestamp)) {\n // Only if this method is called at or within margin of error to the start timestamp.\n this.nativeFramesInstrumentation?.onTransactionStart(transaction);\n this.stallTrackingInstrumentation?.onTransactionStart(transaction);\n }\n }\n\n /**\n * To be called on a transaction finish. Cannot have async methods.\n */\n public onTransactionFinish(\n transaction: Transaction,\n endTimestamp?: number\n ): void {\n this.nativeFramesInstrumentation?.onTransactionFinish(transaction);\n this.stallTrackingInstrumentation?.onTransactionFinish(\n transaction,\n endTimestamp\n );\n }\n\n /**\n * Called by the ReactNativeProfiler component on first component mount.\n */\n public onAppStartFinish(endTimestamp: number): void {\n this._appStartFinishTimestamp = endTimestamp;\n }\n\n /**\n * Instruments the app start measurements on the first route transaction.\n * Starts a route transaction if there isn't routing instrumentation.\n */\n private async _instrumentAppStart(): Promise<void> {\n if (!this.options.enableAppStartTracking || !NATIVE.enableNative) {\n return;\n }\n\n const appStart = await NATIVE.fetchNativeAppStart();\n\n if (!appStart || appStart.didFetchAppStart) {\n return;\n }\n\n if (!this.useAppStartWithProfiler) {\n this._appStartFinishTimestamp = getTimeOriginMilliseconds() / 1000;\n }\n\n if (this.options.routingInstrumentation) {\n this._awaitingAppStartData = appStart;\n } else {\n const appStartTimeSeconds = appStart.appStartTime / 1000;\n\n const idleTransaction = this._createRouteTransaction({\n name: 'App Start',\n op: 'ui.load',\n startTimestamp: appStartTimeSeconds,\n });\n\n if (idleTransaction) {\n this._addAppStartData(idleTransaction, appStart);\n }\n }\n }\n\n /**\n * Adds app start measurements and starts a child span on a transaction.\n */\n private _addAppStartData(\n transaction: IdleTransaction,\n appStart: NativeAppStartResponse\n ): void {\n if (!this._appStartFinishTimestamp) {\n logger.warn('App start was never finished.');\n return;\n }\n\n const appStartTimeSeconds = appStart.appStartTime / 1000;\n\n const appStartMode = appStart.isColdStart ? 'app.start.cold' : 'app.start.warm';\n transaction.startChild({\n description: appStart.isColdStart ? 'Cold App Start' : 'Warm App Start',\n op: appStartMode,\n startTimestamp: appStartTimeSeconds,\n endTimestamp: this._appStartFinishTimestamp,\n });\n\n const appStartDurationMilliseconds =\n this._appStartFinishTimestamp * 1000 - appStart.appStartTime;\n\n // we filter out app start more than 60s.\n // this could be due to many different reasons.\n // we've seen app starts with hours, days and even months.\n if (appStartDurationMilliseconds >= ReactNativeTracing._maxAppStart) {\n return;\n }\n\n transaction.setMeasurement(appStartMode, appStartDurationMilliseconds, 'millisecond');\n }\n\n /** To be called when the route changes, but BEFORE the components of the new route mount. */\n private _onRouteWillChange(\n context: TransactionContext\n ): TransactionType | undefined {\n return this._createRouteTransaction(context);\n }\n\n /**\n * Creates a breadcrumb and sets the current route as a tag.\n */\n private _onConfirmRoute(context: TransactionContext): void {\n this._getCurrentHub?.().configureScope((scope) => {\n if (context.data) {\n const contextData = context.data as RouteChangeContextData;\n\n scope.addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n // We assume that context.name is the name of the route.\n message: `Navigation to ${context.name}`,\n data: {\n from: contextData.previousRoute?.name,\n to: contextData.route.name,\n },\n });\n }\n\n scope.setTag('routing.route.name', context.name);\n });\n }\n\n /** Create routing idle transaction. */\n private _createRouteTransaction(\n context: TransactionContext\n ): IdleTransaction | undefined {\n if (!this._getCurrentHub) {\n logger.warn(\n `[ReactNativeTracing] Did not create ${context.op} transaction because _getCurrentHub is invalid.`\n );\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const { idleTimeoutMs, finalTimeoutMs } = this.options;\n\n const expandedContext = {\n ...context,\n trimEnd: true,\n };\n\n const hub = this._getCurrentHub();\n const idleTransaction = startIdleTransaction(\n hub as Hub,\n expandedContext,\n idleTimeoutMs,\n finalTimeoutMs,\n true\n );\n\n this.onTransactionStart(idleTransaction);\n\n logger.log(\n `[ReactNativeTracing] Starting ${context.op} transaction \"${context.name}\" on scope`\n );\n\n idleTransaction.registerBeforeFinishCallback(\n (transaction, endTimestamp) => {\n this.onTransactionFinish(transaction, endTimestamp);\n }\n );\n\n idleTransaction.registerBeforeFinishCallback((transaction) => {\n if (this.options.enableAppStartTracking && this._awaitingAppStartData) {\n transaction.startTimestamp =\n this._awaitingAppStartData.appStartTime / 1000;\n transaction.op = 'ui.load';\n\n this._addAppStartData(transaction, this._awaitingAppStartData);\n\n this._awaitingAppStartData = undefined;\n }\n });\n\n idleTransaction.registerBeforeFinishCallback(\n (transaction, endTimestamp) => {\n adjustTransactionDuration(\n finalTimeoutMs,\n transaction,\n endTimestamp\n );\n }\n );\n\n if (this.options.ignoreEmptyBackNavigationTransactions) {\n idleTransaction.registerBeforeFinishCallback((transaction) => {\n if (\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n transaction.data?.route?.hasBeenSeen &&\n (!transaction.spanRecorder ||\n transaction.spanRecorder.spans.filter(\n (span) => span.spanId !== transaction.spanId\n ).length === 0)\n ) {\n logger.log(\n '[ReactNativeTracing] Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.'\n );\n // Route has been seen before and has no child spans.\n transaction.sampled = false;\n }\n });\n }\n\n return idleTransaction;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reactnativetracing.js","sourceRoot":"","sources":["../../../src/js/tracing/reactnativetracing.ts"],"names":[],"mappings":";AAOA,OAAO,EACL,oCAAoC,EACpC,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACL,cAAc,IAAI,iBAAiB,EACnC,cAAc,IAAI,iBAAiB,EACnC,OAAO,GACR,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,WAAW,GACZ,MAAM,SAAS,CAAC;AA4EjB,MAAM,gCAAgC,mCACjC,oCAAoC,KACvC,WAAW,EAAE,IAAI,EACjB,sBAAsB,EAAE,GAAG,EAC3B,aAAa,EAAE,IAAI,EACnB,cAAc,EAAE,MAAM,EACtB,qCAAqC,EAAE,IAAI,EAC3C,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EACpC,sBAAsB,EAAE,IAAI,EAC5B,0BAA0B,EAAE,IAAI,EAChC,mBAAmB,EAAE,IAAI,GAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAuB7B,YAAmB,UAA8C,EAAE;;QAhBnE;;WAEG;QACI,SAAI,GAAW,kBAAkB,CAAC,EAAE,CAAC;QAOrC,4BAAuB,GAAY,KAAK,CAAC;QAO9C,IAAI,CAAC,OAAO,iDACP,gCAAgC,GAChC,OAAO,KACV,cAAc,cAAE,OAAO,CAAC,cAAc,mCAEjC,CAAC,OAAO,OAAO,CAAC,sBAAsB,KAAK,QAAQ;gBACpD,mDAAmD;gBACnD,CAAC,CAAC,OAAO,CAAC,sBAAsB,GAAG,IAAI;gBACvC,CAAC,CAAC,SAAS,CAAC,mCACX,gCAAgC,CAAC,cAAc,EACpD,aAAa,cAAE,OAAO,CAAC,aAAa,mCAE/B,OAAO,CAAC,WAAW,mCACnB,gCAAgC,CAAC,aAAa,GACpD,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,SAAS;IACd,kBAAkB;IAClB,uBAA2D,EAC3D,aAAwB;QAExB,6DAA6D;QAC7D,MAAM,EACJ,UAAU,EACV,QAAQ;QACR,mDAAmD;QACnD,cAAc;QACd,kBAAkB;QAClB,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,GACpB,GAAG,IAAI,CAAC,OAAO,CAAC;QAEjB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QAEpC,IAAI,sBAAsB,EAAE;YAC1B,KAAK,IAAI,CAAC,mBAAmB,EAAE,CAAC;SACjC;QAED,IAAI,0BAA0B,EAAE;YAC9B,MAAM,CAAC,0BAA0B,EAAE,CAAC;YACpC,IAAI,CAAC,2BAA2B,GAAG,IAAI,2BAA2B,CAChE,uBAAuB,EACvB,GAAG,EAAE;gBACH,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;gBAEhE,IAAI,IAAI,EAAE;oBACR,OAAO,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC;iBAC3C;gBAED,OAAO,KAAK,CAAC;YACf,CAAC,CACF,CAAC;SACH;aAAM;YACL,MAAM,CAAC,2BAA2B,EAAE,CAAC;SACtC;QAED,IAAI,mBAAmB,EAAE;YACvB,IAAI,CAAC,4BAA4B,GAAG,IAAI,4BAA4B,EAAE,CAAC;SACxE;QAED,IAAI,sBAAsB,EAAE;YAC1B,sBAAsB,CAAC,8BAA8B,CACnD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAClC,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAChC,CAAC;SACH;aAAM;YACL,MAAM,CAAC,GAAG,CACR,kGAAkG,CACnG,CAAC;SACH;QAED,0BAA0B,CAAC;YACzB,UAAU;YACV,QAAQ;YACR,cAAc;YACd,0BAA0B;YAC1B,uBAAuB;SACxB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,WAAwB;;QAChD,IAAI,WAAW,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE;YAC3C,qFAAqF;YACrF,MAAA,IAAI,CAAC,2BAA2B,0CAAE,kBAAkB,CAAC,WAAW,EAAE;YAClE,MAAA,IAAI,CAAC,4BAA4B,0CAAE,kBAAkB,CAAC,WAAW,EAAE;SACpE;IACH,CAAC;IAED;;OAEG;IACI,mBAAmB,CACxB,WAAwB,EACxB,YAAqB;;QAErB,MAAA,IAAI,CAAC,2BAA2B,0CAAE,mBAAmB,CAAC,WAAW,EAAE;QACnE,MAAA,IAAI,CAAC,4BAA4B,0CAAE,mBAAmB,CACpD,WAAW,EACX,YAAY,EACZ;IACJ,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,YAAoB;QAC1C,IAAI,CAAC,wBAAwB,GAAG,YAAY,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACW,mBAAmB;;YAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;gBAChE,OAAO;aACR;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAEpD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,gBAAgB,EAAE;gBAC1C,OAAO;aACR;YAED,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE;gBACjC,IAAI,CAAC,wBAAwB,GAAG,yBAAyB,EAAE,GAAG,IAAI,CAAC;aACpE;YAED,IAAI,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE;gBACvC,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;aACvC;iBAAM;gBACL,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC;gBAEzD,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,CAAC;oBACnD,IAAI,EAAE,WAAW;oBACjB,EAAE,EAAE,OAAO;oBACX,cAAc,EAAE,mBAAmB;iBACpC,CAAC,CAAC;gBAEH,IAAI,eAAe,EAAE;oBACnB,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;iBAClD;aACF;QACH,CAAC;KAAA;IAED;;OAEG;IACK,gBAAgB,CACtB,WAA4B,EAC5B,QAAgC;QAEhC,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE;YAClC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO;SACR;QAED,MAAM,mBAAmB,GAAG,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzD,MAAM,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,CAAC;QACxE,WAAW,CAAC,UAAU,CAAC;YACrB,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB;YACvE,EAAE;YACF,cAAc,EAAE,mBAAmB;YACnC,YAAY,EAAE,IAAI,CAAC,wBAAwB;SAC5C,CAAC,CAAC;QAEH,MAAM,4BAA4B,GAChC,IAAI,CAAC,wBAAwB,GAAG,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC;QAE/D,yCAAyC;QACzC,+CAA+C;QAC/C,0DAA0D;QAC1D,IAAI,4BAA4B,IAAI,kBAAkB,CAAC,YAAY,EAAE;YACnE,OAAO;SACR;QAED,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;QAC3E,WAAW,CAAC,cAAc,CAAC,WAAW,EAAE,4BAA4B,EAAE,aAAa,CAAC,CAAC;IACvF,CAAC;IAED,6FAA6F;IACrF,kBAAkB,CACxB,OAA2B;QAE3B,OAAO,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAA2B;;QACjD,MAAA,IAAI,CAAC,cAAc,+CAAnB,IAAI,EAAoB,cAAc,CAAC,CAAC,KAAK,EAAE,EAAE;;YAC/C,IAAI,OAAO,CAAC,IAAI,EAAE;gBAChB,MAAM,WAAW,GAAG,OAAO,CAAC,IAA8B,CAAC;gBAE3D,KAAK,CAAC,aAAa,CAAC;oBAClB,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,YAAY;oBAClB,wDAAwD;oBACxD,OAAO,EAAE,iBAAiB,OAAO,CAAC,IAAI,EAAE;oBACxC,IAAI,EAAE;wBACJ,IAAI,QAAE,WAAW,CAAC,aAAa,0CAAE,IAAI;wBACrC,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI;qBAC3B;iBACF,CAAC,CAAC;aACJ;YAED,KAAK,CAAC,MAAM,CAAC,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC,EAAE;IACL,CAAC;IAED,uCAAuC;IAC/B,uBAAuB,CAC7B,OAA2B;QAE3B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACxB,MAAM,CAAC,IAAI,CACT,uCAAuC,OAAO,CAAC,EAAE,iDAAiD,CACnG,CAAC;YACF,OAAO,SAAS,CAAC;SAClB;QAED,6DAA6D;QAC7D,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAEvD,MAAM,eAAe,mCAChB,OAAO,KACV,OAAO,EAAE,IAAI,GACd,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAClC,MAAM,eAAe,GAAG,oBAAoB,CAC1C,GAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,IAAI,CACL,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QAEzC,MAAM,CAAC,GAAG,CACR,iCAAiC,OAAO,CAAC,EAAE,iBAAiB,OAAO,CAAC,IAAI,YAAY,CACrF,CAAC;QAEF,eAAe,CAAC,4BAA4B,CAC1C,CAAC,WAAW,EAAE,YAAY,EAAE,EAAE;YAC5B,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QACtD,CAAC,CACF,CAAC;QAEF,eAAe,CAAC,4BAA4B,CAAC,CAAC,WAAW,EAAE,EAAE;YAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,sBAAsB,IAAI,IAAI,CAAC,qBAAqB,EAAE;gBACrE,WAAW,CAAC,cAAc;oBACxB,IAAI,CAAC,qBAAqB,CAAC,YAAY,GAAG,IAAI,CAAC;gBACjD,WAAW,CAAC,EAAE,GAAG,SAAS,CAAC;gBAE3B,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;gBAE/D,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;aACxC;QACH,CAAC,CAAC,CAAC;QAEH,eAAe,CAAC,4BAA4B,CAC1C,CAAC,WAAW,EAAE,YAAY,EAAE,EAAE;YAC5B,yBAAyB,CACvB,cAAc,EACd,WAAW,EACX,YAAY,CACb,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,IAAI,IAAI,CAAC,OAAO,CAAC,qCAAqC,EAAE;YACtD,eAAe,CAAC,4BAA4B,CAAC,CAAC,WAAW,EAAE,EAAE;;gBAC3D;gBACE,sEAAsE;gBACtE,aAAA,WAAW,CAAC,IAAI,0CAAE,KAAK,0CAAE,WAAW;oBACpC,CAAC,CAAC,WAAW,CAAC,YAAY;wBACxB,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CACnC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,CAC7C,CAAC,MAAM,KAAK,CAAC,CAAC,EACjB;oBACA,MAAM,CAAC,GAAG,CACR,0JAA0J,CAC3J,CAAC;oBACF,qDAAqD;oBACrD,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;iBAC7B;YACH,CAAC,CAAC,CAAC;SACJ;QAED,OAAO,eAAe,CAAC;IACzB,CAAC;;AAzUD;;GAEG;AACW,qBAAE,GAAW,oBAAoB,CAAC;AAChD,6CAA6C;AAC9B,+BAAY,GAAW,KAAK,CAAC","sourcesContent":["/* eslint-disable max-lines */\nimport type { Hub } from '@sentry/core';\nimport type {\n IdleTransaction,\n RequestInstrumentationOptions,\n Transaction\n} from '@sentry/tracing';\nimport {\n defaultRequestInstrumentationOptions,\n instrumentOutgoingRequests,\n startIdleTransaction\n} from '@sentry/tracing';\nimport type {\n EventProcessor,\n Integration,\n Transaction as TransactionType,\n TransactionContext,\n} from '@sentry/types';\nimport { logger } from '@sentry/utils';\n\nimport { APP_START_COLD, APP_START_WARM } from '../measurements';\nimport type { NativeAppStartResponse } from '../NativeRNSentry';\nimport type { RoutingInstrumentationInstance } from '../tracing/routingInstrumentation';\nimport { NATIVE } from '../wrapper';\nimport { NativeFramesInstrumentation } from './nativeframes';\nimport {\n APP_START_COLD as APP_START_COLD_OP,\n APP_START_WARM as APP_START_WARM_OP,\n UI_LOAD,\n} from './ops';\nimport { StallTrackingInstrumentation } from './stalltracking';\nimport type { BeforeNavigate, RouteChangeContextData } from './types';\nimport {\n adjustTransactionDuration,\n getTimeOriginMilliseconds,\n isNearToNow,\n} from './utils';\n\nexport interface ReactNativeTracingOptions\n extends RequestInstrumentationOptions {\n /**\n * @deprecated Replaced by idleTimeoutMs\n */\n idleTimeout: number;\n\n /**\n * @deprecated Replaced by maxTransactionDurationMs\n */\n maxTransactionDuration: number;\n\n /**\n * The time to wait in ms until the transaction will be finished. The transaction will use the end timestamp of\n * the last finished span as the endtime for the transaction.\n * Time is in ms.\n *\n * Default: 1000\n */\n idleTimeoutMs: number;\n\n /**\n * The maximum duration (transaction duration + idle timeout) of a transaction\n * before it will be marked as \"deadline_exceeded\".\n * If you never want to mark a transaction set it to 0.\n * Time is in ms.\n *\n * Default: 600000\n */\n finalTimeoutMs: number;\n\n /**\n * The routing instrumentation to be used with the tracing integration.\n * There is no routing instrumentation if nothing is passed.\n */\n routingInstrumentation?: RoutingInstrumentationInstance;\n\n /**\n * Does not sample transactions that are from routes that have been seen any more and don't have any spans.\n * This removes a lot of the clutter as most back navigation transactions are now ignored.\n *\n * Default: true\n */\n ignoreEmptyBackNavigationTransactions: boolean;\n\n /**\n * beforeNavigate is called before a navigation transaction is created and allows users to modify transaction\n * context data, or drop the transaction entirely (by setting `sampled = false` in the context).\n *\n * @param context: The context data which will be passed to `startTransaction` by default\n *\n * @returns A (potentially) modified context object, with `sampled = false` if the transaction should be dropped.\n */\n beforeNavigate: BeforeNavigate;\n\n /**\n * Track the app start time by adding measurements to the first route transaction. If there is no routing instrumentation\n * an app start transaction will be started.\n *\n * Default: true\n */\n enableAppStartTracking: boolean;\n\n /**\n * Track slow/frozen frames from the native layer and adds them as measurements to all transactions.\n */\n enableNativeFramesTracking: boolean;\n\n /**\n * Track when and how long the JS event loop stalls for. Adds stalls as measurements to all transactions.\n */\n enableStallTracking: boolean;\n}\n\nconst defaultReactNativeTracingOptions: ReactNativeTracingOptions = {\n ...defaultRequestInstrumentationOptions,\n idleTimeout: 1000,\n maxTransactionDuration: 600,\n idleTimeoutMs: 1000,\n finalTimeoutMs: 600000,\n ignoreEmptyBackNavigationTransactions: true,\n beforeNavigate: (context) => context,\n enableAppStartTracking: true,\n enableNativeFramesTracking: true,\n enableStallTracking: true,\n};\n\n/**\n * Tracing integration for React Native.\n */\nexport class ReactNativeTracing implements Integration {\n /**\n * @inheritDoc\n */\n public static id: string = 'ReactNativeTracing';\n /** We filter out App starts more than 60s */\n private static _maxAppStart: number = 60000;\n /**\n * @inheritDoc\n */\n public name: string = ReactNativeTracing.id;\n\n /** ReactNativeTracing options */\n public options: ReactNativeTracingOptions;\n\n public nativeFramesInstrumentation?: NativeFramesInstrumentation;\n public stallTrackingInstrumentation?: StallTrackingInstrumentation;\n public useAppStartWithProfiler: boolean = false;\n\n private _getCurrentHub?: () => Hub;\n private _awaitingAppStartData?: NativeAppStartResponse;\n private _appStartFinishTimestamp?: number;\n\n public constructor(options: Partial<ReactNativeTracingOptions> = {}) {\n this.options = {\n ...defaultReactNativeTracingOptions,\n ...options,\n finalTimeoutMs: options.finalTimeoutMs\n // eslint-disable-next-line deprecation/deprecation\n ?? (typeof options.maxTransactionDuration === 'number'\n // eslint-disable-next-line deprecation/deprecation\n ? options.maxTransactionDuration * 1000\n : undefined)\n ?? defaultReactNativeTracingOptions.finalTimeoutMs,\n idleTimeoutMs: options.idleTimeoutMs\n // eslint-disable-next-line deprecation/deprecation\n ?? options.idleTimeout\n ?? defaultReactNativeTracingOptions.idleTimeoutMs,\n };\n }\n\n /**\n * Registers routing and request instrumentation.\n */\n public setupOnce(\n // @ts-ignore TODO\n addGlobalEventProcessor: (callback: EventProcessor) => void,\n getCurrentHub: () => Hub\n ): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const {\n traceFetch,\n traceXHR,\n // eslint-disable-next-line deprecation/deprecation\n tracingOrigins,\n // @ts-ignore TODO\n shouldCreateSpanForRequest,\n tracePropagationTargets,\n routingInstrumentation,\n enableAppStartTracking,\n enableNativeFramesTracking,\n enableStallTracking,\n } = this.options;\n\n this._getCurrentHub = getCurrentHub;\n\n if (enableAppStartTracking) {\n void this._instrumentAppStart();\n }\n\n if (enableNativeFramesTracking) {\n NATIVE.enableNativeFramesTracking();\n this.nativeFramesInstrumentation = new NativeFramesInstrumentation(\n addGlobalEventProcessor,\n () => {\n const self = getCurrentHub().getIntegration(ReactNativeTracing);\n\n if (self) {\n return !!self.nativeFramesInstrumentation;\n }\n\n return false;\n }\n );\n } else {\n NATIVE.disableNativeFramesTracking();\n }\n\n if (enableStallTracking) {\n this.stallTrackingInstrumentation = new StallTrackingInstrumentation();\n }\n\n if (routingInstrumentation) {\n routingInstrumentation.registerRoutingInstrumentation(\n this._onRouteWillChange.bind(this),\n this.options.beforeNavigate,\n this._onConfirmRoute.bind(this)\n );\n } else {\n logger.log(\n '[ReactNativeTracing] Not instrumenting route changes as routingInstrumentation has not been set.'\n );\n }\n\n instrumentOutgoingRequests({\n traceFetch,\n traceXHR,\n tracingOrigins,\n shouldCreateSpanForRequest,\n tracePropagationTargets,\n });\n }\n\n /**\n * To be called on a transaction start. Can have async methods\n */\n public onTransactionStart(transaction: Transaction): void {\n if (isNearToNow(transaction.startTimestamp)) {\n // Only if this method is called at or within margin of error to the start timestamp.\n this.nativeFramesInstrumentation?.onTransactionStart(transaction);\n this.stallTrackingInstrumentation?.onTransactionStart(transaction);\n }\n }\n\n /**\n * To be called on a transaction finish. Cannot have async methods.\n */\n public onTransactionFinish(\n transaction: Transaction,\n endTimestamp?: number\n ): void {\n this.nativeFramesInstrumentation?.onTransactionFinish(transaction);\n this.stallTrackingInstrumentation?.onTransactionFinish(\n transaction,\n endTimestamp\n );\n }\n\n /**\n * Called by the ReactNativeProfiler component on first component mount.\n */\n public onAppStartFinish(endTimestamp: number): void {\n this._appStartFinishTimestamp = endTimestamp;\n }\n\n /**\n * Instruments the app start measurements on the first route transaction.\n * Starts a route transaction if there isn't routing instrumentation.\n */\n private async _instrumentAppStart(): Promise<void> {\n if (!this.options.enableAppStartTracking || !NATIVE.enableNative) {\n return;\n }\n\n const appStart = await NATIVE.fetchNativeAppStart();\n\n if (!appStart || appStart.didFetchAppStart) {\n return;\n }\n\n if (!this.useAppStartWithProfiler) {\n this._appStartFinishTimestamp = getTimeOriginMilliseconds() / 1000;\n }\n\n if (this.options.routingInstrumentation) {\n this._awaitingAppStartData = appStart;\n } else {\n const appStartTimeSeconds = appStart.appStartTime / 1000;\n\n const idleTransaction = this._createRouteTransaction({\n name: 'App Start',\n op: UI_LOAD,\n startTimestamp: appStartTimeSeconds,\n });\n\n if (idleTransaction) {\n this._addAppStartData(idleTransaction, appStart);\n }\n }\n }\n\n /**\n * Adds app start measurements and starts a child span on a transaction.\n */\n private _addAppStartData(\n transaction: IdleTransaction,\n appStart: NativeAppStartResponse\n ): void {\n if (!this._appStartFinishTimestamp) {\n logger.warn('App start was never finished.');\n return;\n }\n\n const appStartTimeSeconds = appStart.appStartTime / 1000;\n\n const op = appStart.isColdStart ? APP_START_COLD_OP : APP_START_WARM_OP;\n transaction.startChild({\n description: appStart.isColdStart ? 'Cold App Start' : 'Warm App Start',\n op,\n startTimestamp: appStartTimeSeconds,\n endTimestamp: this._appStartFinishTimestamp,\n });\n\n const appStartDurationMilliseconds =\n this._appStartFinishTimestamp * 1000 - appStart.appStartTime;\n\n // we filter out app start more than 60s.\n // this could be due to many different reasons.\n // we've seen app starts with hours, days and even months.\n if (appStartDurationMilliseconds >= ReactNativeTracing._maxAppStart) {\n return;\n }\n\n const measurement = appStart.isColdStart ? APP_START_COLD : APP_START_WARM;\n transaction.setMeasurement(measurement, appStartDurationMilliseconds, 'millisecond');\n }\n\n /** To be called when the route changes, but BEFORE the components of the new route mount. */\n private _onRouteWillChange(\n context: TransactionContext\n ): TransactionType | undefined {\n return this._createRouteTransaction(context);\n }\n\n /**\n * Creates a breadcrumb and sets the current route as a tag.\n */\n private _onConfirmRoute(context: TransactionContext): void {\n this._getCurrentHub?.().configureScope((scope) => {\n if (context.data) {\n const contextData = context.data as RouteChangeContextData;\n\n scope.addBreadcrumb({\n category: 'navigation',\n type: 'navigation',\n // We assume that context.name is the name of the route.\n message: `Navigation to ${context.name}`,\n data: {\n from: contextData.previousRoute?.name,\n to: contextData.route.name,\n },\n });\n }\n\n scope.setTag('routing.route.name', context.name);\n });\n }\n\n /** Create routing idle transaction. */\n private _createRouteTransaction(\n context: TransactionContext\n ): IdleTransaction | undefined {\n if (!this._getCurrentHub) {\n logger.warn(\n `[ReactNativeTracing] Did not create ${context.op} transaction because _getCurrentHub is invalid.`\n );\n return undefined;\n }\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const { idleTimeoutMs, finalTimeoutMs } = this.options;\n\n const expandedContext = {\n ...context,\n trimEnd: true,\n };\n\n const hub = this._getCurrentHub();\n const idleTransaction = startIdleTransaction(\n hub as Hub,\n expandedContext,\n idleTimeoutMs,\n finalTimeoutMs,\n true\n );\n\n this.onTransactionStart(idleTransaction);\n\n logger.log(\n `[ReactNativeTracing] Starting ${context.op} transaction \"${context.name}\" on scope`\n );\n\n idleTransaction.registerBeforeFinishCallback(\n (transaction, endTimestamp) => {\n this.onTransactionFinish(transaction, endTimestamp);\n }\n );\n\n idleTransaction.registerBeforeFinishCallback((transaction) => {\n if (this.options.enableAppStartTracking && this._awaitingAppStartData) {\n transaction.startTimestamp =\n this._awaitingAppStartData.appStartTime / 1000;\n transaction.op = 'ui.load';\n\n this._addAppStartData(transaction, this._awaitingAppStartData);\n\n this._awaitingAppStartData = undefined;\n }\n });\n\n idleTransaction.registerBeforeFinishCallback(\n (transaction, endTimestamp) => {\n adjustTransactionDuration(\n finalTimeoutMs,\n transaction,\n endTimestamp\n );\n }\n );\n\n if (this.options.ignoreEmptyBackNavigationTransactions) {\n idleTransaction.registerBeforeFinishCallback((transaction) => {\n if (\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n transaction.data?.route?.hasBeenSeen &&\n (!transaction.spanRecorder ||\n transaction.spanRecorder.spans.filter(\n (span) => span.spanId !== transaction.spanId\n ).length === 0)\n ) {\n logger.log(\n '[ReactNativeTracing] Not sampling transaction as route has been seen before. Pass ignoreEmptyBackNavigationTransactions = false to disable this feature.'\n );\n // Route has been seen before and has no child spans.\n transaction.sampled = false;\n }\n });\n }\n\n return idleTransaction;\n }\n}\n"]}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import type { IdleTransaction, Transaction } from '@sentry/tracing';
|
|
2
2
|
import type { Measurements, MeasurementUnit } from '@sentry/types';
|
|
3
|
+
import { STALL_COUNT, STALL_LONGEST_TIME, STALL_TOTAL_TIME } from '../measurements';
|
|
3
4
|
export interface StallMeasurements extends Measurements {
|
|
4
|
-
|
|
5
|
+
[STALL_COUNT]: {
|
|
5
6
|
value: number;
|
|
6
7
|
unit: MeasurementUnit;
|
|
7
8
|
};
|
|
8
|
-
|
|
9
|
+
[STALL_TOTAL_TIME]: {
|
|
9
10
|
value: number;
|
|
10
11
|
unit: MeasurementUnit;
|
|
11
12
|
};
|
|
12
|
-
|
|
13
|
+
[STALL_LONGEST_TIME]: {
|
|
13
14
|
value: number;
|
|
14
15
|
unit: MeasurementUnit;
|
|
15
16
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stalltracking.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/stalltracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAQ,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGnE,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,
|
|
1
|
+
{"version":3,"file":"stalltracking.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/stalltracking.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAQ,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,CAAC,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IACxD,CAAC,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;IAC7D,CAAC,kBAAkB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CAChE;AAED,oBAAY,oBAAoB,GAAG;IACjC;;;OAGG;IACH,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC;AASF;;;;;;GAMG;AACH,qBAAa,4BAA4B;IAChC,UAAU,EAAE,OAAO,CAAS;IAEnC,OAAO,CAAC,sBAAsB,CAAS;IAEvC,2FAA2F;IAC3F,OAAO,CAAC,eAAe,CAAa;IACpC,+EAA+E;IAC/E,OAAO,CAAC,WAAW,CAAa;IAEhC,2DAA2D;IAC3D,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,QAAQ,CAA8C;IAE9D,OAAO,CAAC,mBAAmB,CAUb;gBAGZ,OAAO,GAAE,oBAAoD;IAK/D;;;OAGG;IACI,SAAS,IAAI,IAAI;IAIxB;;;OAGG;IACI,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAwCzD;;;;OAIG;IACI,mBAAmB,CACxB,WAAW,EAAE,WAAW,GAAG,eAAe,EAC1C,kBAAkB,CAAC,EAAE,MAAM,GAC1B,IAAI;IAuGP;;OAEG;IACH,OAAO,CAAC,eAAe;IAoCvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,MAAM;IAOd;;;OAGG;IACH,OAAO,CAAC,UAAU;IAmClB;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAYjC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { logger, timestampInSeconds } from '@sentry/utils';
|
|
2
|
+
import { STALL_COUNT, STALL_LONGEST_TIME, STALL_TOTAL_TIME } from '../measurements';
|
|
2
3
|
/** Margin of error of 20ms */
|
|
3
4
|
const MARGIN_OF_ERROR_SECONDS = 0.02;
|
|
4
5
|
/** How long between each iteration in the event loop tracker timeout */
|
|
@@ -136,11 +137,11 @@ export class StallTrackingInstrumentation {
|
|
|
136
137
|
}
|
|
137
138
|
return;
|
|
138
139
|
}
|
|
139
|
-
transaction.setMeasurement(
|
|
140
|
+
transaction.setMeasurement(STALL_COUNT, statsOnFinish.stall_count.value -
|
|
140
141
|
transactionStats.atStart.stall_count.value, transactionStats.atStart.stall_count.unit);
|
|
141
|
-
transaction.setMeasurement(
|
|
142
|
+
transaction.setMeasurement(STALL_TOTAL_TIME, statsOnFinish.stall_total_time.value -
|
|
142
143
|
transactionStats.atStart.stall_total_time.value, transactionStats.atStart.stall_total_time.unit);
|
|
143
|
-
transaction.setMeasurement(
|
|
144
|
+
transaction.setMeasurement(STALL_LONGEST_TIME, statsOnFinish.stall_longest_time.value, statsOnFinish.stall_longest_time.unit);
|
|
144
145
|
}
|
|
145
146
|
/**
|
|
146
147
|
* Logs the finish time of the span for use in `trimEnd: true` transactions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stalltracking.js","sourceRoot":"","sources":["../../../src/js/tracing/stalltracking.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { IdleTransaction, Span, Transaction } from '@sentry/tracing';\nimport type { Measurements, MeasurementUnit } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nexport interface StallMeasurements extends Measurements {\n 'stall_count': { value: number, unit: MeasurementUnit };\n 'stall_total_time': { value: number, unit: MeasurementUnit };\n 'stall_longest_time': { value: number, unit: MeasurementUnit };\n}\n\nexport type StallTrackingOptions = {\n /**\n * How long in milliseconds an event loop iteration can be delayed for before being considered a \"stall.\"\n * @default 100\n */\n minimumStallThreshold: number;\n};\n\n/** Margin of error of 20ms */\nconst MARGIN_OF_ERROR_SECONDS = 0.02;\n/** How long between each iteration in the event loop tracker timeout */\nconst LOOP_TIMEOUT_INTERVAL_MS = 50;\n/** Limit for how many transactions the stall tracker will track at a time to prevent leaks due to transactions not being finished */\nconst MAX_RUNNING_TRANSACTIONS = 10;\n\n/**\n * Stall measurement tracker inspired by the `JSEventLoopWatchdog` used internally in React Native:\n * https://github.com/facebook/react-native/blob/006f5afe120c290a37cf6ff896748fbc062bf7ed/Libraries/Interaction/JSEventLoopWatchdog.js\n *\n * However, we modified the interval implementation to instead have a fixed loop timeout interval of `LOOP_TIMEOUT_INTERVAL_MS`.\n * We then would consider that iteration a stall when the total time for that interval to run is greater than `LOOP_TIMEOUT_INTERVAL_MS + minimumStallThreshold`\n */\nexport class StallTrackingInstrumentation {\n public isTracking: boolean = false;\n\n private _minimumStallThreshold: number;\n\n /** Total amount of time of all stalls that occurred during the current tracking session */\n private _totalStallTime: number = 0;\n /** Total number of stalls that occurred during the current tracking session */\n private _stallCount: number = 0;\n\n /** The last timestamp the iteration ran in milliseconds */\n private _lastIntervalMs: number = 0;\n private _timeout: ReturnType<typeof setTimeout> | null = null;\n\n private _statsByTransaction: Map<\n Transaction,\n {\n longestStallTime: number;\n atStart: StallMeasurements;\n atTimestamp: {\n timestamp: number;\n stats: StallMeasurements;\n } | null;\n }\n > = new Map();\n\n public constructor(\n options: StallTrackingOptions = { minimumStallThreshold: 50 }\n ) {\n this._minimumStallThreshold = options.minimumStallThreshold;\n }\n\n /**\n * @inheritDoc\n * Not used for this integration. Instead call `registerTransactionStart` to start tracking.\n */\n public setupOnce(): void {\n // Do nothing.\n }\n\n /**\n * Register a transaction as started. Starts stall tracking if not already running.\n * @returns A finish method that returns the stall measurements.\n */\n public onTransactionStart(transaction: Transaction): void {\n if (this._statsByTransaction.has(transaction)) {\n logger.error(\n '[StallTracking] Tried to start stall tracking on a transaction already being tracked. Measurements might be lost.'\n );\n\n return;\n }\n\n this._startTracking();\n this._statsByTransaction.set(transaction, {\n longestStallTime: 0,\n atTimestamp: null,\n atStart: this._getCurrentStats(transaction),\n });\n this._flushLeakedTransactions();\n\n if (transaction.spanRecorder) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalAdd = transaction.spanRecorder.add;\n\n transaction.spanRecorder.add = (span: Span): void => {\n originalAdd.apply(transaction.spanRecorder, [span]);\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalSpanFinish = span.finish;\n\n span.finish = (endTimestamp?: number) => {\n // We let the span determine its own end timestamp as well in case anything gets changed upstream\n originalSpanFinish.apply(span, [endTimestamp]);\n\n // The span should set a timestamp, so this would be defined.\n if (span.endTimestamp) {\n this._markSpanFinish(transaction, span.endTimestamp);\n }\n };\n };\n }\n }\n\n /**\n * Logs a transaction as finished.\n * Stops stall tracking if no more transactions are running.\n * @returns The stall measurements\n */\n public onTransactionFinish(\n transaction: Transaction | IdleTransaction,\n passedEndTimestamp?: number\n ): void {\n const transactionStats = this._statsByTransaction.get(transaction);\n\n if (!transactionStats) {\n // Transaction has been flushed out somehow, we return null.\n logger.log(\n '[StallTracking] Stall measurements were not added to transaction due to exceeding the max count.'\n );\n\n this._statsByTransaction.delete(transaction);\n this._shouldStopTracking();\n\n return;\n }\n\n const endTimestamp = passedEndTimestamp ?? transaction.endTimestamp;\n\n const spans = transaction.spanRecorder\n ? transaction.spanRecorder.spans\n : [];\n const finishedSpanCount = spans.reduce(\n (count, s) => (s !== transaction && s.endTimestamp ? count + 1 : count),\n 0\n );\n\n const trimEnd = transaction.toContext().trimEnd;\n const endWillBeTrimmed = trimEnd && finishedSpanCount > 0;\n\n /*\n This is not safe in the case that something changes upstream, but if we're planning to move this over to @sentry/javascript anyways,\n we can have this temporarily for now.\n */\n const isIdleTransaction = 'activities' in transaction;\n\n let statsOnFinish: StallMeasurements | undefined;\n if (endTimestamp && isIdleTransaction) {\n /*\n There is different behavior regarding child spans in a normal transaction and an idle transaction. In normal transactions,\n the child spans that aren't finished will be dumped, while in an idle transaction they're cancelled and finished.\n\n Note: `endTimestamp` will always be defined if this is called on an idle transaction finish. This is because we only instrument\n idle transactions inside `ReactNativeTracing`, which will pass an `endTimestamp`.\n */\n\n // There will be cancelled spans, which means that the end won't be trimmed\n const spansWillBeCancelled = spans.some(\n (s) =>\n s !== transaction &&\n s.startTimestamp < endTimestamp &&\n !s.endTimestamp\n );\n\n if (endWillBeTrimmed && !spansWillBeCancelled) {\n // the last span's timestamp will be used.\n\n if (transactionStats.atTimestamp) {\n statsOnFinish = transactionStats.atTimestamp.stats;\n }\n } else {\n // this endTimestamp will be used.\n statsOnFinish = this._getCurrentStats(transaction);\n }\n } else if (endWillBeTrimmed) {\n // If `trimEnd` is used, and there is a span to trim to. If there isn't, then the transaction should use `endTimestamp` or generate one.\n if (transactionStats.atTimestamp) {\n statsOnFinish = transactionStats.atTimestamp.stats;\n }\n } else if (!endTimestamp) {\n statsOnFinish = this._getCurrentStats(transaction);\n }\n\n this._statsByTransaction.delete(transaction);\n this._shouldStopTracking();\n\n if (!statsOnFinish) {\n if (typeof endTimestamp !== 'undefined') {\n logger.log(\n '[StallTracking] Stall measurements not added due to `endTimestamp` being set.'\n );\n } else if (trimEnd) {\n logger.log(\n '[StallTracking] Stall measurements not added due to `trimEnd` being set but we could not determine the stall measurements at that time.'\n );\n }\n\n return;\n }\n\n transaction.setMeasurement('stall_count',\n statsOnFinish.stall_count.value -\n transactionStats.atStart.stall_count.value,\n transactionStats.atStart.stall_count.unit);\n\n transaction.setMeasurement('stall_total_time',\n statsOnFinish.stall_total_time.value -\n transactionStats.atStart.stall_total_time.value,\n transactionStats.atStart.stall_total_time.unit);\n\n transaction.setMeasurement('stall_longest_time',\n statsOnFinish.stall_longest_time.value,\n statsOnFinish.stall_longest_time.unit);\n }\n\n /**\n * Logs the finish time of the span for use in `trimEnd: true` transactions.\n */\n private _markSpanFinish(\n transaction: Transaction,\n spanEndTimestamp: number\n ): void {\n const previousStats = this._statsByTransaction.get(transaction);\n if (previousStats) {\n if (\n Math.abs(timestampInSeconds() - spanEndTimestamp) >\n MARGIN_OF_ERROR_SECONDS\n ) {\n logger.log(\n '[StallTracking] Span end not logged due to end timestamp being outside the margin of error from now.'\n );\n\n if (\n previousStats.atTimestamp &&\n previousStats.atTimestamp.timestamp < spanEndTimestamp\n ) {\n // We also need to delete the stat for the last span, as the transaction would be trimmed to this span not the last one.\n this._statsByTransaction.set(transaction, {\n ...previousStats,\n atTimestamp: null,\n });\n }\n } else {\n this._statsByTransaction.set(transaction, {\n ...previousStats,\n atTimestamp: {\n timestamp: spanEndTimestamp,\n stats: this._getCurrentStats(transaction),\n },\n });\n }\n }\n }\n\n /**\n * Get the current stats for a transaction at a given time.\n */\n private _getCurrentStats(transaction: Transaction): StallMeasurements {\n return {\n stall_count: { value: this._stallCount, unit: 'none' },\n stall_total_time: { value: this._totalStallTime, unit: 'millisecond' },\n stall_longest_time: {\n value: this._statsByTransaction.get(transaction)?.longestStallTime ?? 0, unit: 'millisecond'\n },\n };\n }\n\n /**\n * Start tracking stalls\n */\n private _startTracking(): void {\n if (!this.isTracking) {\n this.isTracking = true;\n this._lastIntervalMs = Math.floor(timestampInSeconds() * 1000);\n\n this._iteration();\n }\n }\n\n /**\n * Stops the stall tracking interval and calls reset().\n */\n private _stopTracking(): void {\n this.isTracking = false;\n\n if (this._timeout !== null) {\n clearTimeout(this._timeout);\n this._timeout = null;\n }\n\n this._reset();\n }\n\n /**\n * Will stop tracking if there are no more transactions.\n */\n private _shouldStopTracking(): void {\n if (this._statsByTransaction.size === 0) {\n this._stopTracking();\n }\n }\n\n /**\n * Clears all the collected stats\n */\n private _reset(): void {\n this._stallCount = 0;\n this._totalStallTime = 0;\n this._lastIntervalMs = 0;\n this._statsByTransaction.clear();\n }\n\n /**\n * Iteration of the stall tracking interval. Measures how long the timer strayed from its expected time of running, and how\n * long the stall is for.\n */\n private _iteration(): void {\n const now = timestampInSeconds() * 1000;\n const totalTimeTaken = now - this._lastIntervalMs;\n\n if (\n totalTimeTaken >=\n LOOP_TIMEOUT_INTERVAL_MS + this._minimumStallThreshold\n ) {\n const stallTime = totalTimeTaken - LOOP_TIMEOUT_INTERVAL_MS;\n this._stallCount += 1;\n this._totalStallTime += stallTime;\n\n for (const [transaction, value] of this._statsByTransaction.entries()) {\n const longestStallTime = Math.max(\n value.longestStallTime ?? 0,\n stallTime\n );\n\n this._statsByTransaction.set(transaction, {\n ...value,\n longestStallTime,\n });\n }\n }\n\n this._lastIntervalMs = now;\n\n if (this.isTracking) {\n this._timeout = setTimeout(\n this._iteration.bind(this),\n LOOP_TIMEOUT_INTERVAL_MS\n );\n }\n }\n\n /**\n * Deletes leaked transactions (Earliest transactions when we have more than MAX_RUNNING_TRANSACTIONS transactions.)\n */\n private _flushLeakedTransactions(): void {\n if (this._statsByTransaction.size > MAX_RUNNING_TRANSACTIONS) {\n let counter = 0;\n const len = this._statsByTransaction.size - MAX_RUNNING_TRANSACTIONS;\n const transactions = this._statsByTransaction.keys();\n for (const t of transactions) {\n if (counter >= len) break;\n counter += 1;\n this._statsByTransaction.delete(t);\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stalltracking.js","sourceRoot":"","sources":["../../../src/js/tracing/stalltracking.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport type { IdleTransaction, Span, Transaction } from '@sentry/tracing';\nimport type { Measurements, MeasurementUnit } from '@sentry/types';\nimport { logger, timestampInSeconds } from '@sentry/utils';\n\nimport { STALL_COUNT, STALL_LONGEST_TIME, STALL_TOTAL_TIME } from '../measurements';\n\nexport interface StallMeasurements extends Measurements {\n [STALL_COUNT]: { value: number, unit: MeasurementUnit };\n [STALL_TOTAL_TIME]: { value: number, unit: MeasurementUnit };\n [STALL_LONGEST_TIME]: { value: number, unit: MeasurementUnit };\n}\n\nexport type StallTrackingOptions = {\n /**\n * How long in milliseconds an event loop iteration can be delayed for before being considered a \"stall.\"\n * @default 100\n */\n minimumStallThreshold: number;\n};\n\n/** Margin of error of 20ms */\nconst MARGIN_OF_ERROR_SECONDS = 0.02;\n/** How long between each iteration in the event loop tracker timeout */\nconst LOOP_TIMEOUT_INTERVAL_MS = 50;\n/** Limit for how many transactions the stall tracker will track at a time to prevent leaks due to transactions not being finished */\nconst MAX_RUNNING_TRANSACTIONS = 10;\n\n/**\n * Stall measurement tracker inspired by the `JSEventLoopWatchdog` used internally in React Native:\n * https://github.com/facebook/react-native/blob/006f5afe120c290a37cf6ff896748fbc062bf7ed/Libraries/Interaction/JSEventLoopWatchdog.js\n *\n * However, we modified the interval implementation to instead have a fixed loop timeout interval of `LOOP_TIMEOUT_INTERVAL_MS`.\n * We then would consider that iteration a stall when the total time for that interval to run is greater than `LOOP_TIMEOUT_INTERVAL_MS + minimumStallThreshold`\n */\nexport class StallTrackingInstrumentation {\n public isTracking: boolean = false;\n\n private _minimumStallThreshold: number;\n\n /** Total amount of time of all stalls that occurred during the current tracking session */\n private _totalStallTime: number = 0;\n /** Total number of stalls that occurred during the current tracking session */\n private _stallCount: number = 0;\n\n /** The last timestamp the iteration ran in milliseconds */\n private _lastIntervalMs: number = 0;\n private _timeout: ReturnType<typeof setTimeout> | null = null;\n\n private _statsByTransaction: Map<\n Transaction,\n {\n longestStallTime: number;\n atStart: StallMeasurements;\n atTimestamp: {\n timestamp: number;\n stats: StallMeasurements;\n } | null;\n }\n > = new Map();\n\n public constructor(\n options: StallTrackingOptions = { minimumStallThreshold: 50 }\n ) {\n this._minimumStallThreshold = options.minimumStallThreshold;\n }\n\n /**\n * @inheritDoc\n * Not used for this integration. Instead call `registerTransactionStart` to start tracking.\n */\n public setupOnce(): void {\n // Do nothing.\n }\n\n /**\n * Register a transaction as started. Starts stall tracking if not already running.\n * @returns A finish method that returns the stall measurements.\n */\n public onTransactionStart(transaction: Transaction): void {\n if (this._statsByTransaction.has(transaction)) {\n logger.error(\n '[StallTracking] Tried to start stall tracking on a transaction already being tracked. Measurements might be lost.'\n );\n\n return;\n }\n\n this._startTracking();\n this._statsByTransaction.set(transaction, {\n longestStallTime: 0,\n atTimestamp: null,\n atStart: this._getCurrentStats(transaction),\n });\n this._flushLeakedTransactions();\n\n if (transaction.spanRecorder) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalAdd = transaction.spanRecorder.add;\n\n transaction.spanRecorder.add = (span: Span): void => {\n originalAdd.apply(transaction.spanRecorder, [span]);\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalSpanFinish = span.finish;\n\n span.finish = (endTimestamp?: number) => {\n // We let the span determine its own end timestamp as well in case anything gets changed upstream\n originalSpanFinish.apply(span, [endTimestamp]);\n\n // The span should set a timestamp, so this would be defined.\n if (span.endTimestamp) {\n this._markSpanFinish(transaction, span.endTimestamp);\n }\n };\n };\n }\n }\n\n /**\n * Logs a transaction as finished.\n * Stops stall tracking if no more transactions are running.\n * @returns The stall measurements\n */\n public onTransactionFinish(\n transaction: Transaction | IdleTransaction,\n passedEndTimestamp?: number\n ): void {\n const transactionStats = this._statsByTransaction.get(transaction);\n\n if (!transactionStats) {\n // Transaction has been flushed out somehow, we return null.\n logger.log(\n '[StallTracking] Stall measurements were not added to transaction due to exceeding the max count.'\n );\n\n this._statsByTransaction.delete(transaction);\n this._shouldStopTracking();\n\n return;\n }\n\n const endTimestamp = passedEndTimestamp ?? transaction.endTimestamp;\n\n const spans = transaction.spanRecorder\n ? transaction.spanRecorder.spans\n : [];\n const finishedSpanCount = spans.reduce(\n (count, s) => (s !== transaction && s.endTimestamp ? count + 1 : count),\n 0\n );\n\n const trimEnd = transaction.toContext().trimEnd;\n const endWillBeTrimmed = trimEnd && finishedSpanCount > 0;\n\n /*\n This is not safe in the case that something changes upstream, but if we're planning to move this over to @sentry/javascript anyways,\n we can have this temporarily for now.\n */\n const isIdleTransaction = 'activities' in transaction;\n\n let statsOnFinish: StallMeasurements | undefined;\n if (endTimestamp && isIdleTransaction) {\n /*\n There is different behavior regarding child spans in a normal transaction and an idle transaction. In normal transactions,\n the child spans that aren't finished will be dumped, while in an idle transaction they're cancelled and finished.\n\n Note: `endTimestamp` will always be defined if this is called on an idle transaction finish. This is because we only instrument\n idle transactions inside `ReactNativeTracing`, which will pass an `endTimestamp`.\n */\n\n // There will be cancelled spans, which means that the end won't be trimmed\n const spansWillBeCancelled = spans.some(\n (s) =>\n s !== transaction &&\n s.startTimestamp < endTimestamp &&\n !s.endTimestamp\n );\n\n if (endWillBeTrimmed && !spansWillBeCancelled) {\n // the last span's timestamp will be used.\n\n if (transactionStats.atTimestamp) {\n statsOnFinish = transactionStats.atTimestamp.stats;\n }\n } else {\n // this endTimestamp will be used.\n statsOnFinish = this._getCurrentStats(transaction);\n }\n } else if (endWillBeTrimmed) {\n // If `trimEnd` is used, and there is a span to trim to. If there isn't, then the transaction should use `endTimestamp` or generate one.\n if (transactionStats.atTimestamp) {\n statsOnFinish = transactionStats.atTimestamp.stats;\n }\n } else if (!endTimestamp) {\n statsOnFinish = this._getCurrentStats(transaction);\n }\n\n this._statsByTransaction.delete(transaction);\n this._shouldStopTracking();\n\n if (!statsOnFinish) {\n if (typeof endTimestamp !== 'undefined') {\n logger.log(\n '[StallTracking] Stall measurements not added due to `endTimestamp` being set.'\n );\n } else if (trimEnd) {\n logger.log(\n '[StallTracking] Stall measurements not added due to `trimEnd` being set but we could not determine the stall measurements at that time.'\n );\n }\n\n return;\n }\n\n transaction.setMeasurement(STALL_COUNT,\n statsOnFinish.stall_count.value -\n transactionStats.atStart.stall_count.value,\n transactionStats.atStart.stall_count.unit);\n\n transaction.setMeasurement(STALL_TOTAL_TIME,\n statsOnFinish.stall_total_time.value -\n transactionStats.atStart.stall_total_time.value,\n transactionStats.atStart.stall_total_time.unit);\n\n transaction.setMeasurement(STALL_LONGEST_TIME,\n statsOnFinish.stall_longest_time.value,\n statsOnFinish.stall_longest_time.unit);\n }\n\n /**\n * Logs the finish time of the span for use in `trimEnd: true` transactions.\n */\n private _markSpanFinish(\n transaction: Transaction,\n spanEndTimestamp: number\n ): void {\n const previousStats = this._statsByTransaction.get(transaction);\n if (previousStats) {\n if (\n Math.abs(timestampInSeconds() - spanEndTimestamp) >\n MARGIN_OF_ERROR_SECONDS\n ) {\n logger.log(\n '[StallTracking] Span end not logged due to end timestamp being outside the margin of error from now.'\n );\n\n if (\n previousStats.atTimestamp &&\n previousStats.atTimestamp.timestamp < spanEndTimestamp\n ) {\n // We also need to delete the stat for the last span, as the transaction would be trimmed to this span not the last one.\n this._statsByTransaction.set(transaction, {\n ...previousStats,\n atTimestamp: null,\n });\n }\n } else {\n this._statsByTransaction.set(transaction, {\n ...previousStats,\n atTimestamp: {\n timestamp: spanEndTimestamp,\n stats: this._getCurrentStats(transaction),\n },\n });\n }\n }\n }\n\n /**\n * Get the current stats for a transaction at a given time.\n */\n private _getCurrentStats(transaction: Transaction): StallMeasurements {\n return {\n stall_count: { value: this._stallCount, unit: 'none' },\n stall_total_time: { value: this._totalStallTime, unit: 'millisecond' },\n stall_longest_time: {\n value: this._statsByTransaction.get(transaction)?.longestStallTime ?? 0, unit: 'millisecond'\n },\n };\n }\n\n /**\n * Start tracking stalls\n */\n private _startTracking(): void {\n if (!this.isTracking) {\n this.isTracking = true;\n this._lastIntervalMs = Math.floor(timestampInSeconds() * 1000);\n\n this._iteration();\n }\n }\n\n /**\n * Stops the stall tracking interval and calls reset().\n */\n private _stopTracking(): void {\n this.isTracking = false;\n\n if (this._timeout !== null) {\n clearTimeout(this._timeout);\n this._timeout = null;\n }\n\n this._reset();\n }\n\n /**\n * Will stop tracking if there are no more transactions.\n */\n private _shouldStopTracking(): void {\n if (this._statsByTransaction.size === 0) {\n this._stopTracking();\n }\n }\n\n /**\n * Clears all the collected stats\n */\n private _reset(): void {\n this._stallCount = 0;\n this._totalStallTime = 0;\n this._lastIntervalMs = 0;\n this._statsByTransaction.clear();\n }\n\n /**\n * Iteration of the stall tracking interval. Measures how long the timer strayed from its expected time of running, and how\n * long the stall is for.\n */\n private _iteration(): void {\n const now = timestampInSeconds() * 1000;\n const totalTimeTaken = now - this._lastIntervalMs;\n\n if (\n totalTimeTaken >=\n LOOP_TIMEOUT_INTERVAL_MS + this._minimumStallThreshold\n ) {\n const stallTime = totalTimeTaken - LOOP_TIMEOUT_INTERVAL_MS;\n this._stallCount += 1;\n this._totalStallTime += stallTime;\n\n for (const [transaction, value] of this._statsByTransaction.entries()) {\n const longestStallTime = Math.max(\n value.longestStallTime ?? 0,\n stallTime\n );\n\n this._statsByTransaction.set(transaction, {\n ...value,\n longestStallTime,\n });\n }\n }\n\n this._lastIntervalMs = now;\n\n if (this.isTracking) {\n this._timeout = setTimeout(\n this._iteration.bind(this),\n LOOP_TIMEOUT_INTERVAL_MS\n );\n }\n }\n\n /**\n * Deletes leaked transactions (Earliest transactions when we have more than MAX_RUNNING_TRANSACTIONS transactions.)\n */\n private _flushLeakedTransactions(): void {\n if (this._statsByTransaction.size > MAX_RUNNING_TRANSACTIONS) {\n let counter = 0;\n const len = this._statsByTransaction.size - MAX_RUNNING_TRANSACTIONS;\n const transactions = this._statsByTransaction.keys();\n for (const t of transactions) {\n if (counter >= len) break;\n counter += 1;\n this._statsByTransaction.delete(t);\n }\n }\n }\n}\n"]}
|
package/dist/js/version.d.ts
CHANGED
package/dist/js/version.js
CHANGED
package/dist/js/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '5.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/js/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,0BAA0B,CAAC;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC","sourcesContent":["export const SDK_PACKAGE_NAME = 'npm:@sentry/react-native';\nexport const SDK_NAME = 'sentry.javascript.react-native';\nexport const SDK_VERSION = '5.1.0';\n"]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@sentry/react-native",
|
|
3
3
|
"homepage": "https://github.com/getsentry/sentry-react-native",
|
|
4
4
|
"repository": "https://github.com/getsentry/sentry-react-native",
|
|
5
|
-
"version": "5.
|
|
5
|
+
"version": "5.1.0",
|
|
6
6
|
"description": "Official Sentry SDK for react-native",
|
|
7
7
|
"typings": "dist/js/index.d.ts",
|
|
8
8
|
"types": "dist/js/index.d.ts",
|
|
@@ -42,21 +42,21 @@
|
|
|
42
42
|
"react-native": ">=0.65.0"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@sentry/browser": "7.
|
|
46
|
-
"@sentry/cli": "2.
|
|
47
|
-
"@sentry/core": "7.
|
|
48
|
-
"@sentry/hub": "7.
|
|
49
|
-
"@sentry/integrations": "7.
|
|
50
|
-
"@sentry/react": "7.
|
|
51
|
-
"@sentry/tracing": "7.
|
|
52
|
-
"@sentry/types": "7.
|
|
53
|
-
"@sentry/utils": "7.
|
|
45
|
+
"@sentry/browser": "7.40.0",
|
|
46
|
+
"@sentry/cli": "2.14.3",
|
|
47
|
+
"@sentry/core": "7.40.0",
|
|
48
|
+
"@sentry/hub": "7.40.0",
|
|
49
|
+
"@sentry/integrations": "7.40.0",
|
|
50
|
+
"@sentry/react": "7.40.0",
|
|
51
|
+
"@sentry/tracing": "7.40.0",
|
|
52
|
+
"@sentry/types": "7.40.0",
|
|
53
|
+
"@sentry/utils": "7.40.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@sentry-internal/eslint-config-sdk": "7.
|
|
57
|
-
"@sentry-internal/eslint-plugin-sdk": "7.
|
|
56
|
+
"@sentry-internal/eslint-config-sdk": "7.40.0",
|
|
57
|
+
"@sentry-internal/eslint-plugin-sdk": "7.40.0",
|
|
58
58
|
"@sentry/typescript": "^5.20.1",
|
|
59
|
-
"@sentry/wizard": "2.
|
|
59
|
+
"@sentry/wizard": "2.6.0",
|
|
60
60
|
"@types/jest": "^29.2.5",
|
|
61
61
|
"@types/react": "^18.0.25",
|
|
62
62
|
"babel-jest": "^29.3.1",
|