Refactor logging in feed-feedback, add debug logging to metrics client
This commit is contained in:
@@ -131,6 +131,8 @@ export function AnalyticsContext({
|
|||||||
combinedMetadata.base.sessionId = sessionId
|
combinedMetadata.base.sessionId = sessionId
|
||||||
combinedMetadata.geolocation = geolocation
|
combinedMetadata.geolocation = geolocation
|
||||||
const context: AnalyticsBaseContextType = {
|
const context: AnalyticsBaseContextType = {
|
||||||
|
...parentContext,
|
||||||
|
// TODO trim down metadata
|
||||||
logger: createLogger(Logger.Context.Default, combinedMetadata),
|
logger: createLogger(Logger.Context.Default, combinedMetadata),
|
||||||
metadata: combinedMetadata,
|
metadata: combinedMetadata,
|
||||||
metric: (event, payload, extraMetadata) => {
|
metric: (event, payload, extraMetadata) => {
|
||||||
@@ -196,6 +198,7 @@ export function useAnalyticsBase() {
|
|||||||
export function useAnalytics() {
|
export function useAnalytics() {
|
||||||
const ctx = useContext(Context)
|
const ctx = useContext(Context)
|
||||||
if (!('feature' in ctx) || !('Features' in ctx)) {
|
if (!('feature' in ctx) || !('Features' in ctx)) {
|
||||||
|
console.log(ctx)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'useAnalytics must be used within an AnalyticsFeaturesContext',
|
'useAnalytics must be used within an AnalyticsFeaturesContext',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {onAppStateChange} from '#/lib/appState'
|
import {onAppStateChange} from '#/lib/appState'
|
||||||
import {isNetworkError} from '#/lib/strings/errors'
|
import {isNetworkError} from '#/lib/strings/errors'
|
||||||
|
import {Logger} from '#/logger'
|
||||||
import {Sentry} from '#/logger/sentry/lib'
|
import {Sentry} from '#/logger/sentry/lib'
|
||||||
import * as env from '#/env'
|
import * as env from '#/env'
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ type Event<M extends Record<string, any>> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TRACKING_ENDPOINT = env.METRICS_API_HOST + '/t'
|
const TRACKING_ENDPOINT = env.METRICS_API_HOST + '/t'
|
||||||
|
const logger = Logger.create(Logger.Context.Metric, {})
|
||||||
|
|
||||||
export class MetricsClient<M extends Record<string, any>> {
|
export class MetricsClient<M extends Record<string, any>> {
|
||||||
private started: boolean = false
|
private started: boolean = false
|
||||||
@@ -49,6 +51,11 @@ export class MetricsClient<M extends Record<string, any>> {
|
|||||||
metadata,
|
metadata,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
logger.debug(`event: ${event as string}`, {
|
||||||
|
payload,
|
||||||
|
metadata,
|
||||||
|
})
|
||||||
|
|
||||||
if (this.queue.length > 100) {
|
if (this.queue.length > 100) {
|
||||||
this.flush()
|
this.flush()
|
||||||
}
|
}
|
||||||
@@ -62,6 +69,10 @@ export class MetricsClient<M extends Record<string, any>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async sendBatch(events: Event<M>[], isRetry: boolean = false) {
|
private async sendBatch(events: Event<M>[], isRetry: boolean = false) {
|
||||||
|
logger.debug(`sendBatch: ${events.length}`, {
|
||||||
|
isRetry,
|
||||||
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const body = JSON.stringify(events)
|
const body = JSON.stringify(events)
|
||||||
if (env.IS_WEB && 'navigator' in globalThis && navigator.sendBeacon) {
|
if (env.IS_WEB && 'navigator' in globalThis && navigator.sendBeacon) {
|
||||||
|
|||||||
+39
-40
@@ -11,7 +11,6 @@ import {type AppBskyFeedDefs} from '@atproto/api'
|
|||||||
import throttle from 'lodash.throttle'
|
import throttle from 'lodash.throttle'
|
||||||
|
|
||||||
import {PROD_FEEDS, STAGING_FEEDS} from '#/lib/constants'
|
import {PROD_FEEDS, STAGING_FEEDS} from '#/lib/constants'
|
||||||
import {Logger} from '#/logger'
|
|
||||||
import {
|
import {
|
||||||
type FeedSourceFeedInfo,
|
type FeedSourceFeedInfo,
|
||||||
type FeedSourceInfo,
|
type FeedSourceInfo,
|
||||||
@@ -22,6 +21,7 @@ import {
|
|||||||
type FeedPostSliceItem,
|
type FeedPostSliceItem,
|
||||||
} from '#/state/queries/post-feed'
|
} from '#/state/queries/post-feed'
|
||||||
import {getItemsForFeedback} from '#/view/com/posts/PostFeed'
|
import {getItemsForFeedback} from '#/view/com/posts/PostFeed'
|
||||||
|
import {useAnalytics} from '#/analytics'
|
||||||
import {useAgent} from './session'
|
import {useAgent} from './session'
|
||||||
|
|
||||||
export const FEEDBACK_FEEDS = [...PROD_FEEDS, ...STAGING_FEEDS]
|
export const FEEDBACK_FEEDS = [...PROD_FEEDS, ...STAGING_FEEDS]
|
||||||
@@ -42,8 +42,6 @@ export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set<
|
|||||||
'app.bsky.feed.defs#interactionSeen',
|
'app.bsky.feed.defs#interactionSeen',
|
||||||
])
|
])
|
||||||
|
|
||||||
const logger = Logger.create(Logger.Context.FeedFeedback)
|
|
||||||
|
|
||||||
export type StateContext = {
|
export type StateContext = {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
onItemSeen: (item: any) => void
|
onItemSeen: (item: any) => void
|
||||||
@@ -65,6 +63,8 @@ export function useFeedFeedback(
|
|||||||
feedSourceInfo: FeedSourceInfo | undefined,
|
feedSourceInfo: FeedSourceInfo | undefined,
|
||||||
hasSession: boolean,
|
hasSession: boolean,
|
||||||
) {
|
) {
|
||||||
|
const ax = useAnalytics()
|
||||||
|
const logger = ax.logger.useContext(ax.logger.Context.FeedFeedback)
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
|
|
||||||
const feed =
|
const feed =
|
||||||
@@ -85,22 +85,55 @@ export function useFeedFeedback(
|
|||||||
WeakSet<FeedPostSliceItem | AppBskyFeedDefs.Interaction>
|
WeakSet<FeedPostSliceItem | AppBskyFeedDefs.Interaction>
|
||||||
>(new WeakSet())
|
>(new WeakSet())
|
||||||
|
|
||||||
|
const flushEvents = useCallback(
|
||||||
|
(stats: AggregatedStats | null, feedDescriptor: string) => {
|
||||||
|
if (stats === null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.clickthroughCount > 0) {
|
||||||
|
ax.metric('feed:clickthrough', {
|
||||||
|
count: stats.clickthroughCount,
|
||||||
|
feed: feedDescriptor,
|
||||||
|
})
|
||||||
|
stats.clickthroughCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.engagedCount > 0) {
|
||||||
|
ax.metric('feed:engaged', {
|
||||||
|
count: stats.engagedCount,
|
||||||
|
feed: feedDescriptor,
|
||||||
|
})
|
||||||
|
stats.engagedCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.seenCount > 0) {
|
||||||
|
ax.metric('feed:seen', {
|
||||||
|
count: stats.seenCount,
|
||||||
|
feed: feedDescriptor,
|
||||||
|
})
|
||||||
|
stats.seenCount = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ax],
|
||||||
|
)
|
||||||
|
|
||||||
const aggregatedStats = useRef<AggregatedStats | null>(null)
|
const aggregatedStats = useRef<AggregatedStats | null>(null)
|
||||||
const throttledFlushAggregatedStats = useMemo(
|
const throttledFlushAggregatedStats = useMemo(
|
||||||
() =>
|
() =>
|
||||||
throttle(
|
throttle(
|
||||||
() =>
|
() =>
|
||||||
flushToStatsig(
|
flushEvents(
|
||||||
aggregatedStats.current,
|
aggregatedStats.current,
|
||||||
feed?.feedDescriptor ?? 'unknown',
|
feed?.feedDescriptor ?? 'unknown',
|
||||||
),
|
),
|
||||||
45e3,
|
5e3,
|
||||||
{
|
{
|
||||||
leading: true, // The outer call is already throttled somewhat.
|
leading: true, // The outer call is already throttled somewhat.
|
||||||
trailing: true,
|
trailing: true,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
[feed?.feedDescriptor],
|
[feed?.feedDescriptor, flushEvents],
|
||||||
)
|
)
|
||||||
|
|
||||||
const sendToFeedNoDelay = useCallback(() => {
|
const sendToFeedNoDelay = useCallback(() => {
|
||||||
@@ -299,37 +332,3 @@ function sendOrAggregateInteractionsForStats(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushToStatsig(stats: AggregatedStats | null, feedDescriptor: string) {
|
|
||||||
if (stats === null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stats.clickthroughCount > 0) {
|
|
||||||
logger.metric('feed:clickthrough', {
|
|
||||||
count: stats.clickthroughCount,
|
|
||||||
feed: feedDescriptor,
|
|
||||||
})
|
|
||||||
stats.clickthroughCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stats.engagedCount > 0) {
|
|
||||||
logger.metric('feed:engaged', {
|
|
||||||
count: stats.engagedCount,
|
|
||||||
feed: feedDescriptor,
|
|
||||||
})
|
|
||||||
stats.engagedCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stats.seenCount > 0) {
|
|
||||||
logger.metric(
|
|
||||||
'feed:seen',
|
|
||||||
{
|
|
||||||
count: stats.seenCount,
|
|
||||||
feed: feedDescriptor,
|
|
||||||
},
|
|
||||||
{statsig: false},
|
|
||||||
)
|
|
||||||
stats.seenCount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user