Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d13dccd
build(android): Bump sentry-android to 5.1.0-beta.6
jennmueng Jul 26, 2021
a5363ac
wip: App start time as an idleTransaction started from ReactNativeTra…
jennmueng Jul 26, 2021
a4dc170
wip: Use cocoa sdk via commit hash
jennmueng Jul 27, 2021
3113cf1
wip with cocoa
jennmueng Jul 27, 2021
3b23593
native wrapper move around
jennmueng Jul 28, 2021
5892843
bump android
jennmueng Jul 28, 2021
6b2196b
reduced app start
jennmueng Jul 28, 2021
c6c143d
ref: Revert RNSentry back
jennmueng Jul 28, 2021
653ccc4
add app start to route transactions
jennmueng Jul 28, 2021
781f9b8
slow/frozen frames on android?
jennmueng Jul 29, 2021
4c17b02
feat: App start on ios
jennmueng Jul 29, 2021
0f1d531
refactoring
jennmueng Jul 30, 2021
b95758a
ref: Remove frames
jennmueng Jul 30, 2021
ffa3eb9
comments
jennmueng Jul 30, 2021
438bfbe
feat: Enable auto performance tracking by default
jennmueng Jul 30, 2021
4481c77
add tests and comments
jennmueng Aug 2, 2021
f11faab
test: Tests for enableAutoPerformanceTracking & enableStallTrackking
jennmueng Aug 2, 2021
6dab64f
Bump to android beta 9
jennmueng Aug 2, 2021
7b0b9c2
ref: cleanup
jennmueng Aug 3, 2021
38622b9
build(ios): Bump cocoa sdk to latest
jennmueng Aug 3, 2021
60ef20e
quotes
jennmueng Aug 3, 2021
9382e01
ref: Java clean
jennmueng Aug 3, 2021
89522f9
changelog
jennmueng Aug 3, 2021
2c0b579
ref: Remove unused import
jennmueng Aug 3, 2021
f2dcbac
fix: Handle null app start case + disabled native & add tests
jennmueng Aug 3, 2021
bee2012
include private sdk only
jennmueng Aug 4, 2021
9cff38b
build(ios): Bump to 7.2.0-beta.9
jennmueng Aug 5, 2021
e4713f4
fix didFetchAppStart on android
jennmueng Aug 5, 2021
f20aad3
use static variable for didFetchAppStart too
jennmueng Aug 5, 2021
4b0d7a8
Merge branch 'master' into jenn/app-start-actual
jennmueng Aug 6, 2021
7056d75
ref: Don't need to import PrivateSentrySDKOnly
jennmueng Aug 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

- build(ios): Bump sentry-cocoa to 7.2.0-beta.9 #1704
- build(android): Bump sentry-android to 5.1.0-beta.9 #1704
- feat: Add app start measurements to the first transaction #1704
- feat: Create an initial initial ui.load transaction by default #1704
- feat: Add `enableAutoPerformanceTracking` flag that enables auto performance when tracing is enabled #1704

## 2.7.0-beta.1

- feat: Track stalls in the JavaScript event loop as measurements #1542
Expand Down
2 changes: 1 addition & 1 deletion RNSentry.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Pod::Spec.new do |s|
s.preserve_paths = '*.js'

s.dependency 'React-Core'
s.dependency 'Sentry', '7.1.4'
s.dependency 'Sentry', '7.2.0-beta.9'

