Skip to content

Commit

Permalink
Improve telemetry (#798)
Browse files Browse the repository at this point in the history
* docs: install posthog-node

* chore: patch detect-package-manager types

* chore: update telemetry service

* docs: update telemetry handler

* chore: include ts files within docs folder in biome config

* fix telemetry url

* chore: undo biome config

* chore: add heartbeat interval back

* chore: remove unused plugin

* fix: queue, kill

* remove duplicate
  • Loading branch information
0xOlias authored Apr 15, 2024
1 parent a4f33f3 commit ce188dc
Show file tree
Hide file tree
Showing 17 changed files with 490 additions and 342 deletions.
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"next": "^14.0.2",
"nextra": "3.0.0-alpha.10",
"nextra-theme-docs": "3.0.0-alpha.10",
"posthog-node": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.1.0",
Expand Down
48 changes: 35 additions & 13 deletions docs/pages/api/telemetry/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { TrackParams } from "@segment/analytics-node";
import { Analytics } from "@segment/analytics-node";
import { Analytics, type TrackParams } from "@segment/analytics-node";
import type { NextApiRequest, NextApiResponse } from "next";
import { PostHog } from "posthog-node";

if (!process.env.SEGMENT_WRITE_KEY) {
if (!process.env.SEGMENT_WRITE_KEY)
throw new Error('Missing required environment variable "SEGMENT_WRITE_KEY".');
}
if (!process.env.POSTHOG_PROJECT_API_KEY)
throw new Error(
'Missing required environment variable "POSTHOG_PROJECT_API_KEY".',
);

const analytics = new Analytics({
writeKey: process.env.SEGMENT_WRITE_KEY,
Expand All @@ -15,6 +18,12 @@ const analytics = new Analytics({
maxEventsInBatch: 1,
});

const client = new PostHog(process.env.POSTHOG_PROJECT_API_KEY, {
host: "https://app.posthog.com",
flushAt: 1,
flushInterval: 0,
});

const asyncTrack = (payload: TrackParams) => {
return new Promise<void>((resolve, reject) => {
analytics.track(payload, (err) => {
Expand All @@ -34,14 +43,27 @@ export default async function forwardTelemetry(
});
}

try {
await asyncTrack(req.body);
res.status(200).json({ success: true });
} catch (e) {
console.error("Error processing telemetry data:", {
error: e,
body: req.body,
});
res.status(500).json({ error: "Server error" });
const body = req.body;

const handleError = (error: unknown) => {
console.error("Error processing telemetry data:", { error, body });
return res.status(500).json({ error: "Server error" });
};

// If the event has an distinctId, it's a new Posthog event from >= 0.4.3
if (body.distinctId) {
client.on("error", handleError);
client.capture(body);
await client.shutdown();
}
// Otherwise, assume it's a Segment event
else {
try {
await asyncTrack(body);
} catch (error) {
handleError(error);
}
}

return res.status(200).json({ success: true });
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"packageManager": "[email protected]",
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
"[email protected]": "patches/[email protected]",
"[email protected]": "patches/[email protected]"
},
"peerDependencyRules": {
"ignoreMissing": ["node-fetch"]
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/_test/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Common } from "@/common/common.js";
import { LoggerService } from "@/common/logger.js";
import { MetricsService } from "@/common/metrics.js";
import { buildOptions } from "@/common/options.js";
import { TelemetryService } from "@/common/telemetry.js";
import { createTelemetry } from "@/common/telemetry.js";
import type { Config } from "@/config/config.js";
import type { DatabaseConfig } from "@/config/database.js";
import type { Network } from "@/config/networks.js";
Expand Down Expand Up @@ -49,11 +49,12 @@ export function setupContext(context: TestContext) {
}),
telemetryDisabled: true,
};
const logger = new LoggerService({ level: "silent" });
context.common = {
options,
logger: new LoggerService({ level: "silent" }),
logger,
metrics: new MetricsService(),
telemetry: new TelemetryService({ options }),
telemetry: createTelemetry({ options, logger }),
};
}

Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/bin/commands/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { runCodegen } from "@/common/codegen.js";
import { LoggerService } from "@/common/logger.js";
import { MetricsService } from "@/common/metrics.js";
import { buildOptions } from "@/common/options.js";
import { TelemetryService } from "@/common/telemetry.js";
import { createTelemetry } from "@/common/telemetry.js";
import type { CliOptions } from "../ponder.js";
import { setupShutdown } from "../utils/shutdown.js";

Expand All @@ -25,7 +25,7 @@ export async function codegen({ cliOptions }: { cliOptions: CliOptions }) {
}

const metrics = new MetricsService();
const telemetry = new TelemetryService({ options });
const telemetry = createTelemetry({ options, logger });
const common = { options, logger, metrics, telemetry };

const buildService = await createBuildService({ common });
Expand All @@ -49,6 +49,11 @@ export async function codegen({ cliOptions }: { cliOptions: CliOptions }) {
return;
}

telemetry.record({
name: "lifecycle:session_start",
properties: { cli_command: "codegen" },
});

runCodegen({ common, graphqlSchema: buildResult.build.graphqlSchema });

logger.info({ service: "codegen", msg: "Wrote ponder-env.d.ts" });
Expand Down
12 changes: 4 additions & 8 deletions packages/core/src/bin/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type BuildResult, createBuildService } from "@/build/index.js";
import { LoggerService } from "@/common/logger.js";
import { MetricsService } from "@/common/metrics.js";
import { buildOptions } from "@/common/options.js";
import { TelemetryService } from "@/common/telemetry.js";
import { buildPayload, createTelemetry } from "@/common/telemetry.js";
import { UiService } from "@/ui/service.js";
import { createQueue } from "@ponder/common";
import type { CliOptions } from "../ponder.js";
Expand Down Expand Up @@ -42,7 +42,7 @@ export async function dev({ cliOptions }: { cliOptions: CliOptions }) {
});

const metrics = new MetricsService();
const telemetry = new TelemetryService({ options });
const telemetry = createTelemetry({ options, logger });
const common = { options, logger, metrics, telemetry };

const buildService = await createBuildService({ common });
Expand Down Expand Up @@ -103,12 +103,8 @@ export async function dev({ cliOptions }: { cliOptions: CliOptions }) {
}

telemetry.record({
event: "App Started",
properties: {
command: "ponder dev",
contractCount: initialResult.build.sources.length,
databaseKind: initialResult.build.databaseConfig.kind,
},
name: "lifecycle:session_start",
properties: { cli_command: "dev", ...buildPayload(initialResult.build) },
});

buildQueue.add(initialResult);
Expand Down
12 changes: 4 additions & 8 deletions packages/core/src/bin/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createBuildService } from "@/build/index.js";
import { LoggerService } from "@/common/logger.js";
import { MetricsService } from "@/common/metrics.js";
import { buildOptions } from "@/common/options.js";
import { TelemetryService } from "@/common/telemetry.js";
import { buildPayload, createTelemetry } from "@/common/telemetry.js";
import { PostgresDatabaseService } from "@/database/postgres/service.js";
import type { NamespaceInfo } from "@/database/service.js";
import { RealtimeIndexingStore } from "@/indexing-store/realtimeStore.js";
Expand Down Expand Up @@ -35,7 +35,7 @@ export async function serve({ cliOptions }: { cliOptions: CliOptions }) {
});

