From 8ca563c08183d4ed42ff974bb76deede5832d60b Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 21 Mar 2024 11:03:43 +1300 Subject: [PATCH] add preregisteredWords options to frequency metric key type (#2377) --- .changeset/breezy-countries-warn.md | 16 ++++++++++++++++ packages/effect/src/Metric.ts | 11 +++++++++-- packages/effect/src/MetricKey.ts | 10 +++++++++- packages/effect/src/MetricKeyType.ts | 7 ++++++- packages/effect/src/internal/metric.ts | 6 ++++-- packages/effect/src/internal/metric/hook.ts | 5 ++++- packages/effect/src/internal/metric/key.ts | 7 +++++-- packages/effect/src/internal/metric/keyType.ts | 7 +++++-- 8 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 .changeset/breezy-countries-warn.md diff --git a/.changeset/breezy-countries-warn.md b/.changeset/breezy-countries-warn.md new file mode 100644 index 0000000000..3eb581fd2b --- /dev/null +++ b/.changeset/breezy-countries-warn.md @@ -0,0 +1,16 @@ +--- +"effect": minor +--- + +add preregisteredWords option to frequency metric key type + +You can use this to register a list of words to pre-populate the value of the +metric. + +```ts +import { Metric } from "effect"; + +const counts = Metric.frequency("counts", { + preregisteredWords: ["a", "b", "c"], +}).register(); +``` diff --git a/packages/effect/src/Metric.ts b/packages/effect/src/Metric.ts index 1d30359719..9a865186c8 100644 --- a/packages/effect/src/Metric.ts +++ b/packages/effect/src/Metric.ts @@ -208,12 +208,19 @@ export const counter: { * @example * import * as Metric from "effect/Metric" * - * const errorFrequency = Metric.frequency("error_frequency", "Counts the occurrences of errors."); + * const errorFrequency = Metric.frequency("error_frequency", { + * description: "Counts the occurrences of errors." + * }); * * @since 2.0.0 * @category constructors */ -export const frequency: (name: string, description?: string) => Metric.Frequency = internal.frequency +export const frequency: ( + name: string, + options?: + | { readonly description?: string | undefined; readonly preregisteredWords?: ReadonlyArray | undefined } + | undefined +) => Metric.Frequency = internal.frequency /** * Returns a new metric that is powered by this one, but which accepts updates diff --git a/packages/effect/src/MetricKey.ts b/packages/effect/src/MetricKey.ts index fb99721752..d7fadf4add 100644 --- a/packages/effect/src/MetricKey.ts +++ b/packages/effect/src/MetricKey.ts @@ -132,7 +132,15 @@ export const counter: { * @since 2.0.0 * @category constructors */ -export const frequency: (name: string, description?: string) => MetricKey.Frequency = internal.frequency +export const frequency: ( + name: string, + options?: + | { + readonly description?: string | undefined + readonly preregisteredWords?: ReadonlyArray | undefined + } + | undefined +) => MetricKey.Frequency = internal.frequency /** * Creates a metric key for a gauge, with the specified name. diff --git a/packages/effect/src/MetricKeyType.ts b/packages/effect/src/MetricKeyType.ts index b5c2bbdeb6..ed325d8d5d 100644 --- a/packages/effect/src/MetricKeyType.ts +++ b/packages/effect/src/MetricKeyType.ts @@ -113,6 +113,7 @@ export declare namespace MetricKeyType { */ export type Frequency = MetricKeyType & { readonly [FrequencyKeyTypeTypeId]: FrequencyKeyTypeTypeId + readonly preregisteredWords: ReadonlyArray } /** @@ -193,7 +194,11 @@ export const counter: () => MetricKeyType.Counter * @since 2.0.0 * @category constructors */ -export const frequency: MetricKeyType.Frequency = internal.frequency +export const frequency: ( + options?: { + readonly preregisteredWords?: ReadonlyArray | undefined + } | undefined +) => MetricKeyType.Frequency = internal.frequency /** * @since 2.0.0 diff --git a/packages/effect/src/internal/metric.ts b/packages/effect/src/internal/metric.ts index c32a809f42..e434b7d79d 100644 --- a/packages/effect/src/internal/metric.ts +++ b/packages/effect/src/internal/metric.ts @@ -98,8 +98,10 @@ export const counter: { } = (name, options) => fromMetricKey(metricKey.counter(name, options as any)) as any /** @internal */ -export const frequency = (name: string, description?: string): Metric.Metric.Frequency => - fromMetricKey(metricKey.frequency(name, description)) +export const frequency = (name: string, options?: { + readonly description?: string | undefined + readonly preregisteredWords?: ReadonlyArray | undefined +}): Metric.Metric.Frequency => fromMetricKey(metricKey.frequency(name, options)) /** @internal */ export const withConstantInput = dual< diff --git a/packages/effect/src/internal/metric/hook.ts b/packages/effect/src/internal/metric/hook.ts index 1c27f78dff..8b70d21489 100644 --- a/packages/effect/src/internal/metric/hook.ts +++ b/packages/effect/src/internal/metric/hook.ts @@ -78,8 +78,11 @@ export const counter = ( } /** @internal */ -export const frequency = (_key: MetricKey.MetricKey.Frequency): MetricHook.MetricHook.Frequency => { +export const frequency = (key: MetricKey.MetricKey.Frequency): MetricHook.MetricHook.Frequency => { const values = new Map() + for (const word of key.keyType.preregisteredWords) { + values.set(word, 0) + } const update = (word: string) => { const slotCount = values.get(word) ?? 0 values.set(word, slotCount + 1) diff --git a/packages/effect/src/internal/metric/key.ts b/packages/effect/src/internal/metric/key.ts index 9f9de16287..69e2307809 100644 --- a/packages/effect/src/internal/metric/key.ts +++ b/packages/effect/src/internal/metric/key.ts @@ -83,8 +83,11 @@ export const counter: { ) /** @internal */ -export const frequency = (name: string, description?: string): MetricKey.MetricKey.Frequency => - new MetricKeyImpl(name, metricKeyType.frequency, Option.fromNullable(description)) +export const frequency = (name: string, options?: { + readonly description?: string | undefined + readonly preregisteredWords?: ReadonlyArray | undefined +}): MetricKey.MetricKey.Frequency => + new MetricKeyImpl(name, metricKeyType.frequency(options), Option.fromNullable(options?.description)) /** @internal */ export const gauge: { diff --git a/packages/effect/src/internal/metric/keyType.ts b/packages/effect/src/internal/metric/keyType.ts index af902c8aae..39e52ccc7b 100644 --- a/packages/effect/src/internal/metric/keyType.ts +++ b/packages/effect/src/internal/metric/keyType.ts @@ -86,7 +86,8 @@ const FrequencyKeyTypeHash = Hash.string(FrequencyKeyTypeSymbolKey) /** @internal */ class FrequencyKeyType implements MetricKeyType.MetricKeyType.Frequency { readonly [MetricKeyTypeTypeId] = metricKeyTypeVariance - readonly [FrequencyKeyTypeTypeId]: MetricKeyType.FrequencyKeyTypeTypeId = FrequencyKeyTypeTypeId; + readonly [FrequencyKeyTypeTypeId]: MetricKeyType.FrequencyKeyTypeTypeId = FrequencyKeyTypeTypeId + constructor(readonly preregisteredWords: ReadonlyArray) {} [Hash.symbol](): number { return FrequencyKeyTypeHash } @@ -192,7 +193,9 @@ export const counter: (options?: { * @since 2.0.0 * @category constructors */ -export const frequency: MetricKeyType.MetricKeyType.Frequency = new FrequencyKeyType() +export const frequency = (options?: { + readonly preregisteredWords?: ReadonlyArray | undefined +}): MetricKeyType.MetricKeyType.Frequency => new FrequencyKeyType(options?.preregisteredWords ?? []) /** * @since 2.0.0