@dudousxd/nestjs-telescope
Version:
Laravel Telescope-style observability console for NestJS — core: watchers, recorder, correlation, SQLite store, headless API.
107 lines • 3.59 kB
TypeScript
import { type Entry } from '../entry/entry.js';
import { type TimeseriesReport } from './timeseries.js';
export interface LatencyStats {
count: number;
p50: number;
p95: number;
p99: number;
max: number;
slow: number;
}
export interface FamilyLatency {
familyHash: string;
label: string;
count: number;
p50: number;
p99: number;
}
export interface CacheStats {
hits: number;
misses: number;
sets: number;
deletes: number;
hitRatio: number;
topKeys: {
key: string;
count: number;
}[];
/** Gets served from a stale/grace value (subset of `hits`). Caches without a
* stale-while-revalidate concept leave this 0. */
staleHits: number;
/** Per-tier hit/miss split for layered caches (e.g. `l1`/`l2`). Empty `{}` for
* single-tier caches that don't report a tier. */
byTier: Record<string, {
hits: number;
misses: number;
}>;
}
export interface StatusBreakdown {
'2xx': number;
'3xx': number;
'4xx': number;
'5xx': number;
other: number;
}
export interface ExceptionGroupStats {
/** The family key — the entry's `familyHash` when present, else `${class}: ${message}`. */
key: string;
class: string;
message: string;
count: number;
/** Most recent occurrence in the window. */
lastAt: Date;
/** Per-bucket occurrence counts, aligned to the report's `overTime` buckets. */
overTime: number[];
}
export interface StatsResult {
type: string;
windowMs: number;
total: number;
/** Throughput over the window — reuses {@link bucketTimeseries}. */
overTime: TimeseriesReport;
/** Present for types whose entries carry a `durationMs`. */
latency?: LatencyStats;
/** Query only: top families by p99. */
families?: FamilyLatency[];
/** Cache only. */
cache?: CacheStats;
/** Request only. */
status?: StatusBreakdown;
/** Exception only: top groups by class+message, with count, last-seen, over-time. */
exceptions?: ExceptionGroupStats[];
/** Caller-supplied: whether the scan hit its cap. */
truncated: boolean;
}
/** Pre-estimated p50/p95/p99 (ms), supplied by a rollup-backed caller to replace
* the raw-scan percentiles in {@link LatencyStats}. count/max/slow stay raw. */
export interface LatencyPercentilesOverride {
p50: number;
p95: number;
p99: number;
}
export interface SummarizeStatsInput {
entries: Entry[];
type: string;
windowStart: Date;
windowEnd: Date;
windowMs: number;
buckets: number;
slowMs: number;
truncated: boolean;
topFamilies?: number;
topKeys?: number;
topExceptions?: number;
/** When provided, p50/p95/p99 in the latency block are taken from these
* rollup-histogram estimates instead of the raw-scan computation. The latency
* block's count/max/slow remain raw-derived. */
latencyPercentiles?: LatencyPercentilesOverride;
}
/** Nearest-rank percentile over a NON-EMPTY ascending array; 0 for empty.
* `q` in [0,1]; `idx = clamp(ceil(q*n)-1, 0, n-1)`. */
export declare function percentile(sortedAscending: number[], q: number): number;
/** Aggregate a window of entries into per-type analytics: latency percentiles,
* query-family breakdown, cache hit/miss, request status breakdown, and a
* throughput time-series. Pure: callers fetch the windowed entries and supply
* the window bounds + `truncated` flag. */
export declare function summarizeStats(input: SummarizeStatsInput): StatsResult;
//# sourceMappingURL=stats.d.ts.map