DeutschGitHub
prototypepackages/prom-metrics-decorator/src

Prometheus Metrics Decorator

@ralphschuler/prom-metrics-decorator

Reuses named metrics and records counters, gauges, histograms and summaries.

Prometheusdecoratorsmetrics

01 · Problem

What is it for?

Recreating a named metric on every call causes registry conflicts and loses a stable measurement contract.

02 · Mental model

How should you think about it?

Create each metric once, then record events through its correct operation: inc, set or observe.

In this repository

Reuses named metrics and records counters, gauges, histograms and summaries. Legacy decorators require compatible TypeScript settings. Labels must have bounded cardinality; class decoration exposes a metric handle.

03 · Control flow

What happens in which order?

  1. Create or resolve the metric once.
  2. Wrap the target operation.
  3. Count a call or await its numeric result.
  4. Use the metric-specific recording method.
  5. Preserve original results and errors.

04 · Building blocks

The important contracts

PromCounter / PromGauge / PromHistogram / PromSummaryCreate reusable call or value instrumentation.
TrackOption / IMetricConfigChoose semantics, labels and metric configuration.

05 · Build it yourself

Implement a small core

Start with this small independent implementation, then use the steps below to make its contract explicit.

  1. Create or resolve the metric once.
  2. Wrap the target operation.
  3. Count a call or await its numeric result.
  4. Use the metric-specific recording method.
  5. Preserve original results and errors.
Concept sketch · may reference omitted helpers
type Counter = { inc(labels?: Record<string, string>): void };

function countCalls<A extends unknown[], R>(
  counter: Counter,
  run: (...args: A) => R,
) {
  return function (this: unknown, ...args: A): R {
    counter.inc();
    return run.apply(this, args);
  };
}

06 · Verify

What should you test?

  • Invoke an instrumented method repeatedly without duplicate registration.
  • Verify histogram and summary observe values.
  • Keep property values independent between instances.

Try it yourself

Turn the first verification claim into a failing test, implement the smallest fix, then add a boundary case.

Invoke an instrumented method repeatedly without duplicate registration.

Compare your approach

Your check should fail when the stated invariant is deliberately broken, and pass again after the fix. Keep setup deterministic and assert an observable result.

07 · Limits

Trade-offs and failure modes

  • Labels with unbounded values create excessive series.
  • Metric recording must not change method return semantics.
  • Decorator support depends on the configured TypeScript mode.
Important

Legacy decorators require compatible TypeScript settings. Labels must have bounded cardinality; class decoration exposes a metric handle.

08 · Keep exploring

Source code and related ideas

yarn tsx packages/prom-metrics-decorator/examples/basic.ts