UNPKG

snapmetrics

Version:

Lightweight library for tracking real-time metrics and events with rolling statistics over configurable time windows.

238 lines (237 loc) 10.3 kB
export type TimeWindow = `${number}${"s" | "m" | "h"}`; interface SnapMetricsOptions { timeWindows?: TimeWindow[]; removeExpiredRecordsThrottlingMS?: number | false; debug?: boolean; } export declare class SnapMetrics { private windows; private timeWindowDurations; private debug; private throttledRemoveExpiredRecords; /** * Constructs an instance of the class. * * @param timeWindowsOrOptions - Either an array of time windows or a configuration options object: * - If an array is provided, it is treated as `timeWindows`, formatted as `<integer><unit>` * where unit is `s`, `m`, or `h`. Defaults to ["1m", "5m", "15m"]. * - If an object is provided, it may contain the following options: * - `timeWindows` (Array<string>): Array of time windows, formatted as `<integer><unit>`. * Defaults to ["1m", "5m", "15m"]. * - `removeExpiredRecordsThrottlingMS` (number | false): Time in milliseconds to throttle * the removal of expired records. Must be a non-negative number (>= 0) or `false` to * disable throttling. Defaults to `100` ms. * - `debug` (boolean): Enables logging for debugging. Defaults to `false`. * @example * const metrics = new SnapMetrics({ timeWindows: ["1m", "5m", "15m"], removeExpiredRecordsThrottlingMS: 100, debug: true }); */ constructor(timeWindowsOrOptions?: TimeWindow[] | SnapMetricsOptions); /** * Removes expired records from all time windows. */ private removeExpiredRecords; /** * Maps a function over all time windows and returns the results. * @param mapper Function that transforms a window's data into a result * @returns Record mapping each time window to its transformed value */ private mapWindows; /** * Gets values from a window, optionally sorted, with efficient caching. * @param windowKey - The time window key * @param sortRequirement - Optional sorting requirement, defaults to ANY * @returns Object containing values array and isSorted flag, or null if window doesn't exist */ private getValues; /** * Records a value into all active time windows. * @param value - Value. * @example * const metrics = new SnapMetrics(); * metrics.record(1); // Records a value of 1 into all active time windows */ record(value: number): void; /** * Measures the execution time of a synchronous or asynchronous function and records the duration in all time windows. * * @template T The return type of the provided function. * @param fn The function to be executed, which can be synchronous or return a Promise for asynchronous execution. * @returns The result of the executed function. If the function returns a Promise, the result will also be a Promise. * @example * const metrics = new SnapMetrics(); * const result = metrics.recordDuration(() => { * // Your function logic here * return someValue; * }); */ recordDuration<T>(fn: () => T | Promise<T>): T | Promise<T>; /** * Returns the count of values for all time windows. * @returns Record mapping each time window to its count of recorded values. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.getCounts(); // { "1m": 2, "5m": 2, "15m": 2 } */ getCounts(): Record<TimeWindow, number>; /** * Returns the sum of values for all time windows. * @returns Record mapping each time window to its sum value. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.getSums(); // { "1m": 3, "5m": 3, "15m": 3 } * * // Empty window returns null * const emptyMetrics = new SnapMetrics(); * emptyMetrics.getSums(); // { "1m": null, "5m": null, "15m": null } */ getSums(): Record<TimeWindow, number | null>; /** * Returns the rolling averages for all time windows. * @returns Record mapping each time window to its average value. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.getAverages(); // { "1m": 1.5, "5m": 1.5, "15m": 1.5 } * * // Empty window returns null * const emptyMetrics = new SnapMetrics(); * emptyMetrics.getAverages(); // { "1m": null, "5m": null, "15m": null } */ getAverages(): Record<TimeWindow, number | null>; /** * Returns the middle value for each time window using linear interpolation. * @description For an even number of values, uses linear interpolation between the two middle values. * @returns Record mapping each time window to its median value. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.record(3); * metrics.getMedians(); // { "1m": 2, "5m": 2, "15m": 2 } */ getMedians(): Record<TimeWindow, number | null>; /** * Returns the value below which the given percentage of observations fall. * @param percentile The percentile to calculate (0-100). For example, 95 for 95th percentile. * @description Uses Hyndman and Fan type 7 linear interpolation method for accurate results. * @returns Record mapping each time window to its percentile value. Returns null for empty windows. * @throws {Error} If percentile is not between 0 and 100. * @example * const metrics = new SnapMetrics(); * // Record some response times... * metrics.getPercentiles(95); // Get 95th percentile response times */ getPercentiles(percentile: number): Record<TimeWindow, number | null>; /** * Returns the smallest value recorded within each time window. * @returns Record mapping each time window to its minimum value. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.getMinimums(); // { "1m": 1, "5m": 1, "15m": 1 } */ getMinimums(): Record<TimeWindow, number | null>; /** * Returns the largest value recorded within each time window. * @returns Record mapping each time window to its maximum value. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.getMaximums(); // { "1m": 2, "5m": 2, "15m": 2 } */ getMaximums(): Record<TimeWindow, number | null>; /** * Returns the standard deviation (square root of variance) for each time window. * @description Indicates how spread out values are from their mean. * @returns Record mapping each time window to its standard deviation. Returns null for empty windows. * @example * const metrics = new SnapMetrics(); * metrics.record(2); * metrics.record(4); * metrics.record(6); * metrics.getStandardDeviations(); // { "1m": 1.63, "5m": 1.63, "15m": 1.63 } */ getStandardDeviations(): Record<TimeWindow, number | null>; /** * Returns all metrics for each time window. * @param options Configuration options * @param options.percentiles Array of percentiles to calculate (0-100). Defaults to [90, 95]. * @returns Record mapping each time window to its metrics: * - count: Number of values in the window * - sum: Sum of all values * - average: Mean value * - median: 50th percentile * - percentile{N}: Nth percentile values for each requested percentile * - minimum: Smallest value * - maximum: Largest value * - standardDeviation: Standard deviation from mean * @example * const metrics = new SnapMetrics(); * metrics.record(1); * metrics.record(2); * metrics.record(3); * * metrics.getMetrics(); * // Returns: * // { * // "1m": { * // count: 3, * // sum: 6, * // average: 2, * // median: 2, * // percentile90: 2.8, * // percentile95: 2.9, * // minimum: 1, * // maximum: 3, * // standardDeviation: 0.816 * // } * // } */ getMetrics({ percentiles }?: { percentiles?: number[]; }): Record<TimeWindow, Record<string, number | null>>; /** * Increments a named counter for tracking frequency across time windows. * @param name - The name of the counter to increment * @param value - Optional amount to increment by (defaults to 1) * @example * const metrics = new SnapMetrics(); * metrics.increment('api_calls'); // Increment by 1 * metrics.increment('bytes_sent', 1024); // Increment by specific amount */ increment(name: string, value?: number): void; /** * Returns the current value of all counters for each time window. * @returns Record mapping each time window to a map of counter values. * @example * const metrics = new SnapMetrics(); * metrics.increment('api_calls'); * metrics.increment('errors'); * metrics.getCounters(); * // Returns: * // { * // "1m": { "api_calls": 1, "errors": 1 }, * // "5m": { "api_calls": 1, "errors": 1 }, * // "15m": { "api_calls": 1, "errors": 1 } * // } */ getCounters(): Record<TimeWindow, Record<string, number>>; /** * Returns the current value of a specific counter for each time window. * @param name The name of the counter to retrieve * @returns Record mapping each time window to the counter's value. Returns null if counter doesn't exist. * @example * const metrics = new SnapMetrics(); * metrics.increment('api_calls'); * metrics.getCounter('api_calls'); // { "1m": 1, "5m": 1, "15m": 1 } */ getCounter(name: string): Record<TimeWindow, number | null>; } export {};