Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
870e47a
wip: Fetch/XHR + React Navigation Instrumentation
jennmueng Dec 6, 2020
a71b8d3
ref: Add navigationActionTypes and add comments/format
jennmueng Dec 8, 2020
0054c64
ref: Comments and formatting for RoutingInstrumentation
jennmueng Dec 8, 2020
6cd93d3
ref: Move tracing utils to separate file and log if no routing inst
jennmueng Dec 8, 2020
aa8ffb0
ref: Rename to ReactNavigationV5Instrumentation
jennmueng Dec 8, 2020
55abdfc
fix: Overhaul v5 instrumentation to handle edge cases
jennmueng Dec 20, 2020
baebf11
ref: Rename _cancelLastTransaction to _discardLatestTransaction
jennmueng Dec 20, 2020
e7e8f97
test: Have a navigation reset action to test
jennmueng Dec 22, 2020
e575345
test: Profile the statistics on the tracker screen
jennmueng Dec 22, 2020
e26e278
feat: Use fetch transport for transactions on android (hack)
jennmueng Dec 24, 2020
a8ea84e
feat: Add React Navigation V4 instrumentation
jennmueng Dec 29, 2020
1f69bc7
fix: Fix ReactNavigationV4Instrumentation by patching the router
jennmueng Dec 30, 2020
11e99ed
ref: Remove TODO comment
jennmueng Jan 2, 2021
1c4db13
feat: Add beforeNavigate to ReactNativeTracing
jennmueng Jan 2, 2021
5fb6218
feat: Log when instrumentation does not send transaction due
jennmueng Jan 2, 2021
c8ad0da
test: shouldAttachTransaction example in sample
jennmueng Jan 2, 2021
3feafc6
ref: Navigation transaction name is just the routeName
jennmueng Jan 2, 2021
e59d158
ref: Use shouldSendTransaction for both instrumentations
jennmueng Jan 2, 2021
883db59
feat: Set sampled = false on V4 instead of dropping
jennmueng Jan 3, 2021
38df430
ref: File rename and export structure change
jennmueng Jan 10, 2021
2c33c86
fix: Fix failing native transport test
jennmueng Jan 10, 2021
dc73747
ref: Change sampling location + add routeName as a tag
jennmueng Jan 10, 2021
0eb60a8
ref: Add V5 suffixes to ReactNavigationV5 instrumentation
jennmueng Jan 10, 2021
f9fe200
test: Add tests for ReactNavigationV5Instrumentation
jennmueng Jan 10, 2021
57b6ef1
fix: Undo bad sampling decision
jennmueng Jan 11, 2021
65095f0
test: Add React Navigation V4 tests
jennmueng Jan 11, 2021
c4a8f86
ref: Cleanup
jennmueng Jan 11, 2021
07f2846
test: Add shouldSendTransaction test for v5
jennmueng Jan 11, 2021
478d946
build(android): Bump sentry-android to 4.0.0-alpha.3
jennmueng Jan 17, 2021
d483321
fix: Remove native transport transaction hack on android
jennmueng Jan 17, 2021
afa0a27
feat: Ignore routes that have been seen before without child spans
jennmueng Jan 18, 2021
386e82e
tests: Fix tests to include hasBeenSeen
jennmueng Jan 18, 2021
17b13da
meta: Changelog
jennmueng Jan 18, 2021
f396f6f
ref: Remove homescreen manual transaction test
jennmueng Jan 18, 2021
b0adc26
fix: Update covid 19 api endpoint
jennmueng Jan 19, 2021
e0f6b25
ref: Sample cleanup
jennmueng Jan 19, 2021
c73c7d9
feat: Add redux example
jennmueng Jan 19, 2021
a45ff82
fix: Update endpoint on manual tracing example
jennmueng Jan 19, 2021
c2a9daf
ref: Use navigation op on manual tracing screen
jennmueng Jan 19, 2021
aa0786c
ref: Cleanup from PR review
jennmueng Jan 19, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- fix: Only set "event" type in envelope item and not the payload #1271
- build: Bump JS dependencies to 5.30.0 #1282
- fix: Add fallback envelope item type to iOS. #1283
- feat: Auto performance tracing with XHR/fetch, and routing instrumentation #1230

