Skip to content

Commit e69e91e

Browse files
feat(sdk): Add JS Core metrics (#3590)
1 parent 82eeed0 commit e69e91e

File tree

6 files changed

+75
-1
lines changed

6 files changed

+75
-1
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ This release contains upgrade of `sentry-android` dependency to major version 7.
77
### Features
88

99
- Add Android profiles to React Native Profiling ([#3397](https://github.com/getsentry/sentry-react-native/pull/3397))
10+
- Add `Sentry.metrics` ([#3590](https://github.com/getsentry/sentry-react-native/pull/3590))
11+
12+
To learn more, see the [Set Up Metrics](https://docs.sentry.io/platforms/react-native/metrics/) guide.
13+
14+
```javascript
15+
import * as Sentry from '@sentry/react-native';
16+
17+
Sentry.init({
18+
dsn: '___DSN___',
19+
integrations: [
20+
Sentry.metrics.metricsAggregatorIntegration(),
21+
],
22+
});
23+
24+
Sentry.metrics.increment("button_click", 1, {
25+
tags: { system: "iOS", app_version: "1.0.0" },
26+
});
27+
```
1028

1129
### Fixes
1230

samples/expo/app/(tabs)/index.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { Text, View } from '@/components/Themed';
66
import { SENTRY_INTERNAL_DSN } from '@/utils/dsn';
77
import { HttpClient } from '@sentry/integrations';
88
import { setScopeProperties } from '@/utils/setScopeProperties';
9+
import { timestampInSeconds } from '@sentry/utils';
10+
import React from 'react';
911

1012
const isRunningInExpoGo = Constants.appOwnership === 'expo'
1113

@@ -38,6 +40,7 @@ Sentry.init({
3840
// default: [/.*/]
3941
failedRequestTargets: [/.*/],
4042
}),
43+
Sentry.metrics.metricsAggregatorIntegration(),
4144
);
4245
return integrations.filter(i => i.name !== 'Dedupe');
4346
},
@@ -66,6 +69,25 @@ Sentry.init({
6669
});
6770

6871
export default function TabOneScreen() {
72+
const [componentMountStartTimestamp] = React.useState<number>(() => {
73+
return timestampInSeconds();
74+
});
75+
76+
React.useEffect(() => {
77+
if (componentMountStartTimestamp) {
78+
// Distributions help you get the most insights from your data by allowing you to obtain aggregations such as p90, min, max, and avg.
79+
Sentry.metrics.distribution(
80+
'tab_one_mount_time',
81+
timestampInSeconds() - componentMountStartTimestamp,
82+
{
83+
unit: "seconds",
84+
},
85+
);
86+
}
87+
// We only want this to run once.
88+
// eslint-disable-next-line react-hooks/exhaustive-deps
89+
}, []);
90+
6991
return (
7092
<View style={styles.container}>
7193
<Text>Welcome to Sentry Expo Sample App!</Text>
@@ -78,6 +100,7 @@ export default function TabOneScreen() {
78100
<Button
79101
title="Capture exception"
80102
onPress={() => {
103+
Sentry.metrics.increment('tab_one.capture_exception_button_press', 1);
81104
Sentry.captureException(new Error('Captured exception'));
82105
}}
83106
/>

samples/react-native/src/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Sentry.init({
6969
// default: [/.*/]
7070
failedRequestTargets: [/.*/],
7171
}),
72+
Sentry.metrics.metricsAggregatorIntegration(),
7273
);
7374
return integrations.filter(i => i.name !== 'Dedupe');
7475
},

samples/react-native/src/Screens/HomeScreen.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { CommonActions } from '@react-navigation/native';
1919
import { UserFeedbackModal } from '../components/UserFeedbackModal';
2020
import { FallbackRender } from '@sentry/react';
2121
import NativeSampleModule from '../../tm/NativeSampleModule';
22+
import { timestampInSeconds } from '@sentry/utils';
2223

2324
const { AssetsModule, CppModule, CrashModule } = NativeModules;
2425

@@ -27,6 +28,25 @@ interface Props {
2728
}
2829

2930
const HomeScreen = (props: Props) => {
31+
const [componentMountStartTimestamp] = React.useState<number>(() => {
32+
return timestampInSeconds();
33+
});
34+
35+
React.useEffect(() => {
36+
if (componentMountStartTimestamp) {
37+
// Distributions help you get the most insights from your data by allowing you to obtain aggregations such as p90, min, max, and avg.
38+
Sentry.metrics.distribution(
39+
'home_mount_time',
40+
timestampInSeconds() - componentMountStartTimestamp,
41+
{
42+
unit: 'seconds',
43+
},
44+
);
45+
}
46+
// We only want this to run once.
47+
// eslint-disable-next-line react-hooks/exhaustive-deps
48+
}, []);
49+
3050
// Show bad code inside error boundary to trigger it.
3151
const [showBadCode, setShowBadCode] = React.useState(false);
3252
const [isFeedbackVisible, setFeedbackVisible] = React.useState(false);

samples/react-native/src/Screens/TrackerScreen.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ const TrackerScreen = () => {
3939
});
4040
};
4141

42+
const onRefreshButtonPress = () => {
43+
Sentry.metrics.increment('tracker_screen.refresh_button_press', 1, {
44+
tags: { graph: 'none', public_data: true },
45+
});
46+
loadData();
47+
};
48+
4249
React.useEffect(() => {
4350
loadData();
4451
}, []);
@@ -71,7 +78,11 @@ const TrackerScreen = () => {
7178
<ActivityIndicator size="small" color="#F6F6F8" />
7279
)}
7380
</View>
74-
<Button sentry-label="refresh" title="Refresh" onPress={loadData} />
81+
<Button
82+
sentry-label="refresh"
83+
title="Refresh"
84+
onPress={onRefreshButtonPress}
85+
/>
7586
</View>
7687
);
7788
};

src/js/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export {
4545
getClient,
4646
setCurrentClient,
4747
addEventProcessor,
48+
metrics,
4849
} from '@sentry/core';
4950

5051
import { _addTracingExtensions } from './tracing/addTracingExtensions';

0 commit comments

Comments
 (0)