@dudousxd/nestjs-telescope
Version:
Laravel Telescope-style observability console for NestJS — core: watchers, recorder, correlation, SQLite store, headless API.
79 lines • 3.7 kB
TypeScript
/** One minute is the base rollup granularity. */
export declare const ROLLUP_BUCKET_MS = 60000;
/**
* Upper boundaries (inclusive, in ms) for the pre-aggregated latency histogram.
* Bucket `i` counts durations `d` where `d <= LATENCY_BOUNDARIES_MS[i]` and
* `d > LATENCY_BOUNDARIES_MS[i-1]`. A final OVERFLOW bucket (index
* `LATENCY_BOUNDARIES_MS.length`) counts everything greater than the last
* boundary, so a histogram always has `LATENCY_BOUNDARIES_MS.length + 1` cells.
*/
export declare const LATENCY_BOUNDARIES_MS: readonly number[];
/** The fixed cell count of every latency histogram (boundaries + 1 overflow). */
export declare const HISTOGRAM_BUCKET_COUNT: number;
/** A fresh, all-zeros histogram of the canonical fixed length. */
export declare function emptyHistogram(): number[];
/**
* The histogram cell a duration falls in: the first index `i` where
* `durationMs <= LATENCY_BOUNDARIES_MS[i]`, else the overflow index. Negative or
* zero durations land in cell 0.
*/
export declare function histogramBucketIndex(durationMs: number): number;
/**
* Increments the histogram cell for `durationMs` by one, in place. Safe against
* the index typing (always a valid in-range cell of a fixed-length array).
*/
export declare function incrementHistogram(histogram: number[], durationMs: number): void;
/**
* Normalizes a (possibly legacy/undefined) stored histogram into a fixed-length
* zero-padded array. Legacy rollup rows with no histogram read back as all-zeros
* of the canonical length — never NaN, never a wrong width.
*/
export declare function normalizeHistogram(histogram: number[] | null | undefined): number[];
/**
* Element-wise additive merge of `addend` into `target` (mutates and returns
* `target`). Both are normalized first, so legacy/short arrays are safe.
*/
export declare function mergeHistograms(target: number[], addend: number[] | null | undefined): number[];
/** Floors an epoch-ms timestamp to the start of its 1-minute rollup bucket. */
export declare function floorToBucket(epochMs: number): number;
/** An additive aggregate for (metric, bucketStart). metric = the entry `type` for now. */
export interface RollupDelta {
metric: string;
bucketStart: number;
count: number;
sum: number;
max: number;
/** Fixed-length ({@link HISTOGRAM_BUCKET_COUNT}) latency histogram for this group. */
histogram: number[];
}
/** A materialized rollup row for (metric, bucketStart). */
export interface RollupBucket {
metric: string;
bucketStart: number;
count: number;
sum: number;
max: number;
/** Fixed-length ({@link HISTOGRAM_BUCKET_COUNT}) latency histogram for this bucket. */
histogram: number[];
}
/**
* Optional SPI a {@link StorageProvider} MAY also implement to support
* pre-aggregated rollups. Detected at runtime via {@link isRollupStore}; it is
* deliberately NOT part of the StorageProvider interface, so stores that do not
* implement it keep working via the raw-scan fallback.
*/
export interface RollupStore {
/**
* Additively merge deltas into the rollup table (accumulate count/sum, keep a
* running max). Idempotent per (metric, bucketStart) via upsert + increment.
*/
recordRollups(deltas: RollupDelta[]): Promise<void>;
/**
* Buckets for the given metrics whose bucketStart is in [fromBucket, toBucket].
* Order unspecified.
*/
queryRollups(metrics: string[], fromBucket: number, toBucket: number): Promise<RollupBucket[]>;
}
/** Duck-types `s` as a {@link RollupStore} (recordRollups & queryRollups present). */
export declare function isRollupStore(s: object): s is RollupStore;
//# sourceMappingURL=rollup-store.d.ts.map