## 2.1.0

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:3.2.0'
api 'io.sentry:sentry-android:4.0.0-alpha.3'
}
46 changes: 39 additions & 7 deletions sample/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import * as React from 'react';
import { Provider } from 'react-redux';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import {Provider} from 'react-redux';
import {
NavigationContainer,
NavigationContainerRef,
} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';

// Import the Sentry React Native SDK
import * as Sentry from '@sentry/react-native';

import HomeScreen from './screens/HomeScreen';
import TrackerScreen from './screens/TrackerScreen';
import ManualTrackerScreen from './screens/ManualTrackerScreen';
import PerformanceTimingScreen from './screens/PerformanceTimingScreen';
import EndToEndTestsScreen from './screens/EndToEndTestsScreen';
import ReduxScreen from './screens/ReduxScreen';

import { store } from './reduxApp';
import { version as packageVersion } from '../../package.json';
import { SENTRY_INTERNAL_DSN } from './dsn';
import {store} from './reduxApp';
import {version as packageVersion} from '../../package.json';
import {SENTRY_INTERNAL_DSN} from './dsn';

const reactNavigationV5Instrumentation = new Sentry.ReactNavigationV5Instrumentation(
{
shouldSendTransaction: (route, previousRoute) => {
if (route.name === 'ManualTracker') {
return false;
}

return true;
},
},
);

