about summary refs log tree commit diff
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-05-30 16:32:59 +0100
committerGitHub <noreply@github.com>2024-05-30 16:32:59 +0100
commitd6275e98c24ae12f070a689eb5602ac08b6abbb7 (patch)
treeadb0cd6699a2c859e804c370d3b10e191ee63450
parent94312010269d511e122d208d0db540267578ed5c (diff)
downloadvoidsky-d6275e98c24ae12f070a689eb5602ac08b6abbb7.tar.zst
[Statsig] Sample noisy events (#4288)
* Sample state:background and state:foreground

* Sample feed events

* Add DEV protection against forgetting to add events to the list
-rw-r--r--src/lib/statsig/events.ts10
-rw-r--r--src/lib/statsig/statsig.tsx20
-rw-r--r--src/view/com/feeds/FeedPage.tsx4
-rw-r--r--src/view/com/pager/Pager.tsx6
-rw-r--r--src/view/com/pager/Pager.web.tsx9
-rw-r--r--src/view/com/posts/Feed.tsx4
-rw-r--r--src/view/screens/Home.tsx9
7 files changed, 41 insertions, 21 deletions
diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts
index 68de52e14..42f4737f8 100644
--- a/src/lib/statsig/events.ts
+++ b/src/lib/statsig/events.ts
@@ -20,10 +20,10 @@ export type LogEvents = {
     context: 'StartOnboarding' | 'AfterOnboarding' | 'Login'
     status: 'granted' | 'denied' | 'undetermined'
   }
-  'state:background': {
+  'state:background:sampled': {
     secondsActive: number
   }
-  'state:foreground': {}
+  'state:foreground:sampled': {}
   'router:navigate:sampled': {}
 
   // Screen events
@@ -57,18 +57,18 @@ export type LogEvents = {
   'onboarding:finished:avatarResult': {
     avatarResult: 'default' | 'created' | 'uploaded'
   }
-  'home:feedDisplayed': {
+  'home:feedDisplayed:sampled': {
     feedUrl: string
     feedType: string
     index: number
     reason: 'focus' | 'tabbar-click' | 'pager-swipe' | 'desktop-sidebar-click'
   }
-  'feed:endReached': {
+  'feed:endReached:sampled': {
     feedUrl: string
     feedType: string
     itemCount: number
   }
-  'feed:refresh': {
+  'feed:refresh:sampled': {
     feedUrl: string
     feedType: string
     reason: 'pull-to-refresh' | 'soft-reset' | 'load-latest'
diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx
index 6ffca0ab4..573a123e1 100644
--- a/src/lib/statsig/statsig.tsx
+++ b/src/lib/statsig/statsig.tsx
@@ -87,7 +87,14 @@ export function toClout(n: number | null | undefined): number | undefined {
   }
 }
 
-const DOWNSAMPLED_EVENTS = new Set(['router:navigate:sampled'])
+const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
+  'router:navigate:sampled',
+  'state:background:sampled',
+  'state:foreground:sampled',
+  'home:feedDisplayed:sampled',
+  'feed:endReached:sampled',
+  'feed:refresh:sampled',
+])
 const isDownsampledSession = Math.random() < 0.9 // 90% likely
 
 export function logEvent<E extends keyof LogEvents>(
@@ -98,6 +105,13 @@ export function logEvent<E extends keyof LogEvents>(
     if (isDownsampledSession && DOWNSAMPLED_EVENTS.has(eventName)) {
       return
     }
+    if (process.env.NODE_ENV === 'development') {
+      if (eventName.endsWith(':sampled')) {
+        logger.error(
+          'Did you forget to add ' + eventName + ' to DOWNSAMPLED_EVENTS?',
+        )
+      }
+    }
     const fullMetadata = {
       ...rawMetadata,
     } as Record<string, string> // Statsig typings are unnecessarily strict here.
@@ -199,14 +213,14 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
   lastState = state
   if (state === 'active') {
     lastActive = performance.now()
-    logEvent('state:foreground', {})
+    logEvent('state:foreground:sampled', {})
   } else {
     let secondsActive = 0
     if (lastActive != null) {
       secondsActive = Math.round((performance.now() - lastActive) / 1e3)
     }
     lastActive = null
-    logEvent('state:background', {
+    logEvent('state:background:sampled', {
       secondsActive,
     })
   }
diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx
index c80740b76..f1d03a7ca 100644
--- a/src/view/com/feeds/FeedPage.tsx
+++ b/src/view/com/feeds/FeedPage.tsx
@@ -76,7 +76,7 @@ export function FeedPage({
       scrollToTop()
       truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
       setHasNew(false)
-      logEvent('feed:refresh', {
+      logEvent('feed:refresh:sampled', {
         feedType: feed.split('|')[0],
         feedUrl: feed,
         reason: 'soft-reset',
@@ -102,7 +102,7 @@ export function FeedPage({
     scrollToTop()
     truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
     setHasNew(false)
-    logEvent('feed:refresh', {
+    logEvent('feed:refresh:sampled', {
       feedType: feed.split('|')[0],
       feedUrl: feed,
       reason: 'load-latest',
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index 26070fb88..ea88f7390 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -15,7 +15,7 @@ const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
 export interface PagerRef {
   setPage: (
     index: number,
-    reason: LogEvents['home:feedDisplayed']['reason'],
+    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
   ) => void
 }
 
@@ -32,7 +32,7 @@ interface Props {
   onPageSelected?: (index: number) => void
   onPageSelecting?: (
     index: number,
-    reason: LogEvents['home:feedDisplayed']['reason'],
+    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
   ) => void
   onPageScrollStateChanged?: (
     scrollState: 'idle' | 'dragging' | 'settling',
@@ -61,7 +61,7 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
     React.useImperativeHandle(ref, () => ({
       setPage: (
         index: number,
-        reason: LogEvents['home:feedDisplayed']['reason'],
+        reason: LogEvents['home:feedDisplayed:sampled']['reason'],
       ) => {
         pagerView.current?.setPage(index)
         onPageSelecting?.(index, reason)
diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx
index abba12b2c..1266a1620 100644
--- a/src/view/com/pager/Pager.web.tsx
+++ b/src/view/com/pager/Pager.web.tsx
@@ -18,7 +18,7 @@ interface Props {
   onPageSelected?: (index: number) => void
   onPageSelecting?: (
     index: number,
-    reason: LogEvents['home:feedDisplayed']['reason'],
+    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
   ) => void
 }
 export const Pager = React.forwardRef(function PagerImpl(
@@ -38,14 +38,17 @@ export const Pager = React.forwardRef(function PagerImpl(
   React.useImperativeHandle(ref, () => ({
     setPage: (
       index: number,
-      reason: LogEvents['home:feedDisplayed']['reason'],
+      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
     ) => {
       onTabBarSelect(index, reason)
     },
   }))
 
   const onTabBarSelect = React.useCallback(
-    (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
+    (
+      index: number,
+      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+    ) => {
       const scrollY = window.scrollY
       // We want to determine if the tabbar is already "sticking" at the top (in which
       // case we should preserve and restore scroll), or if it is somewhere below in the
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index e45abfedc..12171dc3b 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -226,7 +226,7 @@ let Feed = ({
 
   const onRefresh = React.useCallback(async () => {
     track('Feed:onRefresh')
-    logEvent('feed:refresh', {
+    logEvent('feed:refresh:sampled', {
       feedType: feedType,
       feedUrl: feed,
       reason: 'pull-to-refresh',
@@ -244,7 +244,7 @@ let Feed = ({
   const onEndReached = React.useCallback(async () => {
     if (isFetching || !hasNextPage || isError) return
 
-    logEvent('feed:endReached', {
+    logEvent('feed:endReached:sampled', {
       feedType: feedType,
       feedUrl: feed,
       itemCount: feedItems.length,
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 829cd94e4..34d3abf26 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -99,7 +99,7 @@ function HomeScreenReady({
   useFocusEffect(
     useNonReactiveCallback(() => {
       if (selectedFeed) {
-        logEvent('home:feedDisplayed', {
+        logEvent('home:feedDisplayed:sampled', {
           index: selectedIndex,
           feedType: selectedFeed.split('|')[0],
           feedUrl: selectedFeed,
@@ -140,9 +140,12 @@ function HomeScreenReady({
   )
 
   const onPageSelecting = React.useCallback(
-    (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
+    (
+      index: number,
+      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+    ) => {
       const feed = allFeeds[index]
-      logEvent('home:feedDisplayed', {
+      logEvent('home:feedDisplayed:sampled', {
         index,
         feedType: feed.split('|')[0],
         feedUrl: feed,