From dbe83ce6fdd26939bcf20e7244673f3afdd88d7b Mon Sep 17 00:00:00 2001 From: David Newell Date: Wed, 26 Feb 2025 21:42:53 +0000 Subject: [PATCH 01/12] chore: disable plugin server posthog capture if not set --- plugin-server/src/config/config.ts | 2 ++ plugin-server/src/types.ts | 4 +++ plugin-server/src/utils/posthog.ts | 44 ++++++++++++++++-------------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/plugin-server/src/config/config.ts b/plugin-server/src/config/config.ts index 39d1c7b5ae1a1..8896bfc19fadb 100644 --- a/plugin-server/src/config/config.ts +++ b/plugin-server/src/config/config.ts @@ -138,6 +138,8 @@ export function getDefaultConfig(): PluginsServerConfig { RUSTY_HOOK_URL: '', HOG_HOOK_URL: '', CAPTURE_CONFIG_REDIS_HOST: null, + POSTHOG_API_KEY: '', + POSTHOG_HOST_URL: 'http://localhost:8010', STARTUP_PROFILE_DURATION_SECONDS: 300, // 5 minutes STARTUP_PROFILE_CPU: false, diff --git a/plugin-server/src/types.ts b/plugin-server/src/types.ts index 0e2800aa4b9dd..ce36189971aea 100644 --- a/plugin-server/src/types.ts +++ b/plugin-server/src/types.ts @@ -320,6 +320,10 @@ export interface PluginsServerConfig extends CdpConfig, IngestionConsumerConfig CYCLOTRON_DATABASE_URL: string CYCLOTRON_SHARD_DEPTH_LIMIT: number + // posthog + POSTHOG_API_KEY: string + POSTHOG_HOST_URL: string + // cookieless COOKIELESS_DISABLED: boolean COOKIELESS_FORCE_STATELESS_MODE: boolean diff --git a/plugin-server/src/utils/posthog.ts b/plugin-server/src/utils/posthog.ts index fc32dd1248fc6..6a1c0fd07e140 100644 --- a/plugin-server/src/utils/posthog.ts +++ b/plugin-server/src/utils/posthog.ts @@ -2,31 +2,36 @@ import { captureException as captureSentryException, captureMessage as captureSe import { PostHog } from 'posthog-node' import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' +import { defaultConfig } from '../config/config' import { Team } from '../types' -export const posthog = new PostHog('sTMFPsFhdP1Ssg', { - host: 'https://us.i.posthog.com', - enableExceptionAutocapture: false, // TODO - disabled while data volume is a problem, PS seems /extremely/ chatty exceptions wise -}) +export const posthog = defaultConfig.POSTHOG_API_KEY + ? new PostHog(defaultConfig.POSTHOG_API_KEY, { + host: defaultConfig.POSTHOG_HOST_URL, + enableExceptionAutocapture: false, // TODO - disabled while data volume is a problem, PS seems /extremely/ chatty exceptions wise + }) + : null -if (process.env.NODE_ENV === 'test') { +if (process.env.NODE_ENV === 'test' && posthog) { void posthog.disable() } export const captureTeamEvent = (team: Team, event: string, properties: Record = {}): void => { - posthog.capture({ - distinctId: team.uuid, - event, - properties: { - team: team.uuid, - ...properties, - }, - groups: { - project: team.uuid, - organization: team.organization_id, - instance: process.env.SITE_URL ?? 'unknown', - }, - }) + if (posthog) { + posthog.capture({ + distinctId: team.uuid, + event, + properties: { + team: team.uuid, + ...properties, + }, + groups: { + project: team.uuid, + organization: team.organization_id, + instance: process.env.SITE_URL ?? 'unknown', + }, + }) + } } // We use sentry-style hints rather than our flat property list all over the place, @@ -47,8 +52,7 @@ export function captureException(exception: any, hint?: Partial): sentryId = captureSentryException(exception, hint) } - // TODO - this sampling is a hack while we work on our data consumption in error tracking - if (process.env.NODE_ENV === 'production' && Math.random() < 0.1) { + if (posthog) { let additionalProperties = {} if (hint) { additionalProperties = { From d9a1c7470eea7a1648b82b401414b0b177b58137 Mon Sep 17 00:00:00 2001 From: David Newell Date: Thu, 27 Feb 2025 10:34:55 +0000 Subject: [PATCH 02/12] cleanup calling posthog --- plugin-server/src/main/pluginsServer.ts | 10 ++++---- plugin-server/src/utils/db/hub.ts | 4 +-- plugin-server/src/utils/posthog.ts | 21 +++++++++++++--- .../src/worker/ingestion/action-matcher.ts | 7 +----- .../src/worker/ingestion/team-manager.ts | 25 +++++++------------ .../each-batch-webhooks.test.ts | 2 +- .../main/ingestion-queues/each-batch.test.ts | 6 +---- .../worker/ingestion/action-matcher.test.ts | 2 +- .../event-pipeline-integration.test.ts | 2 +- .../worker/ingestion/team-manager.test.ts | 2 +- .../tests/worker/plugins/run.test.ts | 2 +- 11 files changed, 41 insertions(+), 42 deletions(-) diff --git a/plugin-server/src/main/pluginsServer.ts b/plugin-server/src/main/pluginsServer.ts index 119715add0266..56289c998cfda 100644 --- a/plugin-server/src/main/pluginsServer.ts +++ b/plugin-server/src/main/pluginsServer.ts @@ -27,7 +27,7 @@ import { closeHub, createHub, createKafkaClient } from '../utils/db/hub' import { PostgresRouter } from '../utils/db/postgres' import { createRedisClient } from '../utils/db/redis' import { cancelAllScheduledJobs } from '../utils/node-schedule' -import { captureException, posthog } from '../utils/posthog' +import { captureException, flush as flushPostHog, shutdown as shutdownPostHog } from '../utils/posthog' import { PubSub } from '../utils/pubsub' import { status } from '../utils/status' import { delay } from '../utils/utils' @@ -132,7 +132,7 @@ export async function startPluginsServer( pubSub?.stop(), graphileWorker?.stop(), ...services.map((service) => service.onShutdown()), - posthog.shutdown(), + shutdownPostHog(), ]) if (serverInstance.hub) { @@ -390,7 +390,7 @@ export async function startPluginsServer( // we need to create them. We only initialize the ones we need. const postgres = hub?.postgres ?? new PostgresRouter(serverConfig) const kafka = hub?.kafka ?? createKafkaClient(serverConfig) - const teamManager = hub?.teamManager ?? new TeamManager(postgres, serverConfig) + const teamManager = hub?.teamManager ?? new TeamManager(postgres) const organizationManager = hub?.organizationManager ?? new OrganizationManager(postgres, teamManager) const kafkaProducerWrapper = hub?.kafkaProducer ?? (await KafkaProducerWrapper.create(serverConfig)) const rustyHook = hub?.rustyHook ?? new RustyHook(serverConfig) @@ -403,7 +403,7 @@ export async function startPluginsServer( ) const actionManager = hub?.actionManager ?? new ActionManager(postgres, serverConfig) - const actionMatcher = hub?.actionMatcher ?? new ActionMatcher(postgres, actionManager, teamManager) + const actionMatcher = hub?.actionMatcher ?? new ActionMatcher(postgres, actionManager) const groupTypeManager = new GroupTypeManager(postgres, teamManager, serverConfig.SITE_URL) services.push( @@ -610,7 +610,7 @@ export async function startPluginsServer( captureException(error) status.error('💥', 'Launchpad failure!', { error: error.stack ?? error }) void Sentry.flush().catch(() => null) // Flush Sentry in the background - void posthog.flush().catch(() => null) + flushPostHog() status.error('💥', 'Exception while starting server, shutting down!', { error }) await closeJobs() process.exit(1) diff --git a/plugin-server/src/utils/db/hub.ts b/plugin-server/src/utils/db/hub.ts index 7e4c7c5972da3..8f3942a1ba20e 100644 --- a/plugin-server/src/utils/db/hub.ts +++ b/plugin-server/src/utils/db/hub.ts @@ -132,14 +132,14 @@ export async function createHub( serverConfig.PLUGINS_DEFAULT_LOG_LEVEL, serverConfig.PERSON_INFO_CACHE_TTL ) - const teamManager = new TeamManager(postgres, serverConfig) + const teamManager = new TeamManager(postgres) const organizationManager = new OrganizationManager(postgres, teamManager) const pluginsApiKeyManager = new PluginsApiKeyManager(db) const rootAccessManager = new RootAccessManager(db) const rustyHook = new RustyHook(serverConfig) const actionManager = new ActionManager(postgres, serverConfig) - const actionMatcher = new ActionMatcher(postgres, actionManager, teamManager) + const actionMatcher = new ActionMatcher(postgres, actionManager) const groupTypeManager = new GroupTypeManager(postgres, teamManager) const cookielessManager = new CookielessManager(serverConfig, redisPool, teamManager) diff --git a/plugin-server/src/utils/posthog.ts b/plugin-server/src/utils/posthog.ts index 6a1c0fd07e140..04572ddb47394 100644 --- a/plugin-server/src/utils/posthog.ts +++ b/plugin-server/src/utils/posthog.ts @@ -5,7 +5,7 @@ import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' import { defaultConfig } from '../config/config' import { Team } from '../types' -export const posthog = defaultConfig.POSTHOG_API_KEY +const posthog = defaultConfig.POSTHOG_API_KEY ? new PostHog(defaultConfig.POSTHOG_API_KEY, { host: defaultConfig.POSTHOG_HOST_URL, enableExceptionAutocapture: false, // TODO - disabled while data volume is a problem, PS seems /extremely/ chatty exceptions wise @@ -16,10 +16,15 @@ if (process.env.NODE_ENV === 'test' && posthog) { void posthog.disable() } -export const captureTeamEvent = (team: Team, event: string, properties: Record = {}): void => { +export const captureTeamEvent = ( + team: Team, + event: string, + properties: Record = {}, + distinctId: string | null = null +): void => { if (posthog) { posthog.capture({ - distinctId: team.uuid, + distinctId: distinctId ?? team.uuid, event, properties: { team: team.uuid, @@ -66,3 +71,13 @@ export function captureException(exception: any, hint?: Partial): return sentryId } + +export function shutdown(): Promise | null { + return posthog && posthog.shutdown() +} + +export function flush(): void { + if (posthog) { + void posthog.flush().catch(() => null) + } +} diff --git a/plugin-server/src/worker/ingestion/action-matcher.ts b/plugin-server/src/worker/ingestion/action-matcher.ts index 752eb52abb84a..fc49559b75592 100644 --- a/plugin-server/src/worker/ingestion/action-matcher.ts +++ b/plugin-server/src/worker/ingestion/action-matcher.ts @@ -24,7 +24,6 @@ import { mutatePostIngestionEventWithElementsList } from '../../utils/event' import { captureException } from '../../utils/posthog' import { stringify } from '../../utils/utils' import { ActionManager } from './action-manager' -import { TeamManager } from './team-manager' /** These operators can only be matched if the provided filter's value has the right type. */ const propertyOperatorToRequiredValueType: Partial> = { @@ -133,11 +132,7 @@ export function matchString(actual: string, expected: string, matching: StringMa } export class ActionMatcher { - constructor( - private postgres: PostgresRouter, - private actionManager: ActionManager, - private teamManager: TeamManager - ) {} + constructor(private postgres: PostgresRouter, private actionManager: ActionManager) {} public hasWebhooks(teamId: number): boolean { return Object.keys(this.actionManager.getTeamActions(teamId)).length > 0 diff --git a/plugin-server/src/worker/ingestion/team-manager.ts b/plugin-server/src/worker/ingestion/team-manager.ts index d787c50c6c948..b51e380dd506d 100644 --- a/plugin-server/src/worker/ingestion/team-manager.ts +++ b/plugin-server/src/worker/ingestion/team-manager.ts @@ -3,18 +3,17 @@ import LRU from 'lru-cache' import { ONE_MINUTE } from '../../config/constants' import { TeamIDWithConfig } from '../../main/ingestion-queues/session-recording/session-recordings-consumer' -import { PipelineEvent, PluginsServerConfig, ProjectId, Team, TeamId } from '../../types' +import { PipelineEvent, ProjectId, Team, TeamId } from '../../types' import { PostgresRouter, PostgresUse } from '../../utils/db/postgres' import { timeoutGuard } from '../../utils/db/utils' -import { posthog } from '../../utils/posthog' +import { captureTeamEvent } from '../../utils/posthog' export class TeamManager { postgres: PostgresRouter teamCache: LRU tokenToTeamIdCache: LRU - instanceSiteUrl: string - constructor(postgres: PostgresRouter, serverConfig: PluginsServerConfig) { + constructor(postgres: PostgresRouter) { this.postgres = postgres this.teamCache = new LRU({ @@ -27,7 +26,6 @@ export class TeamManager { maxAge: 5 * ONE_MINUTE, // Expiration for negative lookups, positive lookups will expire via teamCache first updateAgeOnGet: false, // Make default behaviour explicit }) - this.instanceSiteUrl = serverConfig.SITE_URL || 'unknown' } public async getTeamForEvent(event: PipelineEvent): Promise { @@ -132,21 +130,16 @@ export class TeamManager { ) const distinctIds: { distinct_id: string }[] = organizationMembers.rows for (const { distinct_id } of distinctIds) { - posthog.capture({ - distinctId: distinct_id, - event: 'first team event ingested', - properties: { - team: team.uuid, + captureTeamEvent( + team, + 'first team event ingested', + { sdk: properties.$lib, realm: properties.realm, host: properties.$host, }, - groups: { - project: team.uuid, - organization: team.organization_id, - instance: this.instanceSiteUrl, - }, - }) + distinct_id + ) } } } diff --git a/plugin-server/tests/main/ingestion-queues/each-batch-webhooks.test.ts b/plugin-server/tests/main/ingestion-queues/each-batch-webhooks.test.ts index cd4317e4efccd..7b47297cf0bff 100644 --- a/plugin-server/tests/main/ingestion-queues/each-batch-webhooks.test.ts +++ b/plugin-server/tests/main/ingestion-queues/each-batch-webhooks.test.ts @@ -84,7 +84,7 @@ describe('eachMessageWebhooksHandlers', () => { it('calls runWebhooksHandlersEventPipeline', async () => { const actionManager = new ActionManager(hub.postgres, hub) - const actionMatcher = new ActionMatcher(hub.postgres, actionManager, hub.teamManager) + const actionMatcher = new ActionMatcher(hub.postgres, actionManager) const hookCannon = new HookCommander( hub.postgres, hub.teamManager, diff --git a/plugin-server/tests/main/ingestion-queues/each-batch.test.ts b/plugin-server/tests/main/ingestion-queues/each-batch.test.ts index 0f2d7cc3b1807..4b0546dbc324b 100644 --- a/plugin-server/tests/main/ingestion-queues/each-batch.test.ts +++ b/plugin-server/tests/main/ingestion-queues/each-batch.test.ts @@ -172,11 +172,7 @@ describe('eachBatchX', () => { describe('eachBatchWebhooksHandlers', () => { it('calls runWebhooksHandlersEventPipeline', async () => { const actionManager = new ActionManager(queue.pluginsServer.postgres, queue.pluginsServer) - const actionMatcher = new ActionMatcher( - queue.pluginsServer.postgres, - actionManager, - queue.pluginsServer.teamManager - ) + const actionMatcher = new ActionMatcher(queue.pluginsServer.postgres, actionManager) const hookCannon = new HookCommander( queue.pluginsServer.postgres, queue.pluginsServer.teamManager, diff --git a/plugin-server/tests/worker/ingestion/action-matcher.test.ts b/plugin-server/tests/worker/ingestion/action-matcher.test.ts index 7bf6fa15ea660..ede5e7d0fea83 100644 --- a/plugin-server/tests/worker/ingestion/action-matcher.test.ts +++ b/plugin-server/tests/worker/ingestion/action-matcher.test.ts @@ -54,7 +54,7 @@ describe('ActionMatcher', () => { hub = await createHub() actionManager = new ActionManager(hub.db.postgres, hub) await actionManager.start() - actionMatcher = new ActionMatcher(hub.db.postgres, actionManager, hub.teamManager) + actionMatcher = new ActionMatcher(hub.db.postgres, actionManager) actionCounter = 0 }) diff --git a/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts b/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts index b3838ef300a44..808594f819efb 100644 --- a/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts +++ b/plugin-server/tests/worker/ingestion/event-pipeline/event-pipeline-integration.test.ts @@ -46,7 +46,7 @@ describe('Event Pipeline integration test', () => { actionManager = new ActionManager(hub.db.postgres, hub) await actionManager.start() - actionMatcher = new ActionMatcher(hub.db.postgres, actionManager, hub.teamManager) + actionMatcher = new ActionMatcher(hub.db.postgres, actionManager) hookCannon = new HookCommander( hub.db.postgres, hub.teamManager, diff --git a/plugin-server/tests/worker/ingestion/team-manager.test.ts b/plugin-server/tests/worker/ingestion/team-manager.test.ts index 94d31e7e0b60f..40d65c06b3bf7 100644 --- a/plugin-server/tests/worker/ingestion/team-manager.test.ts +++ b/plugin-server/tests/worker/ingestion/team-manager.test.ts @@ -20,7 +20,7 @@ describe('TeamManager()', () => { beforeEach(async () => { await resetTestDatabase() postgres = new PostgresRouter(defaultConfig) - teamManager = new TeamManager(postgres, defaultConfig) + teamManager = new TeamManager(postgres) // @ts-expect-error TODO: Fix underlying settings, is this really working? Settings.defaultZoneName = 'utc' diff --git a/plugin-server/tests/worker/plugins/run.test.ts b/plugin-server/tests/worker/plugins/run.test.ts index 291835b406871..88a70cc50a842 100644 --- a/plugin-server/tests/worker/plugins/run.test.ts +++ b/plugin-server/tests/worker/plugins/run.test.ts @@ -279,7 +279,7 @@ describe('runComposeWebhook', () => { queueMetric: jest.fn(), queueError: jest.fn(), } as any, - actionMatcher: new ActionMatcher(mockPostgres, mockActionManager, {} as any), + actionMatcher: new ActionMatcher(mockPostgres, mockActionManager), } }) From 944400ec253ab4293c2522497c862176e7cd9032 Mon Sep 17 00:00:00 2001 From: David Newell Date: Thu, 27 Feb 2025 13:57:03 +0000 Subject: [PATCH 03/12] mock --- plugin-server/tests/main/process-event.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index 481262fb9528b..c7284e6e9d476 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -24,7 +24,6 @@ import { import { closeHub, createHub } from '../../src/utils/db/hub' import { PostgresUse } from '../../src/utils/db/postgres' import { personInitialAndUTMProperties } from '../../src/utils/db/utils' -import { posthog } from '../../src/utils/posthog' import { UUIDT } from '../../src/utils/utils' import { EventPipelineRunner } from '../../src/worker/ingestion/event-pipeline/runner' import { EventsProcessor } from '../../src/worker/ingestion/process-event' @@ -880,8 +879,11 @@ test('capture first team event', async () => { 'testTag' ) - posthog.capture = jest.fn() as any - posthog.identify = jest.fn() as any + const captureTeamEventMock = jest.fn() + jest.mock('../../src/utils/posthog.ts', () => ({ + ...jest.requireActual('../../src/utils/posthog.ts'), + captureTeamEvent: captureTeamEventMock, + })) await processEvent( '2', @@ -900,7 +902,7 @@ test('capture first team event', async () => { new UUIDT().toString() ) - expect(posthog.capture).toHaveBeenCalledWith({ + expect(captureTeamEventMock).toHaveBeenCalledWith({ distinctId: 'plugin_test_user_distinct_id_1001', event: 'first team event ingested', properties: { From b30a14ac7d9d61e737784744c7eed93bbac80bb0 Mon Sep 17 00:00:00 2001 From: David Newell Date: Thu, 27 Feb 2025 14:51:33 +0000 Subject: [PATCH 04/12] better mock --- plugin-server/src/utils/posthog.ts | 19 +++++++++++++------ .../tests/main/process-event.test.ts | 9 +++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/plugin-server/src/utils/posthog.ts b/plugin-server/src/utils/posthog.ts index 04572ddb47394..f954915f253f4 100644 --- a/plugin-server/src/utils/posthog.ts +++ b/plugin-server/src/utils/posthog.ts @@ -16,7 +16,7 @@ if (process.env.NODE_ENV === 'test' && posthog) { void posthog.disable() } -export const captureTeamEvent = ( +const captureTeamEvent = ( team: Team, event: string, properties: Record = {}, @@ -41,14 +41,14 @@ export const captureTeamEvent = ( // We use sentry-style hints rather than our flat property list all over the place, // so define a type for them that we can flatten internally -export type Primitive = number | string | boolean | bigint | symbol | null | undefined -export interface ExceptionHint { +type Primitive = number | string | boolean | bigint | symbol | null | undefined +interface ExceptionHint { level: SeverityLevel tags: Record extra: Record } -export function captureException(exception: any, hint?: Partial): string { +function captureException(exception: any, hint?: Partial): string { //If the passed "exception" is a string, capture it as a message, otherwise, capture it as an exception let sentryId: string if (typeof exception === 'string') { @@ -72,12 +72,19 @@ export function captureException(exception: any, hint?: Partial): return sentryId } -export function shutdown(): Promise | null { +function shutdown(): Promise | null { return posthog && posthog.shutdown() } -export function flush(): void { +function flush(): void { if (posthog) { void posthog.flush().catch(() => null) } } + +export default { + flush, + shutdown, + captureException, + captureTeamEvent, +} diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index c7284e6e9d476..b4f78b5d03b49 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -24,6 +24,7 @@ import { import { closeHub, createHub } from '../../src/utils/db/hub' import { PostgresUse } from '../../src/utils/db/postgres' import { personInitialAndUTMProperties } from '../../src/utils/db/utils' +import posthog from '../../src/utils/posthog' import { UUIDT } from '../../src/utils/utils' import { EventPipelineRunner } from '../../src/worker/ingestion/event-pipeline/runner' import { EventsProcessor } from '../../src/worker/ingestion/process-event' @@ -870,6 +871,8 @@ test('long htext', async () => { }) test('capture first team event', async () => { + const captureTeamEventMock = jest.spyOn(posthog, 'captureTeamEvent') + await hub.db.postgres.query( PostgresUse.COMMON_WRITE, `UPDATE posthog_team @@ -879,12 +882,6 @@ test('capture first team event', async () => { 'testTag' ) - const captureTeamEventMock = jest.fn() - jest.mock('../../src/utils/posthog.ts', () => ({ - ...jest.requireActual('../../src/utils/posthog.ts'), - captureTeamEvent: captureTeamEventMock, - })) - await processEvent( '2', '', From 09dabee3d46e23159f3167413e49de55e105b5d8 Mon Sep 17 00:00:00 2001 From: David Newell Date: Thu, 27 Feb 2025 15:34:29 +0000 Subject: [PATCH 05/12] fix all imports --- plugin-server/src/cdp/redis.ts | 4 +- .../services/hog-function-manager.service.ts | 2 +- plugin-server/src/cdp/utils.ts | 2 +- .../src/ingestion/ingestion-consumer.ts | 2 +- .../main/graphile-worker/graphile-worker.ts | 2 +- .../batch-processing/each-batch-ingestion.ts | 2 +- .../src/main/ingestion-queues/kafka-queue.ts | 2 +- .../session-recording-v2/consumer.ts | 2 +- .../session-recording-v2/utils.ts | 2 +- .../session-recording/process-event.ts | 2 +- .../services/console-logs-ingester.ts | 2 +- .../services/offset-high-water-marker.ts | 2 +- .../services/realtime-manager.ts | 2 +- .../services/replay-events-ingester.ts | 2 +- .../services/session-manager.ts | 2 +- .../session-recordings-consumer.ts | 2 +- .../session-recording/utils.ts | 2 +- plugin-server/src/main/pluginsServer.ts | 7 ++-- plugin-server/src/main/utils.ts | 2 +- plugin-server/src/utils/db/db.ts | 2 +- plugin-server/src/utils/db/elements-chain.ts | 2 +- plugin-server/src/utils/db/error.ts | 2 +- plugin-server/src/utils/db/redis.ts | 2 +- plugin-server/src/utils/db/utils.ts | 2 +- plugin-server/src/utils/exceptions.ts | 35 ++++++++++++++++ plugin-server/src/utils/posthog.ts | 41 +++---------------- plugin-server/src/utils/pubsub.ts | 2 +- plugin-server/src/utils/utils.ts | 2 +- .../src/worker/ingestion/action-matcher.ts | 2 +- .../src/worker/ingestion/app-metrics.ts | 2 +- .../event-pipeline/prepareEventStep.ts | 2 +- .../worker/ingestion/event-pipeline/runner.ts | 2 +- plugin-server/src/worker/ingestion/hooks.ts | 2 +- .../src/worker/ingestion/person-state.ts | 2 +- .../src/worker/ingestion/process-event.ts | 2 +- .../src/worker/ingestion/timestamps.ts | 2 +- plugin-server/src/worker/piscina.ts | 2 +- plugin-server/src/worker/rusty-hook.ts | 2 +- plugin-server/src/worker/worker.ts | 2 +- 39 files changed, 82 insertions(+), 75 deletions(-) create mode 100644 plugin-server/src/utils/exceptions.ts diff --git a/plugin-server/src/cdp/redis.ts b/plugin-server/src/cdp/redis.ts index c6fabde7ac114..b6b73b966953b 100644 --- a/plugin-server/src/cdp/redis.ts +++ b/plugin-server/src/cdp/redis.ts @@ -6,7 +6,7 @@ import { Pipeline, Redis } from 'ioredis' import { PluginsServerConfig } from '../types' import { createRedisClient } from '../utils/db/redis' import { timeoutGuard } from '../utils/db/utils' -import { captureException } from '../utils/posthog' +import posthog from '../utils/posthog' import { status } from '../utils/status' type WithCheckRateLimit = { @@ -126,7 +126,7 @@ export const createCdpRedisPool = (config: PluginsServerConfig): CdpRedis => { } catch (e) { if (options.failOpen) { // We log the error and return null - captureException(e) + posthog.captureException(e) status.error(`Redis call${options.name} failed`, e) return null } diff --git a/plugin-server/src/cdp/services/hog-function-manager.service.ts b/plugin-server/src/cdp/services/hog-function-manager.service.ts index fa9aaa8a4087b..3c603343855ab 100644 --- a/plugin-server/src/cdp/services/hog-function-manager.service.ts +++ b/plugin-server/src/cdp/services/hog-function-manager.service.ts @@ -2,7 +2,7 @@ import * as schedule from 'node-schedule' import { Hub, Team } from '../../types' import { PostgresUse } from '../../utils/db/postgres' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { PubSub } from '../../utils/pubsub' import { status } from '../../utils/status' import { HogFunctionType, HogFunctionTypeType, IntegrationType } from '../types' diff --git a/plugin-server/src/cdp/utils.ts b/plugin-server/src/cdp/utils.ts index 6e9205856338a..b719dcf6349e8 100644 --- a/plugin-server/src/cdp/utils.ts +++ b/plugin-server/src/cdp/utils.ts @@ -8,7 +8,7 @@ import { gunzip, gzip } from 'zlib' import { RawClickHouseEvent, Team, TimestampFormat } from '../types' import { safeClickhouseString } from '../utils/db/utils' -import { captureException } from '../utils/posthog' +import { captureException } from '../utils/exceptions' import { status } from '../utils/status' import { castTimestampOrNow, clickHouseTimestampToISO, UUIDT } from '../utils/utils' import { CdpInternalEvent } from './schema' diff --git a/plugin-server/src/ingestion/ingestion-consumer.ts b/plugin-server/src/ingestion/ingestion-consumer.ts index 464790f82618e..bbc3aaf20937b 100644 --- a/plugin-server/src/ingestion/ingestion-consumer.ts +++ b/plugin-server/src/ingestion/ingestion-consumer.ts @@ -17,7 +17,7 @@ import { import { runInstrumentedFunction } from '../main/utils' import { Hub, PipelineEvent, PluginServerService } from '../types' import { normalizeEvent } from '../utils/event' -import { captureException } from '../utils/posthog' +import { captureException } from '../utils/exceptions' import { retryIfRetriable } from '../utils/retries' import { status } from '../utils/status' import { EventPipelineResult, EventPipelineRunner } from '../worker/ingestion/event-pipeline/runner' diff --git a/plugin-server/src/main/graphile-worker/graphile-worker.ts b/plugin-server/src/main/graphile-worker/graphile-worker.ts index 9994549396f46..b88a351775e78 100644 --- a/plugin-server/src/main/graphile-worker/graphile-worker.ts +++ b/plugin-server/src/main/graphile-worker/graphile-worker.ts @@ -11,8 +11,8 @@ import { import { Pool } from 'pg' import { EnqueuedJob, Hub } from '../../types' +import { captureException } from '../../utils/exceptions' import { instrument } from '../../utils/metrics' -import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { createPostgresPool } from '../../utils/utils' import { graphileEnqueueJobCounter } from './metrics' diff --git a/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts b/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts index 393872a88dbd7..a9e3335c2eb76 100644 --- a/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts +++ b/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts @@ -4,7 +4,7 @@ import { Message, MessageHeader } from 'node-rdkafka' import { KAFKA_EVENTS_PLUGIN_INGESTION_DLQ, KAFKA_EVENTS_PLUGIN_INGESTION_OVERFLOW } from '../../../config/kafka-topics' import { PipelineEvent, ValueMatcher } from '../../../types' import { formPipelineEvent } from '../../../utils/event' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { retryIfRetriable } from '../../../utils/retries' import { status } from '../../../utils/status' import { ConfiguredLimiter, LoggingLimiter } from '../../../utils/token-bucket' diff --git a/plugin-server/src/main/ingestion-queues/kafka-queue.ts b/plugin-server/src/main/ingestion-queues/kafka-queue.ts index d38e87be6dae4..0ecdd4273941c 100644 --- a/plugin-server/src/main/ingestion-queues/kafka-queue.ts +++ b/plugin-server/src/main/ingestion-queues/kafka-queue.ts @@ -6,7 +6,7 @@ import { BatchConsumer, startBatchConsumer } from '../../kafka/batch-consumer' import { createRdConnectionConfigFromEnvVars } from '../../kafka/config' import { Hub } from '../../types' import { timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { status } from '../../utils/status' import { killGracefully } from '../../utils/utils' import { EventsProcessor } from '../../worker/ingestion/process-event' diff --git a/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts b/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts index f0b360990ceab..c45b4891873dc 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts @@ -15,7 +15,7 @@ import { PostgresRouter } from '~/src/utils/db/postgres' import { buildIntegerMatcher } from '../../../config/config' import { BatchConsumer } from '../../../kafka/batch-consumer' import { PluginServerService, PluginsServerConfig, ValueMatcher } from '../../../types' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status as logger } from '../../../utils/status' import { captureIngestionWarning } from '../../../worker/ingestion/utils' import { runInstrumentedFunction } from '../../utils' diff --git a/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts b/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts index e35e3da3d6c44..1510258bf28cc 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts @@ -1,6 +1,6 @@ import { KafkaConsumer, PartitionMetadata } from 'node-rdkafka' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' export const getPartitionsForTopic = ( diff --git a/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts b/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts index 32167a9b28917..3ef81cb6bffc3 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts @@ -1,7 +1,7 @@ import { DateTime } from 'luxon' import { ClickHouseTimestamp, RRWebEvent, TimestampFormat } from '../../../types' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' import { castTimestampOrNow } from '../../../utils/utils' import { activeMilliseconds } from './snapshot-segmenter' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts index 646dd28e64d63..93f43e3cf4102 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts @@ -4,7 +4,7 @@ import { KAFKA_LOG_ENTRIES } from '../../../../config/kafka-topics' import { findOffsetsToCommit } from '../../../../kafka/consumer' import { retryOnDependencyUnavailableError } from '../../../../kafka/error-handling' import { KafkaProducerWrapper } from '../../../../kafka/producer' -import { captureException } from '../../../../utils/posthog' +import { captureException } from '../../../../utils/exceptions' import { status } from '../../../../utils/status' import { eventDroppedCounter } from '../../metrics' import { ConsoleLogEntry, gatherConsoleLogEvents, RRWebEventType } from '../process-event' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts index a313272539a2b..9c26b73588b74 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts @@ -3,7 +3,7 @@ import { TopicPartition } from 'node-rdkafka' import { RedisPool } from '../../../../types' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/posthog' +import { captureException } from '../../../../utils/exceptions' import { status } from '../../../../utils/status' export const offsetHighWaterMarkKey = (prefix: string, tp: TopicPartition) => { diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts index 50b7b8b29012b..da5bdbee5fa38 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts @@ -5,7 +5,7 @@ import { EventEmitter } from 'node:events' import { PluginsServerConfig, RedisPool } from '../../../../types' import { createRedis } from '../../../../utils/db/redis' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/posthog' +import { captureException } from '../../../../utils/exceptions' import { status } from '../../../../utils/status' const Keys = { diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts index 609c0fe2184fc..6f817ce74b5ed 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts @@ -6,7 +6,7 @@ import { KAFKA_CLICKHOUSE_SESSION_REPLAY_EVENTS } from '../../../../config/kafka import { findOffsetsToCommit } from '../../../../kafka/consumer' import { retryOnDependencyUnavailableError } from '../../../../kafka/error-handling' import { KafkaProducerWrapper } from '../../../../kafka/producer' -import { captureException } from '../../../../utils/posthog' +import { captureException } from '../../../../utils/exceptions' import { status } from '../../../../utils/status' import { captureIngestionWarning } from '../../../../worker/ingestion/utils' import { eventDroppedCounter } from '../../metrics' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts index 08cd5b91b49a4..4e04d9a639a41 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts @@ -12,7 +12,7 @@ import * as zlib from 'zlib' import { PluginsServerConfig } from '../../../../types' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/posthog' +import { captureException } from '../../../../utils/exceptions' import { status } from '../../../../utils/status' import { asyncTimeoutGuard } from '../../../../utils/timing' import { ObjectStorage } from '../../../services/object_storage' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts index 99237380f09e1..1feb4cdcbd667 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts @@ -16,7 +16,7 @@ import { PluginServerService, PluginsServerConfig, RedisPool, TeamId, ValueMatch import { BackgroundRefresher } from '../../../utils/background-refresher' import { PostgresRouter } from '../../../utils/db/postgres' import { createRedisPool } from '../../../utils/db/redis' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' import { fetchTeamTokensWithRecordings } from '../../../worker/ingestion/team-manager' import { ObjectStorage } from '../../services/object_storage' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/utils.ts b/plugin-server/src/main/ingestion-queues/session-recording/utils.ts index 9905f24b24afd..6b7e6abf91ae2 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/utils.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/utils.ts @@ -5,7 +5,7 @@ import { Counter } from 'prom-client' import { KafkaProducerWrapper } from '../../../kafka/producer' import { PipelineEvent, RawEventMessage, RRWebEvent } from '../../../types' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' import { captureIngestionWarning } from '../../../worker/ingestion/utils' import { eventDroppedCounter } from '../metrics' diff --git a/plugin-server/src/main/pluginsServer.ts b/plugin-server/src/main/pluginsServer.ts index 56289c998cfda..59d8027f5c4fa 100644 --- a/plugin-server/src/main/pluginsServer.ts +++ b/plugin-server/src/main/pluginsServer.ts @@ -26,8 +26,9 @@ import { Hub, PluginServerCapabilities, PluginServerService, PluginsServerConfig import { closeHub, createHub, createKafkaClient } from '../utils/db/hub' import { PostgresRouter } from '../utils/db/postgres' import { createRedisClient } from '../utils/db/redis' +import { captureException } from '../utils/exceptions' import { cancelAllScheduledJobs } from '../utils/node-schedule' -import { captureException, flush as flushPostHog, shutdown as shutdownPostHog } from '../utils/posthog' +import posthog from '../utils/posthog' import { PubSub } from '../utils/pubsub' import { status } from '../utils/status' import { delay } from '../utils/utils' @@ -132,7 +133,7 @@ export async function startPluginsServer( pubSub?.stop(), graphileWorker?.stop(), ...services.map((service) => service.onShutdown()), - shutdownPostHog(), + posthog.shutdown(), ]) if (serverInstance.hub) { @@ -610,7 +611,7 @@ export async function startPluginsServer( captureException(error) status.error('💥', 'Launchpad failure!', { error: error.stack ?? error }) void Sentry.flush().catch(() => null) // Flush Sentry in the background - flushPostHog() + posthog.flush() status.error('💥', 'Exception while starting server, shutting down!', { error }) await closeJobs() process.exit(1) diff --git a/plugin-server/src/main/utils.ts b/plugin-server/src/main/utils.ts index a5f7008d8ae11..5ec6421504568 100644 --- a/plugin-server/src/main/utils.ts +++ b/plugin-server/src/main/utils.ts @@ -1,7 +1,7 @@ import { exponentialBuckets, Histogram } from 'prom-client' import { timeoutGuard } from '../utils/db/utils' -import { captureException } from '../utils/posthog' +import { captureException } from '../utils/exceptions' import { status } from '../utils/status' interface FunctionInstrumentation { diff --git a/plugin-server/src/utils/db/db.ts b/plugin-server/src/utils/db/db.ts index 4304acca7ce07..1fdde33b0a2bf 100644 --- a/plugin-server/src/utils/db/db.ts +++ b/plugin-server/src/utils/db/db.ts @@ -49,8 +49,8 @@ import { fetchAction, fetchAllActionsGroupedByTeam } from '../../worker/ingestio import { fetchOrganization } from '../../worker/ingestion/organization-manager' import { fetchTeam, fetchTeamByToken } from '../../worker/ingestion/team-manager' import { parseRawClickHouseEvent } from '../event' +import { captureException } from '../exceptions' import { instrumentQuery } from '../metrics' -import { captureException } from '../posthog' import { status } from '../status' import { castTimestampOrNow, diff --git a/plugin-server/src/utils/db/elements-chain.ts b/plugin-server/src/utils/db/elements-chain.ts index 8be7488a5aec2..1fd393c57453e 100644 --- a/plugin-server/src/utils/db/elements-chain.ts +++ b/plugin-server/src/utils/db/elements-chain.ts @@ -1,7 +1,7 @@ import RE2 from 're2' import { Element } from '../../types' -import { captureException } from '../posthog' +import { captureException } from '../exceptions' import { escapeQuotes } from './utils' // Below splits all elements by ;, while ignoring escaped quotes and semicolons within quotes diff --git a/plugin-server/src/utils/db/error.ts b/plugin-server/src/utils/db/error.ts index 5e922383cf8c5..0d872ff97e80c 100644 --- a/plugin-server/src/utils/db/error.ts +++ b/plugin-server/src/utils/db/error.ts @@ -1,7 +1,7 @@ import { PluginEvent, PostHogEvent, ProcessedPluginEvent } from '@posthog/plugin-scaffold' import { Hub, PluginConfig, PluginError, PluginLogEntrySource, PluginLogEntryType } from '../../types' -import { captureException } from '../posthog' +import { captureException } from '../exceptions' export class DependencyUnavailableError extends Error { constructor(message: string, dependencyName: string, error: Error) { diff --git a/plugin-server/src/utils/db/redis.ts b/plugin-server/src/utils/db/redis.ts index e7f410c901858..57d24ac25a197 100644 --- a/plugin-server/src/utils/db/redis.ts +++ b/plugin-server/src/utils/db/redis.ts @@ -4,7 +4,7 @@ import Redis, { RedisOptions } from 'ioredis' import { PluginsServerConfig, RedisPool } from '../../types' import { status } from '../../utils/status' import { killGracefully } from '../../utils/utils' -import { captureException } from '../posthog' +import { captureException } from '../exceptions' /** Number of Redis error events until the server is killed gracefully. */ const REDIS_ERROR_COUNTER_LIMIT = 10 diff --git a/plugin-server/src/utils/db/utils.ts b/plugin-server/src/utils/db/utils.ts index 6b5a844e6c672..0339a67b8c271 100644 --- a/plugin-server/src/utils/db/utils.ts +++ b/plugin-server/src/utils/db/utils.ts @@ -16,7 +16,7 @@ import { } from '../../types' import { status } from '../../utils/status' import { areMapsEqual, castTimestampOrNow } from '../../utils/utils' -import { captureException } from '../posthog' +import { captureException } from '../exceptions' export function unparsePersonPartial(person: Partial): Partial { return { diff --git a/plugin-server/src/utils/exceptions.ts b/plugin-server/src/utils/exceptions.ts new file mode 100644 index 0000000000000..80bbf793f25b3 --- /dev/null +++ b/plugin-server/src/utils/exceptions.ts @@ -0,0 +1,35 @@ +import { captureException as captureSentryException, captureMessage as captureSentryMessage } from '@sentry/node' +import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' + +import posthog from './posthog' + +// We use sentry-style hints rather than our flat property list all over the place, +// so define a type for them that we can flatten internally +type Primitive = number | string | boolean | bigint | symbol | null | undefined +interface ExceptionHint { + level: SeverityLevel + tags: Record + extra: Record +} + +export function captureException(exception: any, hint?: Partial): string { + //If the passed "exception" is a string, capture it as a message, otherwise, capture it as an exception + let sentryId: string + if (typeof exception === 'string') { + sentryId = captureSentryMessage(exception, hint) + } else { + sentryId = captureSentryException(exception, hint) + } + + let additionalProperties = {} + if (hint) { + additionalProperties = { + ...(hint.level ? { level: hint.level } : {}), + ...(hint.tags || {}), + ...(hint.extra || {}), + } + } + posthog.captureException(exception, additionalProperties) + + return sentryId +} diff --git a/plugin-server/src/utils/posthog.ts b/plugin-server/src/utils/posthog.ts index f954915f253f4..0a510cc189e2c 100644 --- a/plugin-server/src/utils/posthog.ts +++ b/plugin-server/src/utils/posthog.ts @@ -1,6 +1,4 @@ -import { captureException as captureSentryException, captureMessage as captureSentryMessage } from '@sentry/node' import { PostHog } from 'posthog-node' -import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' import { defaultConfig } from '../config/config' import { Team } from '../types' @@ -39,46 +37,19 @@ const captureTeamEvent = ( } } -// We use sentry-style hints rather than our flat property list all over the place, -// so define a type for them that we can flatten internally -type Primitive = number | string | boolean | bigint | symbol | null | undefined -interface ExceptionHint { - level: SeverityLevel - tags: Record - extra: Record +function shutdown(): Promise | null { + return posthog ? posthog.shutdown() : null } -function captureException(exception: any, hint?: Partial): string { - //If the passed "exception" is a string, capture it as a message, otherwise, capture it as an exception - let sentryId: string - if (typeof exception === 'string') { - sentryId = captureSentryMessage(exception, hint) - } else { - sentryId = captureSentryException(exception, hint) - } - +function flush(): void { if (posthog) { - let additionalProperties = {} - if (hint) { - additionalProperties = { - ...(hint.level ? { level: hint.level } : {}), - ...(hint.tags || {}), - ...(hint.extra || {}), - } - } - posthog.captureException(exception, undefined, additionalProperties) + void posthog.flush().catch(() => null) } - - return sentryId } -function shutdown(): Promise | null { - return posthog && posthog.shutdown() -} - -function flush(): void { +function captureException(exception: unknown, additionalProperties?: Record): void { if (posthog) { - void posthog.flush().catch(() => null) + posthog.captureException(exception, undefined, additionalProperties) } } diff --git a/plugin-server/src/utils/pubsub.ts b/plugin-server/src/utils/pubsub.ts index 08699fb866d03..a9802595872b2 100644 --- a/plugin-server/src/utils/pubsub.ts +++ b/plugin-server/src/utils/pubsub.ts @@ -2,7 +2,7 @@ import { Redis } from 'ioredis' import { PluginsServerConfig } from '../types' import { createRedis } from './db/redis' -import { captureException } from './posthog' +import { captureException } from './exceptions' import { status } from './status' export type PubSubTask = ((message: string) => void) | ((message: string) => Promise) diff --git a/plugin-server/src/utils/utils.ts b/plugin-server/src/utils/utils.ts index 3f5965dd90929..4c34f1c96989a 100644 --- a/plugin-server/src/utils/utils.ts +++ b/plugin-server/src/utils/utils.ts @@ -14,7 +14,7 @@ import { PluginsServerConfig, TimestampFormat, } from '../types' -import { captureException } from './posthog' +import { captureException } from './exceptions' import { status } from './status' /** Time until autoexit (due to error) gives up on graceful exit and kills the process right away. */ diff --git a/plugin-server/src/worker/ingestion/action-matcher.ts b/plugin-server/src/worker/ingestion/action-matcher.ts index fc49559b75592..6b0e2e59a373f 100644 --- a/plugin-server/src/worker/ingestion/action-matcher.ts +++ b/plugin-server/src/worker/ingestion/action-matcher.ts @@ -21,7 +21,7 @@ import { import { PostgresRouter, PostgresUse } from '../../utils/db/postgres' import { stringToBoolean } from '../../utils/env-utils' import { mutatePostIngestionEventWithElementsList } from '../../utils/event' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { stringify } from '../../utils/utils' import { ActionManager } from './action-manager' diff --git a/plugin-server/src/worker/ingestion/app-metrics.ts b/plugin-server/src/worker/ingestion/app-metrics.ts index 41b8def3efa89..2048781bb51ce 100644 --- a/plugin-server/src/worker/ingestion/app-metrics.ts +++ b/plugin-server/src/worker/ingestion/app-metrics.ts @@ -6,7 +6,7 @@ import { KAFKA_APP_METRICS } from '../../config/kafka-topics' import { KafkaProducerWrapper } from '../../kafka/producer' import { TeamId, TimestampFormat } from '../../types' import { cleanErrorStackTrace } from '../../utils/db/error' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { status } from '../../utils/status' import { castTimestampOrNow, UUIDT } from '../../utils/utils' diff --git a/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts b/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts index 7863390efba6e..a1e99356000b7 100644 --- a/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts +++ b/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts @@ -2,7 +2,7 @@ import { PluginEvent } from '@posthog/plugin-scaffold' import { PreIngestionEvent } from '~/src/types' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' import { parseEventTimestamp } from '../timestamps' import { captureIngestionWarning } from '../utils' diff --git a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts index e490180b3e77f..54b4df87d6740 100644 --- a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts +++ b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts @@ -8,7 +8,7 @@ import { Hub, PipelineEvent } from '../../../types' import { DependencyUnavailableError } from '../../../utils/db/error' import { timeoutGuard } from '../../../utils/db/utils' import { normalizeProcessPerson } from '../../../utils/event' -import { captureException } from '../../../utils/posthog' +import { captureException } from '../../../utils/exceptions' import { status } from '../../../utils/status' import { EventsProcessor } from '../process-event' import { captureIngestionWarning, generateEventDeadLetterQueueMessage } from '../utils' diff --git a/plugin-server/src/worker/ingestion/hooks.ts b/plugin-server/src/worker/ingestion/hooks.ts index a24b626cb3fae..0b94b0d397acc 100644 --- a/plugin-server/src/worker/ingestion/hooks.ts +++ b/plugin-server/src/worker/ingestion/hooks.ts @@ -4,8 +4,8 @@ import { RustyHook } from 'worker/rusty-hook' import { Action, Hook, HookPayload, PostIngestionEvent, Team } from '../../types' import { PostgresRouter, PostgresUse } from '../../utils/db/postgres' import { convertToHookPayload } from '../../utils/event' +import { captureException } from '../../utils/exceptions' import { trackedFetch } from '../../utils/fetch' -import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { AppMetric, AppMetrics } from './app-metrics' import { OrganizationManager } from './organization-manager' diff --git a/plugin-server/src/worker/ingestion/person-state.ts b/plugin-server/src/worker/ingestion/person-state.ts index 1dbd1306de008..6276f250248f4 100644 --- a/plugin-server/src/worker/ingestion/person-state.ts +++ b/plugin-server/src/worker/ingestion/person-state.ts @@ -9,7 +9,7 @@ import { InternalPerson, Person, PropertyUpdateOperation } from '../../types' import { DB } from '../../utils/db/db' import { PostgresUse, TransactionClient } from '../../utils/db/postgres' import { eventToPersonProperties, initialEventToPersonProperties, timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { promiseRetry } from '../../utils/retries' import { status } from '../../utils/status' import { uuidFromDistinctId } from './person-uuid' diff --git a/plugin-server/src/worker/ingestion/process-event.ts b/plugin-server/src/worker/ingestion/process-event.ts index ae145ec72095e..effe40d0858ce 100644 --- a/plugin-server/src/worker/ingestion/process-event.ts +++ b/plugin-server/src/worker/ingestion/process-event.ts @@ -22,7 +22,7 @@ import { DB, GroupId } from '../../utils/db/db' import { elementsToString, extractElements } from '../../utils/db/elements-chain' import { MessageSizeTooLarge } from '../../utils/db/error' import { safeClickhouseString, sanitizeEventName, timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { status } from '../../utils/status' import { castTimestampOrNow } from '../../utils/utils' import { GroupTypeManager, MAX_GROUP_TYPES_PER_TEAM } from './group-type-manager' diff --git a/plugin-server/src/worker/ingestion/timestamps.ts b/plugin-server/src/worker/ingestion/timestamps.ts index 6c6a55a9dc163..f3a9fb49e14ec 100644 --- a/plugin-server/src/worker/ingestion/timestamps.ts +++ b/plugin-server/src/worker/ingestion/timestamps.ts @@ -1,7 +1,7 @@ import { PluginEvent } from '@posthog/plugin-scaffold' import { DateTime, Duration } from 'luxon' -import { captureException } from '../../utils/posthog' +import { captureException } from '../../utils/exceptions' import { status } from '../../utils/status' type IngestionWarningCallback = (type: string, details: Record) => void diff --git a/plugin-server/src/worker/piscina.ts b/plugin-server/src/worker/piscina.ts index 06e502156828c..c69b5b5035ae4 100644 --- a/plugin-server/src/worker/piscina.ts +++ b/plugin-server/src/worker/piscina.ts @@ -1,6 +1,6 @@ import { Hub, PluginsServerConfig } from '~/src/types' -import { captureException } from '../utils/posthog' +import { captureException } from '../utils/exceptions' import { createWorker } from './worker' export const makePiscina = async (serverConfig: PluginsServerConfig, hub: Hub) => { diff --git a/plugin-server/src/worker/rusty-hook.ts b/plugin-server/src/worker/rusty-hook.ts index 10e266aa0f155..ade87a8f2121f 100644 --- a/plugin-server/src/worker/rusty-hook.ts +++ b/plugin-server/src/worker/rusty-hook.ts @@ -4,8 +4,8 @@ import fetch from 'node-fetch' import { buildIntegerMatcher } from '../config/config' import { PluginsServerConfig, ValueMatcher } from '../types' import { isProdEnv } from '../utils/env-utils' +import { captureException } from '../utils/exceptions' import { raiseIfUserProvidedUrlUnsafe } from '../utils/fetch' -import { captureException } from '../utils/posthog' import { status } from '../utils/status' import { sleep } from '../utils/utils' import { pluginActionMsSummary } from './metrics' diff --git a/plugin-server/src/worker/worker.ts b/plugin-server/src/worker/worker.ts index f1be9adc0d410..c4b6dc8e078d2 100644 --- a/plugin-server/src/worker/worker.ts +++ b/plugin-server/src/worker/worker.ts @@ -4,7 +4,7 @@ import { initApp } from '../init' import { runInTransaction } from '../sentry' import { Hub, PluginConfig, PluginsServerConfig } from '../types' import { processError } from '../utils/db/error' -import { captureException } from '../utils/posthog' +import { captureException } from '../utils/exceptions' import { status } from '../utils/status' import { cloneObject, pluginConfigIdFromStack } from '../utils/utils' import { setupMmdb } from './plugins/mmdb' From 2a649da94a1a8b7ec620185674e3b5014591f076 Mon Sep 17 00:00:00 2001 From: David Newell Date: Thu, 27 Feb 2025 16:37:15 +0000 Subject: [PATCH 06/12] simplify setup --- plugin-server/src/cdp/redis.ts | 4 +- .../services/hog-function-manager.service.ts | 2 +- plugin-server/src/cdp/utils.ts | 2 +- .../src/ingestion/ingestion-consumer.ts | 2 +- .../main/graphile-worker/graphile-worker.ts | 2 +- .../batch-processing/each-batch-ingestion.ts | 2 +- .../src/main/ingestion-queues/kafka-queue.ts | 2 +- .../session-recording-v2/consumer.ts | 2 +- .../session-recording-v2/utils.ts | 2 +- .../session-recording/process-event.ts | 2 +- .../services/console-logs-ingester.ts | 2 +- .../services/offset-high-water-marker.ts | 2 +- .../services/realtime-manager.ts | 2 +- .../services/replay-events-ingester.ts | 2 +- .../services/session-manager.ts | 2 +- .../session-recordings-consumer.ts | 2 +- .../session-recording/utils.ts | 2 +- plugin-server/src/main/pluginsServer.ts | 8 ++-- plugin-server/src/main/utils.ts | 2 +- plugin-server/src/utils/db/db.ts | 2 +- plugin-server/src/utils/db/elements-chain.ts | 2 +- plugin-server/src/utils/db/error.ts | 2 +- plugin-server/src/utils/db/redis.ts | 2 +- plugin-server/src/utils/db/utils.ts | 2 +- plugin-server/src/utils/exceptions.ts | 35 --------------- plugin-server/src/utils/posthog.ts | 44 ++++++++++++++----- .../src/worker/ingestion/action-matcher.ts | 2 +- .../src/worker/ingestion/app-metrics.ts | 2 +- .../event-pipeline/prepareEventStep.ts | 2 +- .../worker/ingestion/event-pipeline/runner.ts | 2 +- plugin-server/src/worker/ingestion/hooks.ts | 2 +- .../src/worker/ingestion/person-state.ts | 2 +- .../src/worker/ingestion/process-event.ts | 2 +- .../src/worker/ingestion/timestamps.ts | 2 +- plugin-server/src/worker/piscina.ts | 2 +- plugin-server/src/worker/rusty-hook.ts | 2 +- plugin-server/src/worker/worker.ts | 2 +- .../tests/main/process-event.test.ts | 10 +++-- .../worker/ingestion/team-manager.test.ts | 6 --- 39 files changed, 78 insertions(+), 95 deletions(-) delete mode 100644 plugin-server/src/utils/exceptions.ts diff --git a/plugin-server/src/cdp/redis.ts b/plugin-server/src/cdp/redis.ts index b6b73b966953b..c6fabde7ac114 100644 --- a/plugin-server/src/cdp/redis.ts +++ b/plugin-server/src/cdp/redis.ts @@ -6,7 +6,7 @@ import { Pipeline, Redis } from 'ioredis' import { PluginsServerConfig } from '../types' import { createRedisClient } from '../utils/db/redis' import { timeoutGuard } from '../utils/db/utils' -import posthog from '../utils/posthog' +import { captureException } from '../utils/posthog' import { status } from '../utils/status' type WithCheckRateLimit = { @@ -126,7 +126,7 @@ export const createCdpRedisPool = (config: PluginsServerConfig): CdpRedis => { } catch (e) { if (options.failOpen) { // We log the error and return null - posthog.captureException(e) + captureException(e) status.error(`Redis call${options.name} failed`, e) return null } diff --git a/plugin-server/src/cdp/services/hog-function-manager.service.ts b/plugin-server/src/cdp/services/hog-function-manager.service.ts index 3c603343855ab..fa9aaa8a4087b 100644 --- a/plugin-server/src/cdp/services/hog-function-manager.service.ts +++ b/plugin-server/src/cdp/services/hog-function-manager.service.ts @@ -2,7 +2,7 @@ import * as schedule from 'node-schedule' import { Hub, Team } from '../../types' import { PostgresUse } from '../../utils/db/postgres' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { PubSub } from '../../utils/pubsub' import { status } from '../../utils/status' import { HogFunctionType, HogFunctionTypeType, IntegrationType } from '../types' diff --git a/plugin-server/src/cdp/utils.ts b/plugin-server/src/cdp/utils.ts index b719dcf6349e8..6e9205856338a 100644 --- a/plugin-server/src/cdp/utils.ts +++ b/plugin-server/src/cdp/utils.ts @@ -8,7 +8,7 @@ import { gunzip, gzip } from 'zlib' import { RawClickHouseEvent, Team, TimestampFormat } from '../types' import { safeClickhouseString } from '../utils/db/utils' -import { captureException } from '../utils/exceptions' +import { captureException } from '../utils/posthog' import { status } from '../utils/status' import { castTimestampOrNow, clickHouseTimestampToISO, UUIDT } from '../utils/utils' import { CdpInternalEvent } from './schema' diff --git a/plugin-server/src/ingestion/ingestion-consumer.ts b/plugin-server/src/ingestion/ingestion-consumer.ts index bbc3aaf20937b..464790f82618e 100644 --- a/plugin-server/src/ingestion/ingestion-consumer.ts +++ b/plugin-server/src/ingestion/ingestion-consumer.ts @@ -17,7 +17,7 @@ import { import { runInstrumentedFunction } from '../main/utils' import { Hub, PipelineEvent, PluginServerService } from '../types' import { normalizeEvent } from '../utils/event' -import { captureException } from '../utils/exceptions' +import { captureException } from '../utils/posthog' import { retryIfRetriable } from '../utils/retries' import { status } from '../utils/status' import { EventPipelineResult, EventPipelineRunner } from '../worker/ingestion/event-pipeline/runner' diff --git a/plugin-server/src/main/graphile-worker/graphile-worker.ts b/plugin-server/src/main/graphile-worker/graphile-worker.ts index b88a351775e78..9994549396f46 100644 --- a/plugin-server/src/main/graphile-worker/graphile-worker.ts +++ b/plugin-server/src/main/graphile-worker/graphile-worker.ts @@ -11,8 +11,8 @@ import { import { Pool } from 'pg' import { EnqueuedJob, Hub } from '../../types' -import { captureException } from '../../utils/exceptions' import { instrument } from '../../utils/metrics' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { createPostgresPool } from '../../utils/utils' import { graphileEnqueueJobCounter } from './metrics' diff --git a/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts b/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts index a9e3335c2eb76..393872a88dbd7 100644 --- a/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts +++ b/plugin-server/src/main/ingestion-queues/batch-processing/each-batch-ingestion.ts @@ -4,7 +4,7 @@ import { Message, MessageHeader } from 'node-rdkafka' import { KAFKA_EVENTS_PLUGIN_INGESTION_DLQ, KAFKA_EVENTS_PLUGIN_INGESTION_OVERFLOW } from '../../../config/kafka-topics' import { PipelineEvent, ValueMatcher } from '../../../types' import { formPipelineEvent } from '../../../utils/event' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { retryIfRetriable } from '../../../utils/retries' import { status } from '../../../utils/status' import { ConfiguredLimiter, LoggingLimiter } from '../../../utils/token-bucket' diff --git a/plugin-server/src/main/ingestion-queues/kafka-queue.ts b/plugin-server/src/main/ingestion-queues/kafka-queue.ts index 0ecdd4273941c..d38e87be6dae4 100644 --- a/plugin-server/src/main/ingestion-queues/kafka-queue.ts +++ b/plugin-server/src/main/ingestion-queues/kafka-queue.ts @@ -6,7 +6,7 @@ import { BatchConsumer, startBatchConsumer } from '../../kafka/batch-consumer' import { createRdConnectionConfigFromEnvVars } from '../../kafka/config' import { Hub } from '../../types' import { timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { killGracefully } from '../../utils/utils' import { EventsProcessor } from '../../worker/ingestion/process-event' diff --git a/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts b/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts index c45b4891873dc..f0b360990ceab 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording-v2/consumer.ts @@ -15,7 +15,7 @@ import { PostgresRouter } from '~/src/utils/db/postgres' import { buildIntegerMatcher } from '../../../config/config' import { BatchConsumer } from '../../../kafka/batch-consumer' import { PluginServerService, PluginsServerConfig, ValueMatcher } from '../../../types' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status as logger } from '../../../utils/status' import { captureIngestionWarning } from '../../../worker/ingestion/utils' import { runInstrumentedFunction } from '../../utils' diff --git a/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts b/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts index 1510258bf28cc..e35e3da3d6c44 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording-v2/utils.ts @@ -1,6 +1,6 @@ import { KafkaConsumer, PartitionMetadata } from 'node-rdkafka' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' export const getPartitionsForTopic = ( diff --git a/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts b/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts index 3ef81cb6bffc3..32167a9b28917 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/process-event.ts @@ -1,7 +1,7 @@ import { DateTime } from 'luxon' import { ClickHouseTimestamp, RRWebEvent, TimestampFormat } from '../../../types' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' import { castTimestampOrNow } from '../../../utils/utils' import { activeMilliseconds } from './snapshot-segmenter' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts index 93f43e3cf4102..646dd28e64d63 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/console-logs-ingester.ts @@ -4,7 +4,7 @@ import { KAFKA_LOG_ENTRIES } from '../../../../config/kafka-topics' import { findOffsetsToCommit } from '../../../../kafka/consumer' import { retryOnDependencyUnavailableError } from '../../../../kafka/error-handling' import { KafkaProducerWrapper } from '../../../../kafka/producer' -import { captureException } from '../../../../utils/exceptions' +import { captureException } from '../../../../utils/posthog' import { status } from '../../../../utils/status' import { eventDroppedCounter } from '../../metrics' import { ConsoleLogEntry, gatherConsoleLogEvents, RRWebEventType } from '../process-event' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts index 9c26b73588b74..a313272539a2b 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/offset-high-water-marker.ts @@ -3,7 +3,7 @@ import { TopicPartition } from 'node-rdkafka' import { RedisPool } from '../../../../types' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/exceptions' +import { captureException } from '../../../../utils/posthog' import { status } from '../../../../utils/status' export const offsetHighWaterMarkKey = (prefix: string, tp: TopicPartition) => { diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts index da5bdbee5fa38..50b7b8b29012b 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/realtime-manager.ts @@ -5,7 +5,7 @@ import { EventEmitter } from 'node:events' import { PluginsServerConfig, RedisPool } from '../../../../types' import { createRedis } from '../../../../utils/db/redis' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/exceptions' +import { captureException } from '../../../../utils/posthog' import { status } from '../../../../utils/status' const Keys = { diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts index 6f817ce74b5ed..609c0fe2184fc 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/replay-events-ingester.ts @@ -6,7 +6,7 @@ import { KAFKA_CLICKHOUSE_SESSION_REPLAY_EVENTS } from '../../../../config/kafka import { findOffsetsToCommit } from '../../../../kafka/consumer' import { retryOnDependencyUnavailableError } from '../../../../kafka/error-handling' import { KafkaProducerWrapper } from '../../../../kafka/producer' -import { captureException } from '../../../../utils/exceptions' +import { captureException } from '../../../../utils/posthog' import { status } from '../../../../utils/status' import { captureIngestionWarning } from '../../../../worker/ingestion/utils' import { eventDroppedCounter } from '../../metrics' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts b/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts index 4e04d9a639a41..08cd5b91b49a4 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/services/session-manager.ts @@ -12,7 +12,7 @@ import * as zlib from 'zlib' import { PluginsServerConfig } from '../../../../types' import { timeoutGuard } from '../../../../utils/db/utils' -import { captureException } from '../../../../utils/exceptions' +import { captureException } from '../../../../utils/posthog' import { status } from '../../../../utils/status' import { asyncTimeoutGuard } from '../../../../utils/timing' import { ObjectStorage } from '../../../services/object_storage' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts index 1feb4cdcbd667..99237380f09e1 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/session-recordings-consumer.ts @@ -16,7 +16,7 @@ import { PluginServerService, PluginsServerConfig, RedisPool, TeamId, ValueMatch import { BackgroundRefresher } from '../../../utils/background-refresher' import { PostgresRouter } from '../../../utils/db/postgres' import { createRedisPool } from '../../../utils/db/redis' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' import { fetchTeamTokensWithRecordings } from '../../../worker/ingestion/team-manager' import { ObjectStorage } from '../../services/object_storage' diff --git a/plugin-server/src/main/ingestion-queues/session-recording/utils.ts b/plugin-server/src/main/ingestion-queues/session-recording/utils.ts index 6b7e6abf91ae2..9905f24b24afd 100644 --- a/plugin-server/src/main/ingestion-queues/session-recording/utils.ts +++ b/plugin-server/src/main/ingestion-queues/session-recording/utils.ts @@ -5,7 +5,7 @@ import { Counter } from 'prom-client' import { KafkaProducerWrapper } from '../../../kafka/producer' import { PipelineEvent, RawEventMessage, RRWebEvent } from '../../../types' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' import { captureIngestionWarning } from '../../../worker/ingestion/utils' import { eventDroppedCounter } from '../metrics' diff --git a/plugin-server/src/main/pluginsServer.ts b/plugin-server/src/main/pluginsServer.ts index 59d8027f5c4fa..122bd9fa1fb92 100644 --- a/plugin-server/src/main/pluginsServer.ts +++ b/plugin-server/src/main/pluginsServer.ts @@ -26,9 +26,9 @@ import { Hub, PluginServerCapabilities, PluginServerService, PluginsServerConfig import { closeHub, createHub, createKafkaClient } from '../utils/db/hub' import { PostgresRouter } from '../utils/db/postgres' import { createRedisClient } from '../utils/db/redis' -import { captureException } from '../utils/exceptions' import { cancelAllScheduledJobs } from '../utils/node-schedule' -import posthog from '../utils/posthog' +import { captureException } from '../utils/posthog' +import { flush as posthogFlush, shutdown as posthogShutdown } from '../utils/posthog' import { PubSub } from '../utils/pubsub' import { status } from '../utils/status' import { delay } from '../utils/utils' @@ -133,7 +133,7 @@ export async function startPluginsServer( pubSub?.stop(), graphileWorker?.stop(), ...services.map((service) => service.onShutdown()), - posthog.shutdown(), + posthogShutdown(), ]) if (serverInstance.hub) { @@ -611,7 +611,7 @@ export async function startPluginsServer( captureException(error) status.error('💥', 'Launchpad failure!', { error: error.stack ?? error }) void Sentry.flush().catch(() => null) // Flush Sentry in the background - posthog.flush() + posthogFlush() status.error('💥', 'Exception while starting server, shutting down!', { error }) await closeJobs() process.exit(1) diff --git a/plugin-server/src/main/utils.ts b/plugin-server/src/main/utils.ts index 5ec6421504568..a5f7008d8ae11 100644 --- a/plugin-server/src/main/utils.ts +++ b/plugin-server/src/main/utils.ts @@ -1,7 +1,7 @@ import { exponentialBuckets, Histogram } from 'prom-client' import { timeoutGuard } from '../utils/db/utils' -import { captureException } from '../utils/exceptions' +import { captureException } from '../utils/posthog' import { status } from '../utils/status' interface FunctionInstrumentation { diff --git a/plugin-server/src/utils/db/db.ts b/plugin-server/src/utils/db/db.ts index 1fdde33b0a2bf..4304acca7ce07 100644 --- a/plugin-server/src/utils/db/db.ts +++ b/plugin-server/src/utils/db/db.ts @@ -49,8 +49,8 @@ import { fetchAction, fetchAllActionsGroupedByTeam } from '../../worker/ingestio import { fetchOrganization } from '../../worker/ingestion/organization-manager' import { fetchTeam, fetchTeamByToken } from '../../worker/ingestion/team-manager' import { parseRawClickHouseEvent } from '../event' -import { captureException } from '../exceptions' import { instrumentQuery } from '../metrics' +import { captureException } from '../posthog' import { status } from '../status' import { castTimestampOrNow, diff --git a/plugin-server/src/utils/db/elements-chain.ts b/plugin-server/src/utils/db/elements-chain.ts index 1fd393c57453e..8be7488a5aec2 100644 --- a/plugin-server/src/utils/db/elements-chain.ts +++ b/plugin-server/src/utils/db/elements-chain.ts @@ -1,7 +1,7 @@ import RE2 from 're2' import { Element } from '../../types' -import { captureException } from '../exceptions' +import { captureException } from '../posthog' import { escapeQuotes } from './utils' // Below splits all elements by ;, while ignoring escaped quotes and semicolons within quotes diff --git a/plugin-server/src/utils/db/error.ts b/plugin-server/src/utils/db/error.ts index 0d872ff97e80c..5e922383cf8c5 100644 --- a/plugin-server/src/utils/db/error.ts +++ b/plugin-server/src/utils/db/error.ts @@ -1,7 +1,7 @@ import { PluginEvent, PostHogEvent, ProcessedPluginEvent } from '@posthog/plugin-scaffold' import { Hub, PluginConfig, PluginError, PluginLogEntrySource, PluginLogEntryType } from '../../types' -import { captureException } from '../exceptions' +import { captureException } from '../posthog' export class DependencyUnavailableError extends Error { constructor(message: string, dependencyName: string, error: Error) { diff --git a/plugin-server/src/utils/db/redis.ts b/plugin-server/src/utils/db/redis.ts index 57d24ac25a197..e7f410c901858 100644 --- a/plugin-server/src/utils/db/redis.ts +++ b/plugin-server/src/utils/db/redis.ts @@ -4,7 +4,7 @@ import Redis, { RedisOptions } from 'ioredis' import { PluginsServerConfig, RedisPool } from '../../types' import { status } from '../../utils/status' import { killGracefully } from '../../utils/utils' -import { captureException } from '../exceptions' +import { captureException } from '../posthog' /** Number of Redis error events until the server is killed gracefully. */ const REDIS_ERROR_COUNTER_LIMIT = 10 diff --git a/plugin-server/src/utils/db/utils.ts b/plugin-server/src/utils/db/utils.ts index 0339a67b8c271..6b5a844e6c672 100644 --- a/plugin-server/src/utils/db/utils.ts +++ b/plugin-server/src/utils/db/utils.ts @@ -16,7 +16,7 @@ import { } from '../../types' import { status } from '../../utils/status' import { areMapsEqual, castTimestampOrNow } from '../../utils/utils' -import { captureException } from '../exceptions' +import { captureException } from '../posthog' export function unparsePersonPartial(person: Partial): Partial { return { diff --git a/plugin-server/src/utils/exceptions.ts b/plugin-server/src/utils/exceptions.ts deleted file mode 100644 index 80bbf793f25b3..0000000000000 --- a/plugin-server/src/utils/exceptions.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { captureException as captureSentryException, captureMessage as captureSentryMessage } from '@sentry/node' -import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' - -import posthog from './posthog' - -// We use sentry-style hints rather than our flat property list all over the place, -// so define a type for them that we can flatten internally -type Primitive = number | string | boolean | bigint | symbol | null | undefined -interface ExceptionHint { - level: SeverityLevel - tags: Record - extra: Record -} - -export function captureException(exception: any, hint?: Partial): string { - //If the passed "exception" is a string, capture it as a message, otherwise, capture it as an exception - let sentryId: string - if (typeof exception === 'string') { - sentryId = captureSentryMessage(exception, hint) - } else { - sentryId = captureSentryException(exception, hint) - } - - let additionalProperties = {} - if (hint) { - additionalProperties = { - ...(hint.level ? { level: hint.level } : {}), - ...(hint.tags || {}), - ...(hint.extra || {}), - } - } - posthog.captureException(exception, additionalProperties) - - return sentryId -} diff --git a/plugin-server/src/utils/posthog.ts b/plugin-server/src/utils/posthog.ts index 0a510cc189e2c..4d47bf0e9d242 100644 --- a/plugin-server/src/utils/posthog.ts +++ b/plugin-server/src/utils/posthog.ts @@ -1,4 +1,6 @@ +import { captureException as captureSentryException, captureMessage as captureSentryMessage } from '@sentry/node' import { PostHog } from 'posthog-node' +import { SeverityLevel } from 'posthog-node/src/extensions/error-tracking/types' import { defaultConfig } from '../config/config' import { Team } from '../types' @@ -14,12 +16,12 @@ if (process.env.NODE_ENV === 'test' && posthog) { void posthog.disable() } -const captureTeamEvent = ( +export function captureTeamEvent( team: Team, event: string, properties: Record = {}, distinctId: string | null = null -): void => { +): void { if (posthog) { posthog.capture({ distinctId: distinctId ?? team.uuid, @@ -37,25 +39,45 @@ const captureTeamEvent = ( } } -function shutdown(): Promise | null { +export function shutdown(): Promise | null { return posthog ? posthog.shutdown() : null } -function flush(): void { +export function flush(): void { if (posthog) { void posthog.flush().catch(() => null) } } -function captureException(exception: unknown, additionalProperties?: Record): void { +// We use sentry-style hints rather than our flat property list all over the place, +// so define a type for them that we can flatten internally +type Primitive = number | string | boolean | bigint | symbol | null | undefined +interface ExceptionHint { + level: SeverityLevel + tags: Record + extra: Record +} + +export function captureException(exception: any, hint?: Partial): string { + //If the passed "exception" is a string, capture it as a message, otherwise, capture it as an exception + let sentryId: string + if (typeof exception === 'string') { + sentryId = captureSentryMessage(exception, hint) + } else { + sentryId = captureSentryException(exception, hint) + } + if (posthog) { + let additionalProperties = {} + if (hint) { + additionalProperties = { + ...(hint.level ? { level: hint.level } : {}), + ...(hint.tags || {}), + ...(hint.extra || {}), + } + } posthog.captureException(exception, undefined, additionalProperties) } -} -export default { - flush, - shutdown, - captureException, - captureTeamEvent, + return sentryId } diff --git a/plugin-server/src/worker/ingestion/action-matcher.ts b/plugin-server/src/worker/ingestion/action-matcher.ts index 6b0e2e59a373f..fc49559b75592 100644 --- a/plugin-server/src/worker/ingestion/action-matcher.ts +++ b/plugin-server/src/worker/ingestion/action-matcher.ts @@ -21,7 +21,7 @@ import { import { PostgresRouter, PostgresUse } from '../../utils/db/postgres' import { stringToBoolean } from '../../utils/env-utils' import { mutatePostIngestionEventWithElementsList } from '../../utils/event' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { stringify } from '../../utils/utils' import { ActionManager } from './action-manager' diff --git a/plugin-server/src/worker/ingestion/app-metrics.ts b/plugin-server/src/worker/ingestion/app-metrics.ts index 2048781bb51ce..41b8def3efa89 100644 --- a/plugin-server/src/worker/ingestion/app-metrics.ts +++ b/plugin-server/src/worker/ingestion/app-metrics.ts @@ -6,7 +6,7 @@ import { KAFKA_APP_METRICS } from '../../config/kafka-topics' import { KafkaProducerWrapper } from '../../kafka/producer' import { TeamId, TimestampFormat } from '../../types' import { cleanErrorStackTrace } from '../../utils/db/error' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { castTimestampOrNow, UUIDT } from '../../utils/utils' diff --git a/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts b/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts index a1e99356000b7..7863390efba6e 100644 --- a/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts +++ b/plugin-server/src/worker/ingestion/event-pipeline/prepareEventStep.ts @@ -2,7 +2,7 @@ import { PluginEvent } from '@posthog/plugin-scaffold' import { PreIngestionEvent } from '~/src/types' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' import { parseEventTimestamp } from '../timestamps' import { captureIngestionWarning } from '../utils' diff --git a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts index 54b4df87d6740..e490180b3e77f 100644 --- a/plugin-server/src/worker/ingestion/event-pipeline/runner.ts +++ b/plugin-server/src/worker/ingestion/event-pipeline/runner.ts @@ -8,7 +8,7 @@ import { Hub, PipelineEvent } from '../../../types' import { DependencyUnavailableError } from '../../../utils/db/error' import { timeoutGuard } from '../../../utils/db/utils' import { normalizeProcessPerson } from '../../../utils/event' -import { captureException } from '../../../utils/exceptions' +import { captureException } from '../../../utils/posthog' import { status } from '../../../utils/status' import { EventsProcessor } from '../process-event' import { captureIngestionWarning, generateEventDeadLetterQueueMessage } from '../utils' diff --git a/plugin-server/src/worker/ingestion/hooks.ts b/plugin-server/src/worker/ingestion/hooks.ts index 0b94b0d397acc..a24b626cb3fae 100644 --- a/plugin-server/src/worker/ingestion/hooks.ts +++ b/plugin-server/src/worker/ingestion/hooks.ts @@ -4,8 +4,8 @@ import { RustyHook } from 'worker/rusty-hook' import { Action, Hook, HookPayload, PostIngestionEvent, Team } from '../../types' import { PostgresRouter, PostgresUse } from '../../utils/db/postgres' import { convertToHookPayload } from '../../utils/event' -import { captureException } from '../../utils/exceptions' import { trackedFetch } from '../../utils/fetch' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { AppMetric, AppMetrics } from './app-metrics' import { OrganizationManager } from './organization-manager' diff --git a/plugin-server/src/worker/ingestion/person-state.ts b/plugin-server/src/worker/ingestion/person-state.ts index 6276f250248f4..1dbd1306de008 100644 --- a/plugin-server/src/worker/ingestion/person-state.ts +++ b/plugin-server/src/worker/ingestion/person-state.ts @@ -9,7 +9,7 @@ import { InternalPerson, Person, PropertyUpdateOperation } from '../../types' import { DB } from '../../utils/db/db' import { PostgresUse, TransactionClient } from '../../utils/db/postgres' import { eventToPersonProperties, initialEventToPersonProperties, timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { promiseRetry } from '../../utils/retries' import { status } from '../../utils/status' import { uuidFromDistinctId } from './person-uuid' diff --git a/plugin-server/src/worker/ingestion/process-event.ts b/plugin-server/src/worker/ingestion/process-event.ts index effe40d0858ce..ae145ec72095e 100644 --- a/plugin-server/src/worker/ingestion/process-event.ts +++ b/plugin-server/src/worker/ingestion/process-event.ts @@ -22,7 +22,7 @@ import { DB, GroupId } from '../../utils/db/db' import { elementsToString, extractElements } from '../../utils/db/elements-chain' import { MessageSizeTooLarge } from '../../utils/db/error' import { safeClickhouseString, sanitizeEventName, timeoutGuard } from '../../utils/db/utils' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' import { castTimestampOrNow } from '../../utils/utils' import { GroupTypeManager, MAX_GROUP_TYPES_PER_TEAM } from './group-type-manager' diff --git a/plugin-server/src/worker/ingestion/timestamps.ts b/plugin-server/src/worker/ingestion/timestamps.ts index f3a9fb49e14ec..6c6a55a9dc163 100644 --- a/plugin-server/src/worker/ingestion/timestamps.ts +++ b/plugin-server/src/worker/ingestion/timestamps.ts @@ -1,7 +1,7 @@ import { PluginEvent } from '@posthog/plugin-scaffold' import { DateTime, Duration } from 'luxon' -import { captureException } from '../../utils/exceptions' +import { captureException } from '../../utils/posthog' import { status } from '../../utils/status' type IngestionWarningCallback = (type: string, details: Record) => void diff --git a/plugin-server/src/worker/piscina.ts b/plugin-server/src/worker/piscina.ts index c69b5b5035ae4..06e502156828c 100644 --- a/plugin-server/src/worker/piscina.ts +++ b/plugin-server/src/worker/piscina.ts @@ -1,6 +1,6 @@ import { Hub, PluginsServerConfig } from '~/src/types' -import { captureException } from '../utils/exceptions' +import { captureException } from '../utils/posthog' import { createWorker } from './worker' export const makePiscina = async (serverConfig: PluginsServerConfig, hub: Hub) => { diff --git a/plugin-server/src/worker/rusty-hook.ts b/plugin-server/src/worker/rusty-hook.ts index ade87a8f2121f..10e266aa0f155 100644 --- a/plugin-server/src/worker/rusty-hook.ts +++ b/plugin-server/src/worker/rusty-hook.ts @@ -4,8 +4,8 @@ import fetch from 'node-fetch' import { buildIntegerMatcher } from '../config/config' import { PluginsServerConfig, ValueMatcher } from '../types' import { isProdEnv } from '../utils/env-utils' -import { captureException } from '../utils/exceptions' import { raiseIfUserProvidedUrlUnsafe } from '../utils/fetch' +import { captureException } from '../utils/posthog' import { status } from '../utils/status' import { sleep } from '../utils/utils' import { pluginActionMsSummary } from './metrics' diff --git a/plugin-server/src/worker/worker.ts b/plugin-server/src/worker/worker.ts index c4b6dc8e078d2..f1be9adc0d410 100644 --- a/plugin-server/src/worker/worker.ts +++ b/plugin-server/src/worker/worker.ts @@ -4,7 +4,7 @@ import { initApp } from '../init' import { runInTransaction } from '../sentry' import { Hub, PluginConfig, PluginsServerConfig } from '../types' import { processError } from '../utils/db/error' -import { captureException } from '../utils/exceptions' +import { captureException } from '../utils/posthog' import { status } from '../utils/status' import { cloneObject, pluginConfigIdFromStack } from '../utils/utils' import { setupMmdb } from './plugins/mmdb' diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index b4f78b5d03b49..ea993ddaa8764 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -10,6 +10,8 @@ import { PluginEvent } from '@posthog/plugin-scaffold/src/types' import * as IORedis from 'ioredis' import { DateTime } from 'luxon' +import { captureTeamEvent } from '~/src/utils/posthog' + import { KAFKA_EVENTS_PLUGIN_INGESTION } from '../../src/config/kafka-topics' import { ClickHouseEvent, @@ -24,7 +26,6 @@ import { import { closeHub, createHub } from '../../src/utils/db/hub' import { PostgresUse } from '../../src/utils/db/postgres' import { personInitialAndUTMProperties } from '../../src/utils/db/utils' -import posthog from '../../src/utils/posthog' import { UUIDT } from '../../src/utils/utils' import { EventPipelineRunner } from '../../src/worker/ingestion/event-pipeline/runner' import { EventsProcessor } from '../../src/worker/ingestion/process-event' @@ -34,6 +35,9 @@ import { createUserTeamAndOrganization, getFirstTeam, getTeams, resetTestDatabas jest.mock('../../src/utils/status') jest.setTimeout(600000) // 600 sec timeout. +jest.mock('../../../src/utils/posthog', () => ({ + captureTeamEvent: jest.fn(), +})) export async function createPerson( server: Hub, @@ -871,8 +875,6 @@ test('long htext', async () => { }) test('capture first team event', async () => { - const captureTeamEventMock = jest.spyOn(posthog, 'captureTeamEvent') - await hub.db.postgres.query( PostgresUse.COMMON_WRITE, `UPDATE posthog_team @@ -899,7 +901,7 @@ test('capture first team event', async () => { new UUIDT().toString() ) - expect(captureTeamEventMock).toHaveBeenCalledWith({ + expect(captureTeamEvent).toHaveBeenCalledWith({ distinctId: 'plugin_test_user_distinct_id_1001', event: 'first team event ingested', properties: { diff --git a/plugin-server/tests/worker/ingestion/team-manager.test.ts b/plugin-server/tests/worker/ingestion/team-manager.test.ts index 40d65c06b3bf7..a201dfdf63b15 100644 --- a/plugin-server/tests/worker/ingestion/team-manager.test.ts +++ b/plugin-server/tests/worker/ingestion/team-manager.test.ts @@ -6,12 +6,6 @@ import { TeamManager } from '../../../src/worker/ingestion/team-manager' import { resetTestDatabase } from '../../helpers/sql' jest.mock('../../../src/utils/status') -jest.mock('../../../src/utils/posthog', () => ({ - posthog: { - identify: jest.fn(), - capture: jest.fn(), - }, -})) describe('TeamManager()', () => { let teamManager: TeamManager From e60129b8578c7f241340d203b9d47a1c1eb95db9 Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 10:21:45 +0000 Subject: [PATCH 07/12] imports --- plugin-server/src/utils/pubsub.ts | 2 +- plugin-server/src/utils/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-server/src/utils/pubsub.ts b/plugin-server/src/utils/pubsub.ts index a9802595872b2..08699fb866d03 100644 --- a/plugin-server/src/utils/pubsub.ts +++ b/plugin-server/src/utils/pubsub.ts @@ -2,7 +2,7 @@ import { Redis } from 'ioredis' import { PluginsServerConfig } from '../types' import { createRedis } from './db/redis' -import { captureException } from './exceptions' +import { captureException } from './posthog' import { status } from './status' export type PubSubTask = ((message: string) => void) | ((message: string) => Promise) diff --git a/plugin-server/src/utils/utils.ts b/plugin-server/src/utils/utils.ts index 4c34f1c96989a..3f5965dd90929 100644 --- a/plugin-server/src/utils/utils.ts +++ b/plugin-server/src/utils/utils.ts @@ -14,7 +14,7 @@ import { PluginsServerConfig, TimestampFormat, } from '../types' -import { captureException } from './exceptions' +import { captureException } from './posthog' import { status } from './status' /** Time until autoexit (due to error) gives up on graceful exit and kills the process right away. */ From 0ea4b7055f71f22520112b9adc72b21cb4bdc69e Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 10:44:36 +0000 Subject: [PATCH 08/12] comment --- plugin-server/src/config/config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin-server/src/config/config.ts b/plugin-server/src/config/config.ts index 01d326ec63155..fbe23cb5e8473 100644 --- a/plugin-server/src/config/config.ts +++ b/plugin-server/src/config/config.ts @@ -141,6 +141,8 @@ export function getDefaultConfig(): PluginsServerConfig { RUSTY_HOOK_URL: '', HOG_HOOK_URL: '', CAPTURE_CONFIG_REDIS_HOST: null, + + // posthog POSTHOG_API_KEY: '', POSTHOG_HOST_URL: 'http://localhost:8010', From 7a81930e93f44b008842aa4fca70750a96aa2f67 Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 14:19:03 +0000 Subject: [PATCH 09/12] fix path --- plugin-server/tests/main/process-event.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index ea993ddaa8764..8b637192fb944 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -35,7 +35,7 @@ import { createUserTeamAndOrganization, getFirstTeam, getTeams, resetTestDatabas jest.mock('../../src/utils/status') jest.setTimeout(600000) // 600 sec timeout. -jest.mock('../../../src/utils/posthog', () => ({ +jest.mock('../../src/utils/posthog', () => ({ captureTeamEvent: jest.fn(), })) From c2f6ffc7ccb327d0cece4efa4a34325eaeec90e8 Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 14:53:30 +0000 Subject: [PATCH 10/12] fix test --- plugin-server/tests/main/process-event.test.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index 8b637192fb944..e8468c458489f 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -902,16 +902,10 @@ test('capture first team event', async () => { ) expect(captureTeamEvent).toHaveBeenCalledWith({ - distinctId: 'plugin_test_user_distinct_id_1001', + team: team, event: 'first team event ingested', - properties: { - team: team.uuid, - }, - groups: { - project: team.uuid, - organization: team.organization_id, - instance: 'unknown', - }, + properties: { team: team.uuid }, + distinctId: 'plugin_test_user_distinct_id_1001', }) team = await getFirstTeam(hub) From 13e801e8af5d7376013426d3cc192f4d9423dd6a Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 15:24:40 +0000 Subject: [PATCH 11/12] fix test because team object changes during run --- plugin-server/tests/main/process-event.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index e8468c458489f..e67c9ff5d0ec0 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -901,12 +901,12 @@ test('capture first team event', async () => { new UUIDT().toString() ) - expect(captureTeamEvent).toHaveBeenCalledWith({ - team: team, - event: 'first team event ingested', - properties: { team: team.uuid }, - distinctId: 'plugin_test_user_distinct_id_1001', - }) + expect(captureTeamEvent).toHaveBeenCalledWith( + expect.objectContaining({ uuid: team.uuid, organization_id: team.organization_id }), + 'first team event ingested', + { host: undefined, realm: undefined, sdk: undefined }, + 'plugin_test_user_distinct_id_1001' + ) team = await getFirstTeam(hub) expect(team.ingested_event).toEqual(true) From e986efa5ff493c02dd5b4302c468f656324c6d51 Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 28 Feb 2025 16:46:38 +0000 Subject: [PATCH 12/12] replace mocks --- plugin-server/tests/main/process-event.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin-server/tests/main/process-event.test.ts b/plugin-server/tests/main/process-event.test.ts index e67c9ff5d0ec0..fc40789043fe9 100644 --- a/plugin-server/tests/main/process-event.test.ts +++ b/plugin-server/tests/main/process-event.test.ts @@ -36,6 +36,7 @@ import { createUserTeamAndOrganization, getFirstTeam, getTeams, resetTestDatabas jest.mock('../../src/utils/status') jest.setTimeout(600000) // 600 sec timeout. jest.mock('../../src/utils/posthog', () => ({ + ...jest.requireActual('../../src/utils/posthog'), captureTeamEvent: jest.fn(), }))