s.source_files = 'ios/RNSentry.{h,m}'
s.public_header_files = 'ios/RNSentry.h'
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ android {

dependencies {
implementation 'com.facebook.react:react-native:+'
api 'io.sentry:sentry-android:5.1.0-beta.2'
api 'io.sentry:sentry-android:5.1.0-beta.9'
}
30 changes: 28 additions & 2 deletions android/src/main/java/io/sentry/react/RNSentryModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -27,12 +27,14 @@
import java.util.logging.Logger;

import io.sentry.android.core.AnrIntegration;
import io.sentry.android.core.AppStartState;
import io.sentry.android.core.NdkIntegration;
import io.sentry.android.core.SentryAndroid;
import io.sentry.Sentry;
import io.sentry.Breadcrumb;
import io.sentry.DateUtils;
import io.sentry.HubAdapter;
import io.sentry.Integration;
import io.sentry.Sentry;
import io.sentry.SentryLevel;
import io.sentry.UncaughtExceptionHandlerIntegration;
import io.sentry.protocol.SdkVersion;
Expand All @@ -47,6 +49,7 @@ public class RNSentryModule extends ReactContextBaseJavaModule {
final static Logger logger = Logger.getLogger("react-native-sentry");

private static PackageInfo packageInfo;
private static boolean didFetchAppStart = false;

public RNSentryModule(ReactApplicationContext reactContext) {
super(reactContext);
Expand Down Expand Up @@ -180,6 +183,29 @@ public void fetchNativeRelease(Promise promise) {
promise.resolve(release);
}

@ReactMethod
public void fetchNativeAppStart(Promise promise) {
final AppStartState appStartInstance = AppStartState.getInstance();
final Date appStartTime = appStartInstance.getAppStartTime();

if (appStartTime == null) {
promise.resolve(null);
} else {
final double appStartTimestamp = (double) appStartTime.getTime();

WritableMap appStart = Arguments.createMap();

appStart.putDouble("appStartTime", appStartTimestamp);
appStart.putBoolean("isColdStart", appStartInstance.isColdStart());
appStart.putBoolean("didFetchAppStart", RNSentryModule.didFetchAppStart);

promise.resolve(appStart);
}
// This is always set to true, as we would only allow an app start fetch to only happen once
// in the case of a JS bundle reload, we do not want it to be instrumented again.
RNSentryModule.didFetchAppStart = true;
}

@ReactMethod
public void captureEnvelope(String envelope, Promise promise) {
try {
Expand Down
31 changes: 31 additions & 0 deletions ios/RNSentry.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ + (void)storeEnvelope:(SentryEnvelope *)envelope;

@end

static bool didFetchAppStart;

@implementation RNSentry {
bool sentHybridSdkDidBecomeActive;
}
Expand All @@ -40,6 +42,8 @@ + (BOOL)requiresMainQueueSetup {
resolve:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
PrivateSentrySDKOnly.appStartMeasurementHybridSDKMode = true;

NSError *error = nil;

SentryBeforeSendEventCallback beforeSend = ^SentryEvent*(SentryEvent *event) {
Expand Down Expand Up @@ -80,6 +84,9 @@ + (BOOL)requiresMainQueueSetup {
sentHybridSdkDidBecomeActive = true;
}




resolve(@YES);
}

Expand All @@ -102,6 +109,30 @@ + (BOOL)requiresMainQueueSetup {
}];
}

RCT_EXPORT_METHOD(fetchNativeAppStart:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{

SentryAppStartMeasurement *appStartMeasurement = PrivateSentrySDKOnly.appStartMeasurement;

if (appStartMeasurement == nil) {
resolve(nil);
} else {
BOOL isColdStart = appStartMeasurement.type == SentryAppStartTypeCold;

resolve(@{
@"isColdStart": [NSNumber numberWithBool:isColdStart],
@"appStartTime": [NSNumber numberWithDouble:(appStartMeasurement.appStartTimestamp.timeIntervalSince1970 * 1000)],
@"didFetchAppStart": [NSNumber numberWithBool:didFetchAppStart],
});

}

// This is always set to true, as we would only allow an app start fetch to only happen once
// in the case of a JS bundle reload, we do not want it to be instrumented again.
didFetchAppStart = true;
}

RCT_EXPORT_METHOD(fetchNativeRelease:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
Expand Down
52 changes: 30 additions & 22 deletions sample/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Sentry.init({
maxBreadcrumbs: 150, // Extend from the default 100 breadcrumbs.
integrations: [
new Sentry.ReactNativeTracing({
idleTimeout: 5000,
idleTimeout: 5000, // This is the default timeout
routingInstrumentation: reactNavigationV5Instrumentation,
tracingOrigins: ['localhost', /^\//, /^https:\/\//],
beforeNavigate: (context: Sentry.ReactNavigationTransactionContext) => {
Expand Down Expand Up @@ -71,27 +71,35 @@ const App = () => {
const navigation = React.useRef<NavigationContainerRef>();

return (
<Provider store={store}>
<NavigationContainer
ref={navigation}
onReady={() => {
reactNavigationV5Instrumentation.registerNavigationContainer(
navigation,
);
}}>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Tracker" component={TrackerScreen} />
<Stack.Screen name="ManualTracker" component={ManualTrackerScreen} />
<Stack.Screen
name="PerformanceTiming"
component={PerformanceTimingScreen}
/>
<Stack.Screen name="Redux" component={ReduxScreen} />
<Stack.Screen name="EndToEndTests" component={EndToEndTestsScreen} />
</Stack.Navigator>
</NavigationContainer>
</Provider>
<Sentry.Profiler name="App">
<Provider store={store}>
<NavigationContainer
ref={navigation}
onReady={() => {
reactNavigationV5Instrumentation.registerNavigationContainer(
navigation,
);
}}>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Tracker" component={TrackerScreen} />
<Stack.Screen
name="ManualTracker"
component={ManualTrackerScreen}
/>
<Stack.Screen
name="PerformanceTiming"
component={PerformanceTimingScreen}
/>
<Stack.Screen name="Redux" component={ReduxScreen} />
<Stack.Screen
name="EndToEndTests"
component={EndToEndTestsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
</Sentry.Profiler>
);
};

Expand Down
9 changes: 9 additions & 0 deletions src/js/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { Breadcrumb } from "@sentry/types";

import { ReactNativeOptions } from "./options";

export type NativeAppStartResponse = {
isColdStart: boolean;
appStartTime: number;
didFetchAppStart: boolean;
};

export type NativeReleaseResponse = {
build: string;
id: string;
Expand All @@ -17,6 +23,8 @@ interface SerializedObject {
}

export interface SentryNativeBridgeModule {
nativeClientAvailable: boolean;

addBreadcrumb(breadcrumb: Breadcrumb): void;
captureEnvelope(
payload:
Expand All @@ -35,6 +43,7 @@ export interface SentryNativeBridgeModule {
version: string;
}>;
fetchNativeDeviceContexts(): PromiseLike<NativeDeviceContextsResponse>;
fetchNativeAppStart(): PromiseLike<NativeAppStartResponse | null>;
getStringBytesLength(str: string): Promise<number>;
initNativeSdk(options: ReactNativeOptions): Promise<boolean>;
setUser(
Expand Down
3 changes: 3 additions & 0 deletions src/js/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@ export interface ReactNativeOptions extends BrowserOptions {

/** Enable JS event loop stall tracking. Enabled by default. */
enableStallTracking?: boolean;

/** Enable auto performance tracking by default. */
enableAutoPerformanceTracking?: boolean;
}
12 changes: 10 additions & 2 deletions src/js/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from "./integrations";
import { ReactNativeOptions } from "./options";
import { ReactNativeScope } from "./scope";
import { ReactNativeTracing } from "./tracing";

const IGNORED_DEFAULT_INTEGRATIONS = [
"GlobalHandlers", // We will use the react-native internal handlers
Expand All @@ -26,6 +27,7 @@ const DEFAULT_OPTIONS: ReactNativeOptions = {
enableNativeNagger: true,
autoInitializeNativeSdk: true,
enableStallTracking: true,
enableAutoPerformanceTracking: true,
};

/**
Expand Down Expand Up @@ -84,8 +86,14 @@ export function init(passedOptions: ReactNativeOptions): void {
if (options.enableNative) {
options.defaultIntegrations.push(new DeviceContext());
}
if (tracingEnabled && options.enableStallTracking) {
options.defaultIntegrations.push(new StallTracking());
if (tracingEnabled) {
if (options.enableAutoPerformanceTracking) {
options.defaultIntegrations.push(new ReactNativeTracing());

if (options.enableStallTracking) {
options.defaultIntegrations.push(new StallTracking());
}
}
}
}

Expand Down
Loading