[Statsig] Add more events to downsample, increase downsample rate (#5198)
* add some events for sampling * include downsample rate in metadata * fix metadata logic * uncomment debug
This commit is contained in:
parent
adef9cff10
commit
c8be9b78c6
7 changed files with 47 additions and 37 deletions
|
|
@ -661,16 +661,15 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
|
||||||
linking={LINKING}
|
linking={LINKING}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
onStateChange={() => {
|
onStateChange={() => {
|
||||||
logEvent('router:navigate:sampled', {
|
const routeName = getCurrentRouteName()
|
||||||
from: prevLoggedRouteName.current,
|
if (routeName === 'Notifications') {
|
||||||
})
|
logEvent('router:navigate:notifications:sampled', {})
|
||||||
prevLoggedRouteName.current = getCurrentRouteName()
|
}
|
||||||
}}
|
}}
|
||||||
onReady={() => {
|
onReady={() => {
|
||||||
attachRouteToLogEvents(getCurrentRouteName)
|
attachRouteToLogEvents(getCurrentRouteName)
|
||||||
logModuleInitTime()
|
logModuleInitTime()
|
||||||
onReady()
|
onReady()
|
||||||
logEvent('router:navigate:sampled', {})
|
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
|
|
|
||||||
|
|
@ -276,8 +276,8 @@ export function DescriptionPlaceholder() {
|
||||||
export type FollowButtonProps = {
|
export type FollowButtonProps = {
|
||||||
profile: AppBskyActorDefs.ProfileViewBasic
|
profile: AppBskyActorDefs.ProfileViewBasic
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
logContext: LogEvents['profile:follow']['logContext'] &
|
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
||||||
LogEvents['profile:unfollow']['logContext']
|
LogEvents['profile:unfollow:sampled']['logContext']
|
||||||
} & Partial<ButtonProps>
|
} & Partial<ButtonProps>
|
||||||
|
|
||||||
export function FollowButton(props: FollowButtonProps) {
|
export function FollowButton(props: FollowButtonProps) {
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ export function useFollowMethods({
|
||||||
logContext,
|
logContext,
|
||||||
}: {
|
}: {
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
|
profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
|
||||||
logContext: LogEvents['profile:follow']['logContext'] &
|
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
||||||
LogEvents['profile:unfollow']['logContext']
|
LogEvents['profile:unfollow:sampled']['logContext']
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const requireAuth = useRequireAuth()
|
const requireAuth = useRequireAuth()
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export type LogEvents = {
|
||||||
secondsActive: number
|
secondsActive: number
|
||||||
}
|
}
|
||||||
'state:foreground:sampled': {}
|
'state:foreground:sampled': {}
|
||||||
'router:navigate:sampled': {}
|
'router:navigate:notifications:sampled': {}
|
||||||
'deepLink:referrerReceived': {
|
'deepLink:referrerReceived': {
|
||||||
to: string
|
to: string
|
||||||
referrer: string
|
referrer: string
|
||||||
|
|
@ -127,25 +127,25 @@ export type LogEvents = {
|
||||||
langs: string
|
langs: string
|
||||||
logContext: 'Composer'
|
logContext: 'Composer'
|
||||||
}
|
}
|
||||||
'post:like': {
|
'post:like:sampled': {
|
||||||
doesLikerFollowPoster: boolean | undefined
|
doesLikerFollowPoster: boolean | undefined
|
||||||
doesPosterFollowLiker: boolean | undefined
|
doesPosterFollowLiker: boolean | undefined
|
||||||
likerClout: number | undefined
|
likerClout: number | undefined
|
||||||
postClout: number | undefined
|
postClout: number | undefined
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:repost': {
|
'post:repost:sampled': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:unlike': {
|
'post:unlike:sampled': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:unrepost': {
|
'post:unrepost:sampled': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:mute': {}
|
'post:mute': {}
|
||||||
'post:unmute': {}
|
'post:unmute': {}
|
||||||
'profile:follow': {
|
'profile:follow:sampled': {
|
||||||
didBecomeMutual: boolean | undefined
|
didBecomeMutual: boolean | undefined
|
||||||
followeeClout: number | undefined
|
followeeClout: number | undefined
|
||||||
followerClout: number | undefined
|
followerClout: number | undefined
|
||||||
|
|
@ -162,7 +162,7 @@ export type LogEvents = {
|
||||||
| 'FeedInterstitial'
|
| 'FeedInterstitial'
|
||||||
| 'ProfileHeaderSuggestedFollows'
|
| 'ProfileHeaderSuggestedFollows'
|
||||||
}
|
}
|
||||||
'profile:unfollow': {
|
'profile:unfollow:sampled': {
|
||||||
logContext:
|
logContext:
|
||||||
| 'RecommendedFollowsItem'
|
| 'RecommendedFollowsItem'
|
||||||
| 'PostThreadItem'
|
| 'PostThreadItem'
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,9 @@ export function toClout(n: number | null | undefined): number | undefined {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DOWNSAMPLE_RATE = 0.95 // 95% likely
|
||||||
const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
|
const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
|
||||||
'router:navigate:sampled',
|
'router:navigate:notifications:sampled',
|
||||||
'state:background:sampled',
|
'state:background:sampled',
|
||||||
'state:foreground:sampled',
|
'state:foreground:sampled',
|
||||||
'home:feedDisplayed:sampled',
|
'home:feedDisplayed:sampled',
|
||||||
|
|
@ -99,8 +100,14 @@ const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
|
||||||
'discover:clickthrough:sampled',
|
'discover:clickthrough:sampled',
|
||||||
'discover:engaged:sampled',
|
'discover:engaged:sampled',
|
||||||
'discover:seen:sampled',
|
'discover:seen:sampled',
|
||||||
|
'post:like:sampled',
|
||||||
|
'post:unlike:sampled',
|
||||||
|
'post:repost:sampled',
|
||||||
|
'post:unrepost:sampled',
|
||||||
|
'profile:follow:sampled',
|
||||||
|
'profile:unfollow:sampled',
|
||||||
])
|
])
|
||||||
const isDownsampledSession = Math.random() < 0.9 // 90% likely
|
const isDownsampledSession = Math.random() < DOWNSAMPLE_RATE
|
||||||
|
|
||||||
export function logEvent<E extends keyof LogEvents>(
|
export function logEvent<E extends keyof LogEvents>(
|
||||||
eventName: E & string,
|
eventName: E & string,
|
||||||
|
|
@ -117,12 +124,16 @@ export function logEvent<E extends keyof LogEvents>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDownsampledSession && DOWNSAMPLED_EVENTS.has(eventName)) {
|
const isDownsampledEvent = DOWNSAMPLED_EVENTS.has(eventName)
|
||||||
|
if (isDownsampledSession && isDownsampledEvent) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const fullMetadata = {
|
const fullMetadata = {
|
||||||
...rawMetadata,
|
...rawMetadata,
|
||||||
} as Record<string, string> // Statsig typings are unnecessarily strict here.
|
} as Record<string, string> // Statsig typings are unnecessarily strict here.
|
||||||
|
if (isDownsampledEvent) {
|
||||||
|
fullMetadata.downsampleRate = DOWNSAMPLE_RATE.toString()
|
||||||
|
}
|
||||||
fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
|
fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
|
||||||
if (Statsig.initializeCalled()) {
|
if (Statsig.initializeCalled()) {
|
||||||
Statsig.logEvent(eventName, null, fullMetadata)
|
Statsig.logEvent(eventName, null, fullMetadata)
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,8 @@ export function useGetPosts() {
|
||||||
|
|
||||||
export function usePostLikeMutationQueue(
|
export function usePostLikeMutationQueue(
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
logContext: LogEvents['post:like']['logContext'] &
|
logContext: LogEvents['post:like:sampled']['logContext'] &
|
||||||
LogEvents['post:unlike']['logContext'],
|
LogEvents['post:unlike:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const postUri = post.uri
|
const postUri = post.uri
|
||||||
|
|
@ -158,7 +158,7 @@ export function usePostLikeMutationQueue(
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePostLikeMutation(
|
function usePostLikeMutation(
|
||||||
logContext: LogEvents['post:like']['logContext'],
|
logContext: LogEvents['post:like:sampled']['logContext'],
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
) {
|
) {
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
|
|
@ -175,7 +175,7 @@ function usePostLikeMutation(
|
||||||
if (currentAccount) {
|
if (currentAccount) {
|
||||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||||
}
|
}
|
||||||
logEvent('post:like', {
|
logEvent('post:like:sampled', {
|
||||||
logContext,
|
logContext,
|
||||||
doesPosterFollowLiker: postAuthor.viewer
|
doesPosterFollowLiker: postAuthor.viewer
|
||||||
? Boolean(postAuthor.viewer.followedBy)
|
? Boolean(postAuthor.viewer.followedBy)
|
||||||
|
|
@ -200,12 +200,12 @@ function usePostLikeMutation(
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePostUnlikeMutation(
|
function usePostUnlikeMutation(
|
||||||
logContext: LogEvents['post:unlike']['logContext'],
|
logContext: LogEvents['post:unlike:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {postUri: string; likeUri: string}>({
|
return useMutation<void, Error, {postUri: string; likeUri: string}>({
|
||||||
mutationFn: ({likeUri}) => {
|
mutationFn: ({likeUri}) => {
|
||||||
logEvent('post:unlike', {logContext})
|
logEvent('post:unlike:sampled', {logContext})
|
||||||
return agent.deleteLike(likeUri)
|
return agent.deleteLike(likeUri)
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
|
|
@ -216,8 +216,8 @@ function usePostUnlikeMutation(
|
||||||
|
|
||||||
export function usePostRepostMutationQueue(
|
export function usePostRepostMutationQueue(
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
logContext: LogEvents['post:repost']['logContext'] &
|
logContext: LogEvents['post:repost:sampled']['logContext'] &
|
||||||
LogEvents['post:unrepost']['logContext'],
|
LogEvents['post:unrepost:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const postUri = post.uri
|
const postUri = post.uri
|
||||||
|
|
@ -273,7 +273,7 @@ export function usePostRepostMutationQueue(
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePostRepostMutation(
|
function usePostRepostMutation(
|
||||||
logContext: LogEvents['post:repost']['logContext'],
|
logContext: LogEvents['post:repost:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<
|
return useMutation<
|
||||||
|
|
@ -282,7 +282,7 @@ function usePostRepostMutation(
|
||||||
{uri: string; cid: string} // the post's uri and cid
|
{uri: string; cid: string} // the post's uri and cid
|
||||||
>({
|
>({
|
||||||
mutationFn: post => {
|
mutationFn: post => {
|
||||||
logEvent('post:repost', {logContext})
|
logEvent('post:repost:sampled', {logContext})
|
||||||
return agent.repost(post.uri, post.cid)
|
return agent.repost(post.uri, post.cid)
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
|
|
@ -292,12 +292,12 @@ function usePostRepostMutation(
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePostUnrepostMutation(
|
function usePostUnrepostMutation(
|
||||||
logContext: LogEvents['post:unrepost']['logContext'],
|
logContext: LogEvents['post:unrepost:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {postUri: string; repostUri: string}>({
|
return useMutation<void, Error, {postUri: string; repostUri: string}>({
|
||||||
mutationFn: ({repostUri}) => {
|
mutationFn: ({repostUri}) => {
|
||||||
logEvent('post:unrepost', {logContext})
|
logEvent('post:unrepost:sampled', {logContext})
|
||||||
return agent.deleteRepost(repostUri)
|
return agent.deleteRepost(repostUri)
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,8 @@ export function useProfileUpdateMutation() {
|
||||||
|
|
||||||
export function useProfileFollowMutationQueue(
|
export function useProfileFollowMutationQueue(
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
||||||
logContext: LogEvents['profile:follow']['logContext'] &
|
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
||||||
LogEvents['profile:unfollow']['logContext'],
|
LogEvents['profile:follow:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
@ -291,7 +291,7 @@ export function useProfileFollowMutationQueue(
|
||||||
}
|
}
|
||||||
|
|
||||||
function useProfileFollowMutation(
|
function useProfileFollowMutation(
|
||||||
logContext: LogEvents['profile:follow']['logContext'],
|
logContext: LogEvents['profile:follow:sampled']['logContext'],
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
||||||
) {
|
) {
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
|
|
@ -306,7 +306,7 @@ function useProfileFollowMutation(
|
||||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||||
}
|
}
|
||||||
captureAction(ProgressGuideAction.Follow)
|
captureAction(ProgressGuideAction.Follow)
|
||||||
logEvent('profile:follow', {
|
logEvent('profile:follow:sampled', {
|
||||||
logContext,
|
logContext,
|
||||||
didBecomeMutual: profile.viewer
|
didBecomeMutual: profile.viewer
|
||||||
? Boolean(profile.viewer.followedBy)
|
? Boolean(profile.viewer.followedBy)
|
||||||
|
|
@ -323,12 +323,12 @@ function useProfileFollowMutation(
|
||||||
}
|
}
|
||||||
|
|
||||||
function useProfileUnfollowMutation(
|
function useProfileUnfollowMutation(
|
||||||
logContext: LogEvents['profile:unfollow']['logContext'],
|
logContext: LogEvents['profile:unfollow:sampled']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {did: string; followUri: string}>({
|
return useMutation<void, Error, {did: string; followUri: string}>({
|
||||||
mutationFn: async ({followUri}) => {
|
mutationFn: async ({followUri}) => {
|
||||||
logEvent('profile:unfollow', {logContext})
|
logEvent('profile:unfollow:sampled', {logContext})
|
||||||
track('Profile:Unfollow', {username: followUri})
|
track('Profile:Unfollow', {username: followUri})
|
||||||
return await agent.deleteFollow(followUri)
|
return await agent.deleteFollow(followUri)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue