Fix feedfeedback metrics not distinguishing which feed it's from (#9099)

* fix feedfeedback metrics being sent for all feeds

* remove `discover:` metrics
This commit is contained in:
Samuel Newman
2025-10-01 16:09:12 +03:00
committed by GitHub
parent 144d61ef76
commit 1e6a44f2e8
2 changed files with 36 additions and 17 deletions
+10 -5
View File
@@ -175,19 +175,24 @@ export type MetricEvents = {
'feed:suggestion:press': { 'feed:suggestion:press': {
feedUrl: string feedUrl: string
} }
'discover:showMore': { 'feed:showMore': {
feed: string
feedContext: string feedContext: string
} }
'discover:showLess': { 'feed:showLess': {
feed: string
feedContext: string feedContext: string
} }
'discover:clickthrough': { 'feed:clickthrough': {
feed: string
count: number count: number
} }
'discover:engaged': { 'feed:engaged': {
feed: string
count: number count: number
} }
'discover:seen': { 'feed:seen': {
feed: string
count: number count: number
} }
+26 -12
View File
@@ -12,7 +12,6 @@ import throttle from 'lodash.throttle'
import {PROD_FEEDS, STAGING_FEEDS} from '#/lib/constants' import {PROD_FEEDS, STAGING_FEEDS} from '#/lib/constants'
import {isNetworkError} from '#/lib/hooks/useCleanError' import {isNetworkError} from '#/lib/hooks/useCleanError'
import {logEvent} from '#/lib/statsig/statsig'
import {Logger} from '#/logger' import {Logger} from '#/logger'
import { import {
type FeedSourceFeedInfo, type FeedSourceFeedInfo,
@@ -90,11 +89,19 @@ export function useFeedFeedback(
const aggregatedStats = useRef<AggregatedStats | null>(null) const aggregatedStats = useRef<AggregatedStats | null>(null)
const throttledFlushAggregatedStats = useMemo( const throttledFlushAggregatedStats = useMemo(
() => () =>
throttle(() => flushToStatsig(aggregatedStats.current), 45e3, { throttle(
leading: true, // The outer call is already throttled somewhat. () =>
trailing: true, flushToStatsig(
}), aggregatedStats.current,
[], feed?.feedDescriptor ?? 'unknown',
),
45e3,
{
leading: true, // The outer call is already throttled somewhat.
trailing: true,
},
),
[feed?.feedDescriptor],
) )
const sendToFeedNoDelay = useCallback(() => { const sendToFeedNoDelay = useCallback(() => {
@@ -135,6 +142,7 @@ export function useFeedFeedback(
sendOrAggregateInteractionsForStats( sendOrAggregateInteractionsForStats(
aggregatedStats.current, aggregatedStats.current,
interactionsToSend, interactionsToSend,
feed?.feedDescriptor ?? 'unknown',
) )
throttledFlushAggregatedStats() throttledFlushAggregatedStats()
logger.debug('flushed') logger.debug('flushed')
@@ -271,19 +279,22 @@ function createAggregatedStats(): AggregatedStats {
function sendOrAggregateInteractionsForStats( function sendOrAggregateInteractionsForStats(
stats: AggregatedStats, stats: AggregatedStats,
interactions: AppBskyFeedDefs.Interaction[], interactions: AppBskyFeedDefs.Interaction[],
feed: string,
) { ) {
for (let interaction of interactions) { for (let interaction of interactions) {
switch (interaction.event) { switch (interaction.event) {
// Pressing "Show more" / "Show less" is relatively uncommon so we won't aggregate them. // Pressing "Show more" / "Show less" is relatively uncommon so we won't aggregate them.
// This lets us send the feed context together with them. // This lets us send the feed context together with them.
case 'app.bsky.feed.defs#requestLess': { case 'app.bsky.feed.defs#requestLess': {
logEvent('discover:showLess', { logger.metric('feed:showLess', {
feed,
feedContext: interaction.feedContext ?? '', feedContext: interaction.feedContext ?? '',
}) })
break break
} }
case 'app.bsky.feed.defs#requestMore': { case 'app.bsky.feed.defs#requestMore': {
logEvent('discover:showMore', { logger.metric('feed:showMore', {
feed,
feedContext: interaction.feedContext ?? '', feedContext: interaction.feedContext ?? '',
}) })
break break
@@ -313,28 +324,31 @@ function sendOrAggregateInteractionsForStats(
} }
} }
function flushToStatsig(stats: AggregatedStats | null) { function flushToStatsig(stats: AggregatedStats | null, feedDescriptor: string) {
if (stats === null) { if (stats === null) {
return return
} }
if (stats.clickthroughCount > 0) { if (stats.clickthroughCount > 0) {
logEvent('discover:clickthrough', { logger.metric('feed:clickthrough', {
count: stats.clickthroughCount, count: stats.clickthroughCount,
feed: feedDescriptor,
}) })
stats.clickthroughCount = 0 stats.clickthroughCount = 0
} }
if (stats.engagedCount > 0) { if (stats.engagedCount > 0) {
logEvent('discover:engaged', { logger.metric('feed:engaged', {
count: stats.engagedCount, count: stats.engagedCount,
feed: feedDescriptor,
}) })
stats.engagedCount = 0 stats.engagedCount = 0
} }
if (stats.seenCount > 0) { if (stats.seenCount > 0) {
logEvent('discover:seen', { logger.metric('feed:seen', {
count: stats.seenCount, count: stats.seenCount,
feed: feedDescriptor,
}) })
stats.seenCount = 0 stats.seenCount = 0
} }