diff options
Diffstat (limited to 'u/trace/metrics.ts')
-rw-r--r-- | u/trace/metrics.ts | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/u/trace/metrics.ts b/u/trace/metrics.ts deleted file mode 100644 index 2301afd..0000000 --- a/u/trace/metrics.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { - isObject, - type ITrace, - type ITraceWith, - type Mapper, - type SideEffect, - type Supplier, -} from '@emprespresso/pengueno'; - -export enum Unit { - COUNT = 'COUNT', - MILLISECONDS = 'MILLISECONDS', -} - -export interface IMetric { - readonly count: IEmittableMetric; - readonly time: IEmittableMetric; - readonly failure: undefined | IMetric; - readonly success: undefined | IMetric; - readonly warn: undefined | IMetric; - readonly children: Supplier<Array<IMetric>>; - - readonly _tag: 'IMetric'; -} -export const isIMetric = (t: unknown): t is IMetric => isObject(t) && '_tag' in t && t._tag === 'IMetric'; - -export interface IEmittableMetric { - readonly name: string; - readonly unit: Unit; - withValue: Mapper<number, MetricValue>; -} - -export class EmittableMetric implements IEmittableMetric { - constructor( - public readonly name: string, - public readonly unit: Unit, - ) {} - - public withValue(value: number): MetricValue { - return { - name: this.name, - unit: this.unit, - emissionTimestamp: Date.now(), - value, - _tag: 'MetricValue', - }; - } -} - -export class Metric implements IMetric { - constructor( - public readonly count: IEmittableMetric, - public readonly time: IEmittableMetric, - public readonly failure: undefined | Metric = undefined, - public readonly success: undefined | Metric = undefined, - public readonly warn: undefined | Metric = undefined, - public readonly _tag: 'IMetric' = 'IMetric', - ) {} - - public children() { - return [this.failure, this.success, this.warn].filter((x) => x) as IMetric[]; - } - - static fromName(name: string, addChildren = true): Metric { - return new Metric( - new EmittableMetric(`${name}.count`, Unit.COUNT), - new EmittableMetric(`${name}.elapsed`, Unit.MILLISECONDS), - addChildren ? Metric.fromName(`${name}.failure`, false) : undefined, - addChildren ? Metric.fromName(`${name}.success`, false) : undefined, - addChildren ? Metric.fromName(`${name}.warn`, false) : undefined, - ); - } -} - -export interface MetricValue { - readonly name: string; - readonly unit: Unit; - readonly value: number; - readonly emissionTimestamp: number; - readonly _tag: 'MetricValue'; -} -export const isMetricValue = (t: unknown): t is MetricValue => isObject(t) && '_tag' in t && t._tag === 'MetricValue'; - -export const isMetricsTraceSupplier = (t: unknown): t is MetricsTraceSupplier => isMetricValue(t) || isIMetric(t); - -export type MetricsTraceSupplier = ITraceWith<IMetric | MetricValue | undefined>; -type MetricTracingTuple = [IMetric, Date]; -export class MetricsTrace implements ITrace<MetricsTraceSupplier> { - constructor( - private readonly metricConsumer: SideEffect<Array<MetricValue>>, - private readonly tracing: Array<MetricTracingTuple> = [], - private readonly flushed: Set<IMetric> = new Set(), - ) {} - - public addTrace(trace: MetricsTraceSupplier) { - if (!isIMetric(trace)) return this; - return new MetricsTrace(this.metricConsumer)._nowTracing(trace); - } - - public trace(metric: MetricsTraceSupplier) { - if (typeof metric === 'undefined' || typeof metric === 'string') return this; - if (isMetricValue(metric)) { - this.metricConsumer([metric]); - return this; - } - - const foundMetricValues = this.tracing - .flatMap(([tracing, startedTracing]) => - [tracing, ...tracing.children()] - .filter((_tracing) => metric === _tracing) - .flatMap((metric) => [ - this.addMetric(metric, startedTracing), - this.addMetric(tracing, startedTracing), - ]), - ) - .flatMap((values) => values); - - if (foundMetricValues.length === 0) { - return this._nowTracing(metric); - } - - this.metricConsumer(foundMetricValues); - return this; - } - - private addMetric(metric: IMetric, startedTracing: Date): Array<MetricValue> { - if (this.flushed.has(metric)) { - return []; - } - - this.flushed.add(metric); - return [metric.count.withValue(1.0), metric.time.withValue(Date.now() - startedTracing.getTime())]; - } - - private _nowTracing(metric?: IMetric): MetricsTrace { - if (!metric) return this; - this.tracing.push([metric, new Date()]); - return this; - } -} |