diff options
author | Elizabeth Hunt <me@liz.coffee> | 2025-07-27 18:50:33 -0700 |
---|---|---|
committer | Elizabeth Hunt <me@liz.coffee> | 2025-07-27 19:31:06 -0700 |
commit | 7aa11b7a8abacf81dec20fff21216df35d333756 (patch) | |
tree | 40f6a76c37412cf1c5a67f99a4ee30e3aae863c9 /u/trace/metric | |
parent | e4df72cd446270cf867ec308995a05e21b3aa601 (diff) | |
download | ci-7aa11b7a8abacf81dec20fff21216df35d333756.tar.gz ci-7aa11b7a8abacf81dec20fff21216df35d333756.zip |
Pulls in pengueno from npm
Diffstat (limited to 'u/trace/metric')
-rw-r--r-- | u/trace/metric/emittable.ts | 18 | ||||
-rw-r--r-- | u/trace/metric/index.ts | 41 | ||||
-rw-r--r-- | u/trace/metric/metric.ts | 54 | ||||
-rw-r--r-- | u/trace/metric/trace.ts | 59 |
4 files changed, 0 insertions, 172 deletions
diff --git a/u/trace/metric/emittable.ts b/u/trace/metric/emittable.ts deleted file mode 100644 index f3441ec..0000000 --- a/u/trace/metric/emittable.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IEmittableMetric, MetricValue, MetricValueTag, Unit } from './index.js'; - -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: MetricValueTag, - }; - } -} diff --git a/u/trace/metric/index.ts b/u/trace/metric/index.ts deleted file mode 100644 index 72c37d2..0000000 --- a/u/trace/metric/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { isTagged, Tagged, type Mapper } from '@emprespresso/pengueno'; - -export enum Unit { - COUNT = 'COUNT', - MILLISECONDS = 'MILLISECONDS', -} - -export const MetricValueTag = 'MetricValue' as const; -export type MetricValueTag = typeof MetricValueTag; -export const isMetricValue = (t: unknown): t is MetricValue => isTagged(t, MetricValueTag); -export interface MetricValue extends Tagged<MetricValueTag> { - readonly name: string; - readonly unit: Unit; - readonly value: number; - readonly emissionTimestamp: number; -} - -export interface IEmittableMetric { - readonly name: string; - readonly unit: Unit; - readonly withValue: Mapper<number, MetricValue>; -} - -export const IMetricTag = 'IMetric' as const; -export type IMetricTag = typeof IMetricTag; -export const isIMetric = (t: unknown): t is IMetric => isTagged(t, IMetricTag); -export interface IMetric extends Tagged<IMetricTag> { - readonly count: IEmittableMetric; - readonly time: IEmittableMetric; - readonly parent: undefined | IMetric; -} - -export interface IResultMetric extends IMetric { - readonly failure: IMetric; - readonly success: IMetric; - readonly warn: IMetric; -} - -export * from './emittable.js'; -export * from './metric.js'; -export * from './trace.js'; diff --git a/u/trace/metric/metric.ts b/u/trace/metric/metric.ts deleted file mode 100644 index 8ef339f..0000000 --- a/u/trace/metric/metric.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { EmittableMetric, IMetric, IMetricTag, IResultMetric, Unit } from './index.js'; - -class _Tagged { - protected constructor(public readonly _tag = IMetricTag) {} -} - -export class Metric extends _Tagged implements IMetric { - private static DELIM = '.'; - - protected constructor( - public readonly name: string, - public readonly parent: undefined | IMetric = undefined, - public readonly count = new EmittableMetric(Metric.join(name, 'count'), Unit.COUNT), - public readonly time = new EmittableMetric(Metric.join(name, 'time'), Unit.MILLISECONDS), - ) { - super(); - } - - public child(_name: string): Metric { - const childName = Metric.join(this.name, _name); - return new Metric(childName, this); - } - - public asResult() { - return ResultMetric.from(this); - } - - static join(...name: Array<string>) { - return name.join(Metric.DELIM); - } - - static fromName(name: string): Metric { - return new Metric(name); - } -} - -export class ResultMetric extends Metric implements IResultMetric { - protected constructor( - public readonly name: string, - public readonly parent: undefined | IMetric = undefined, - public readonly failure: IMetric, - public readonly success: IMetric, - public readonly warn: IMetric, - ) { - super(name, parent); - } - - static from(metric: Metric) { - const failure = metric.child('failure'); - const success = metric.child('success'); - const warn = metric.child('warn'); - return new ResultMetric(metric.name, metric.parent, failure, success, warn); - } -} diff --git a/u/trace/metric/trace.ts b/u/trace/metric/trace.ts deleted file mode 100644 index 0c5fe37..0000000 --- a/u/trace/metric/trace.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { IMetric, isIMetric, isMetricValue, ITrace, ITraceWith, MetricValue, SideEffect } from '@emprespresso/pengueno'; - -export type MetricsTraceSupplier = - | ITraceWith<IMetric | MetricValue | undefined> - | Array<ITraceWith<IMetric | MetricValue | undefined>>; -export const isMetricsTraceSupplier = (t: unknown): t is MetricsTraceSupplier => - isMetricValue(t) || isIMetric(t) || (Array.isArray(t) && t.every((_m) => isMetricValue(_m) || isIMetric(_m))); - -export class MetricsTrace implements ITrace<MetricsTraceSupplier> { - constructor( - private readonly metricConsumer: SideEffect<Array<MetricValue>>, - private readonly activeTraces: ReadonlyMap<IMetric, number> = new Map(), - private readonly completedTraces: ReadonlySet<IMetric> = new Set(), - ) {} - - public traceScope(trace: MetricsTraceSupplier): MetricsTrace { - const now = Date.now(); - const metricsToTrace = (Array.isArray(trace) ? trace : [trace]).filter(isIMetric); - - const initialTraces = new Map(metricsToTrace.map((metric) => [metric, now])); - - return new MetricsTrace(this.metricConsumer, initialTraces); - } - - public trace(metrics: MetricsTraceSupplier): MetricsTrace { - if (!metrics || typeof metrics === 'string') { - return this; - } - - const now = Date.now(); - const allMetrics = Array.isArray(metrics) ? metrics : [metrics]; - - // partition the incoming metrics - const valuesToEmit = allMetrics.filter(isMetricValue); - const traceableMetrics = allMetrics.filter(isIMetric); - - const metricsToStart = traceableMetrics.filter((m) => !this.activeTraces.has(m)); - const metricsToEnd = traceableMetrics.filter((m) => this.activeTraces.has(m) && !this.completedTraces.has(m)); - - // the new metrics to emit based on traces ending *now* - const endedMetricValues = metricsToEnd.flatMap((metric) => [ - metric.count.withValue(1.0), - metric.time.withValue(now - this.activeTraces.get(metric)!), - ]); - - const allMetricsToEmit = [...valuesToEmit, ...endedMetricValues]; - if (allMetricsToEmit.length > 0) { - this.metricConsumer(allMetricsToEmit); - } - - // the next immutable state - const nextActiveTraces = new Map([ - ...this.activeTraces, - ...metricsToStart.map((m): [IMetric, number] => [m, now]), - ]); - const nextCompletedTraces = new Set([...this.completedTraces, ...metricsToEnd]); - return new MetricsTrace(this.metricConsumer, nextActiveTraces, nextCompletedTraces); - } -} |