export type Attributes = Record; export type SpanStatus = { status: "ok"; } | { status: "error"; error: { name: string; message: string; }; }; export interface SpanOptions { name: string; attributes?: Attributes; } export interface TelemetrySpan { readonly id: string; setAttributes(a: Attributes): void; addEvent(name: string, a?: Attributes): void; setStatus(s: SpanStatus): void; /** A child span. */ startSpan(o: SpanOptions, fn: (span: TelemetrySpan) => T): T; } export interface Counter { add(value: number, a?: Attributes): void; } export interface Histogram { record(value: number, a?: Attributes): void; } export interface Telemetry { readonly enabled: boolean; startSpan(o: SpanOptions, fn: (span: TelemetrySpan) => T): T; counter(name: string): Counter; histogram(name: string): Histogram; } export type TelemetryRecord = { t: "span"; id: string; parent: string | null; name: string; start: number; end: number; ms: number; attributes: Attributes; events: { name: string; at: number; attributes?: Attributes; }[]; status: SpanStatus; proc: string; } | { t: "metric"; kind: "counter" | "histogram"; name: string; value: number; at: number; attributes?: Attributes; proc: string; }; export type Sink = (r: TelemetryRecord) => void; /** Does nothing, at no cost: what every component gets unless telemetry is on. */ export declare const NOOP_TELEMETRY: Telemetry; /** Telemetry that hands every finished span and metric point to `sink`. `proc` names the process (daemon, host-). */ export declare function createTelemetry(sink: Sink, proc: string, now?: () => number): Telemetry; /** In memory, for tests. */ export declare function memoryTelemetry(proc?: string): { telemetry: Telemetry; records: TelemetryRecord[]; }; /** * A JSON-lines file, written in batches (every 250 ms and at exit): a stress run makes * thousands of records, and the daemon's loop must not wait on each one. */ export declare function fileTelemetry(path: string, proc: string): Telemetry; /** * ROOST_TELEMETRY=path turns it on (for this process and the hosts it starts). A * relative path is made absolute here and written back, so hosts started in other * directories write to the same file. */ export declare function telemetryFromEnv(proc: string, env?: NodeJS.ProcessEnv): Telemetry; /** Records from a telemetry file (lines that do not parse are skipped). */ export declare function parseTelemetry(text: string): TelemetryRecord[]; /** p50/p95/p99, min, max and count of some values (a stress report's latency line). */ export declare function percentiles(values: number[]): { n: number; min: number; p50: number; p95: number; p99: number; max: number; } | null;