pi-mono/packages/chord/test/examples/62-telemetry/start.ts
Mario Zechner ff33ef42c4 feat(chord): telemetry from pages and workers stored by the server, who a span was for
The four telemetry gaps (rows on commits, chord.host, microsecond times, a read-only store) and: pages record and
send span batches over their link to the server's ingest object (checked, capped, rate-limited, stamped browser and
with the link's principal); workers send theirs too, so the server is the store's only writer; principalAttributes
lets an app choose what a span records about its principal. The tutorial shows a real page's click traced to the
worker, with the trace viewer.
2026-11-04 11:59:14 +00:00

59 lines
2.4 KiB
TypeScript

// The tally app's start: `startServer` with the app's telemetry store, a SQLite file in the data directory. The server
// is its only writer: each worker sends what it records to the server, so one trace reads tab → server → worker.
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import type { Context } from "../../../src/context/index.ts";
import { type App, startServer } from "../../../src/node/app/index.ts";
import { openNodeSqliteDatabase } from "../../../src/sqlite/node.ts";
import { createSqliteTelemetry, type SqliteTelemetry } from "../../../src/telemetry-sqlite/index.ts";
import type { TallyPrincipal } from "./app/principals.ts";
import * as v1 from "./app/v1.ts";
/** The app's API: its name, versions and this process's modules (the worker's entry has the same). */
export const API = { name: "@tally/app", versions: ["v1"], modules: { "@tally/app/v1": v1 } };
/** The app's facet kinds. */
export const KINDS = { server: { platform: "node" }, worker: { platform: "node" } } as const;
/** The telemetry store every process of the app at `dataDir` records to. */
export function telemetryFile(dataDir: string): string {
return join(dataDir, "telemetry.sqlite");
}
/** Opens the SQLite telemetry store at `path` (the server's). */
export async function openTelemetry(path: string): Promise<SqliteTelemetry> {
return createSqliteTelemetry(await openNodeSqliteDatabase(path));
}
/** Starts the tally app on a free loopback port with its data in `dataDir`, recording to `telemetry`. */
export function startTally(
dataDir: string,
telemetry: SqliteTelemetry,
context: Context,
): Promise<App<TallyPrincipal>> {
return startServer<TallyPrincipal>(
{
name: "tally",
dataDir,
root: fileURLToPath(new URL("./plugins/", import.meta.url)),
listen: { host: "127.0.0.1", port: 0 },
api: API,
kinds: KINDS,
principal: { server: { kind: "server" }, worker: (address) => ({ kind: "worker", tally: address.key }) },
telemetry,
workers: [
{
kind: v1.Tally,
entry: fileURLToPath(new URL("./worker.ts", import.meta.url)),
execArgv: ["--conditions=source", "--experimental-strip-types", "--no-warnings"],
start: () => ({}),
// The owner reaches a tally through the server, which relays.
authorize: (principal) => principal.kind === "owner" || principal.kind === "server",
},
],
onError: (error) => console.error("app:", error.kind, error.error),
},
context,
);
}