Sentry.init({
// Replace the example DSN below with your own DSN:
Expand All @@ -24,6 +41,13 @@ Sentry.init({
return e;
},
maxBreadcrumbs: 150, // Extend from the default 100 breadcrumbs.
integrations: [
new Sentry.ReactNativeTracing({
idleTimeout: 5000,
routingInstrumentation: reactNavigationV5Instrumentation,
tracingOrigins: ['localhost', /^\//, /^https:\/\//],
}),
],
enableAutoSessionTracking: true,
// For testing, session close when 5 seconds (instead of the default 30) in the background.
sessionTrackingIntervalMillis: 5000,
Expand All @@ -38,16 +62,24 @@ Sentry.init({
const Stack = createStackNavigator();

const App = () => {
const navigation = React.createRef<NavigationContainerRef>();

React.useEffect(() => {
reactNavigationV5Instrumentation.registerNavigationContainer(navigation);
}, []);

return (
<Provider store={store}>
<NavigationContainer>
<NavigationContainer ref={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>
Expand Down
2 changes: 1 addition & 1 deletion sample/src/components/Counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const Counter = () => {
const dispatch = useDispatch();

return (
<View className="counter">
<View>
<Text>Count:</Text>
<Text>{counter}</Text>
<TouchableOpacity
Expand Down
4 changes: 4 additions & 0 deletions sample/src/reduxApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const reducer = (state = initialState, action) => {
}
};

/*
Example of how to use the Sentry redux enhancer packaged with @sentry/react:
*/

const sentryEnhancer = Sentry.createReduxEnhancer();

const store = createStore(reducer, sentryEnhancer);
Expand Down
9 changes: 6 additions & 3 deletions sample/src/screens/EndToEndTestsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// This screen is used solely for E2E tests and are not visible through the UI (no button to load it).
import React, { useEffect } from 'react';
import {ScrollView, Text, Platform} from 'react-native';
import React from 'react';
import {ScrollView, Text} from 'react-native';

import * as Sentry from '@sentry/react-native';

import {getTestProps} from '../../utils/getTestProps';
import {SENTRY_INTERNAL_DSN} from '../dsn';

/**
* This screen is for internal end-to-end testing purposes only. Do not use.
* Not visible through the UI (no button to load it).
*/
const EndToEndTestsScreen = () => {
const [eventId, setEventId] = React.useState(null);

Expand Down
43 changes: 33 additions & 10 deletions sample/src/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/

import React from 'react';
import {
Image,
Expand All @@ -17,6 +9,11 @@ import {
View,
} from 'react-native';
import {StackNavigationProp} from '@react-navigation/stack';
import {
CommonActions,
useNavigation,
useNavigationState,
} from '@react-navigation/native';

import * as Sentry from '@sentry/react-native';

Expand Down Expand Up @@ -207,15 +204,41 @@ const HomeScreen = (props: Props) => {
onPress={() => {
props.navigation.navigate('Tracker');
}}>
<Text style={styles.buttonText}>Tracing Example</Text>
<Text style={styles.buttonText}>Auto Tracing Example</Text>
</TouchableOpacity>
<View style={styles.spacer} />
<TouchableOpacity
onPress={() => {
props.navigation.navigate('ManualTracker');
}}>
<Text style={styles.buttonText}>Manual Tracing Example</Text>
</TouchableOpacity>
<View style={styles.spacer} />
<TouchableOpacity
onPress={() => {
props.navigation.navigate('PerformanceTiming');
// Navigate with a reset action just to test
props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{name: 'Home'},
{
name: 'PerformanceTiming',
params: {someParam: 'hello'},
},
],
}),
);
}}>
<Text style={styles.buttonText}>Performance Timing</Text>
</TouchableOpacity>
<View style={styles.spacer} />
<TouchableOpacity
onPress={() => {
props.navigation.navigate('Redux');
}}>
<Text style={styles.buttonText}>Redux Example</Text>
</TouchableOpacity>
</View>
</View>
</ScrollView>
Expand Down
156 changes: 156 additions & 0 deletions sample/src/screens/ManualTrackerScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import * as React from 'react';
import {Button, View, StyleSheet, Text, ActivityIndicator} from 'react-native';

import * as Sentry from '@sentry/react-native';

/**
* An example of how to add a Sentry Transaction to a React component manually.
* So you can control all spans that belong to that one transaction.
*
* This screen calls an API to get the latest COVID-19 Data to display. We attach a span
* to the fetch call and track the time it takes for Promise to resolve.
*/
const TrackerScreen = () => {
const [cases, setCases] = React.useState<{
TotalConfirmed: number;
TotalDeaths: number;
TotalRecovered: number;
} | null>(null);

const transaction = React.useRef(null);

React.useEffect(() => {
// Initialize the transaction for the screen.
transaction.current = Sentry.startTransaction({
name: 'Tracker Screen',
op: 'navigation',
});

return () => {
// Finishing the transaction triggers sending the data to Sentry.
transaction.current?.finish();
transaction.current = null;
Sentry.configureScope((scope) => {
scope.setSpan(undefined);
});
};
}, []);

const loadData = () => {
setCases(null);

// Create a child span for the API call.
const span = transaction.current?.startChild({
op: 'http',
description: 'Fetch Covid19 data from API',
});

fetch('https://api.covid19api.com/summary', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((json) => {
setCases(json.Global);

span?.setData('json', json);
span?.finish();
});
};

React.useEffect(() => {
loadData();
}, []);

return (
<View style={styles.screen}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Global COVID19 Cases</Text>
</View>
<View style={styles.card}>
{cases ? (
<>
<Statistic
title="Confirmed"
count={cases.TotalConfirmed}
textColor="#C83852"
/>
<Statistic
title="Deaths"
count={cases.TotalDeaths}
textColor="#362D59"
/>
<Statistic
title="Recovered"
count={cases.TotalRecovered}
textColor="#69C289"
/>
</>
) : (
<ActivityIndicator size="small" color="#F6F6F8" />
)}
</View>
<Button title="Refresh" onPress={loadData} />
</View>
);
};

export default Sentry.withProfiler(TrackerScreen);

const Statistic = (props: {
title: string;
count: number;
textColor: string;
}): React.ReactElement => {
return (
<View style={styles.statisticContainer}>
<Text>{props.title}</Text>
<Text style={[styles.statisticCount, {color: props.textColor}]}>
{`${props.count}`.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')}
</Text>
</View>
);
};

const styles = StyleSheet.create({
screen: {
flex: 1,
padding: 16,
},
titleContainer: {
paddingBottom: 12,
},
title: {
fontSize: 24,
fontWeight: '700',
},
card: {
width: '100%',
height: 240,
padding: 12,
borderWidth: 1,
borderColor: '#79628C',
borderRadius: 6,
backgroundColor: '#F6F6F8',
alignItems: 'center',
justifyContent: 'center',
},
statisticContainer: {
width: '100%',
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
statisticTitle: {
fontSize: 16,
fontWeight: '500',
},
statisticCount: {
fontSize: 16,
fontWeight: '700',
},
});
20 changes: 20 additions & 0 deletions sample/src/screens/ReduxScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from 'react';
import {View, StyleSheet} from 'react-native';

import Counter from '../components/Counter';

const ReduxScreen = () => {
return (
<View style={styles.container}>
<Counter />
</View>
);
};

export default ReduxScreen;

const styles = StyleSheet.create({
container: {
padding: 20,
},
});
Loading