Class ResilienceMetrics

java.lang.Object
com.tnsai.resilience.ResilienceMetrics

public final class ResilienceMetrics extends Object
In-memory metrics registry for @Metered actions (issue #173, Phase 1).

Records per-metric-name counters (total, success, failure) and an optional latency histogram. Tests can snapshot any metric via snapshot(java.lang.String); production code reads aggregates via the same API. Phase 2 ships a MetricsSink SPI that lets consumers route the same emissions to Micrometer / Prometheus / OpenTelemetry without changing this class's contract.

Why in-memory in Phase 1

The Phase-1 boundary across this sprint (#171 / #172 / #177 / #173) is "no external storage / no distributed-state SPI". An in-memory registry keyed by metric name is correct for single-instance deployments and safe for tests; multi-node aggregation needs the Phase-2 sink SPI to fan out.

Thread safety

ConcurrentHashMap for the metric map, LongAdder for hot-path counters (better than AtomicLong under contention), ReentrantLock around histogram array mutation. Snapshot reads are point-in-time — concurrent writes during a snapshot are visible-or-not without tearing.
Since:
0.5.4 (issue #173, Phase 1)
  • Method Details

    • getInstance

      public static ResilienceMetrics getInstance()
      Singleton — Phase 1 has no SPI fan-out, one registry per JVM.
    • record

      public void record(String name, boolean success, long durationMs, boolean histogram)
      Records a single action invocation.
      Parameters:
      name - the metric name (defaults to class.method when blank)
      success - whether the action returned normally
      durationMs - measured wall-clock duration in milliseconds
      histogram - whether to bucket the duration into the latency histogram (mirrors @Metered.histogram())
    • snapshot

      Snapshots the current state of name, or empty if it was never recorded.
    • snapshotAll

      public List<ResilienceMetrics.MetricSnapshot> snapshotAll()
      Snapshots every recorded metric. Order: insertion (per ConcurrentHashMap iteration).
    • resetForTesting

      public void resetForTesting()
      Test hook — drops every recorded metric. Production code should never call this; tests use it between cases to prevent cross-test contamination.