const metrics = new MetricsService();
const telemetry = new TelemetryService({ options });
const telemetry = createTelemetry({ options, logger });
const common = { options, logger, metrics, telemetry };

const buildService = await createBuildService({ common });
Expand All @@ -59,12 +59,8 @@ export async function serve({ cliOptions }: { cliOptions: CliOptions }) {
}

telemetry.record({
event: "App Started",
properties: {
command: "ponder serve",
contractCount: initialResult.build.sources.length,
databaseKind: initialResult.build.databaseConfig.kind,
},
name: "lifecycle:session_start",
properties: { cli_command: "serve", ...buildPayload(initialResult.build) },
});

const { databaseConfig, schema, graphqlSchema } = initialResult.build;
Expand Down
12 changes: 4 additions & 8 deletions packages/core/src/bin/commands/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createBuildService } from "@/build/index.js";
import { LoggerService } from "@/common/logger.js";
import { MetricsService } from "@/common/metrics.js";
import { buildOptions } from "@/common/options.js";
import { TelemetryService } from "@/common/telemetry.js";
import { buildPayload, createTelemetry } from "@/common/telemetry.js";
import type { CliOptions } from "../ponder.js";
import { run } from "../utils/run.js";
import { setupShutdown } from "../utils/shutdown.js";
Expand Down Expand Up @@ -32,7 +32,7 @@ export async function start({ cliOptions }: { cliOptions: CliOptions }) {
});

const metrics = new MetricsService();
const telemetry = new TelemetryService({ options });
const telemetry = createTelemetry({ options, logger });
const common = { options, logger, metrics, telemetry };

const buildService = await createBuildService({ common });
Expand All @@ -56,12 +56,8 @@ export async function start({ cliOptions }: { cliOptions: CliOptions }) {
}

telemetry.record({
event: "App Started",
properties: {
command: "ponder start",
contractCount: initialResult.build.sources.length,
databaseKind: initialResult.build.databaseConfig.kind,
},
name: "lifecycle:session_start",
properties: { cli_command: "start", ...buildPayload(initialResult.build) },
});

cleanupReloadable = await run({
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/bin/utils/shutdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export function setupShutdown({
});
}
common.telemetry.record({
event: "App Killed",
properties: { processDuration: process.uptime() },
name: "lifecycle:session_end",
properties: { duration_seconds: process.uptime() },
});

await cleanup();
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/common/common.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { LoggerService } from "./logger.js";
import type { MetricsService } from "./metrics.js";
import type { Options } from "./options.js";
import type { TelemetryService } from "./telemetry.js";
import type { Telemetry } from "./telemetry.js";

export type Common = {
options: Options;
logger: LoggerService;
metrics: MetricsService;
telemetry: TelemetryService;
telemetry: Telemetry;
};
6 changes: 2 additions & 4 deletions packages/core/src/common/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export type Options = {

telemetryUrl: string;
telemetryDisabled: boolean;
telemetryIsExampleProject: boolean;
telemetryConfigDir: string | undefined;

logLevel: LevelWithSilent;
};
Expand Down Expand Up @@ -78,9 +78,7 @@ export const buildOptions = ({ cliOptions }: { cliOptions: CliOptions }) => {

telemetryUrl: "https://ponder.sh/api/telemetry",
telemetryDisabled: Boolean(process.env.PONDER_TELEMETRY_DISABLED),
telemetryIsExampleProject: Boolean(
process.env.PONDER_TELEMETRY_IS_EXAMPLE_PROJECT,
),
telemetryConfigDir: undefined,

logLevel,
} satisfies Options;
Expand Down
Loading

0 comments on commit ce188dc

Please sign in to comment.