SuperCache.Cluster.Metrics (SuperCache v1.3.0)

Copy Markdown View Source

Low-overhead counter and latency-sample store for SuperCache observability.

All state is held in a single :public ETS table owned by this GenServer. Writes use update_counter/3 (atomic) and are safe to call from any process without coordination overhead.

Counter keys

Counters are stored as {namespace, field} tuples:

{:tpc, :committed}
{:tpc, :aborted}
{:api, :put}, :calls}          # note: nested via get_all/1
{{:api, :put}, :errors}

Latency samples

Latency ring buffers are stored as {:latency, key} records holding a list of the most recent @max_samples microsecond values. The list is bounded so memory usage is constant regardless of call volume.

Usage

# In Router / Replicator — after an operation completes:
Metrics.increment({:api, :put}, :calls)
Metrics.push_latency({:api_latency_us, :put}, elapsed_us)

# Reading back:
Metrics.get_all({:api, :put})
# => %{calls: 1_200, errors: 2}

Metrics.get_latency_samples({:api_latency_us, :put})
# => [45, 110, 88, ...]

Summary

Functions

Returns a specification to start this module under a supervisor.

Return all counters for namespace as %{field => count}.

Return all latency samples for key (unordered).

Atomically increment counter field under namespace by 1.

Push a latency sample (microseconds) into the ring buffer for key.

Reset all counters and latency samples for namespace.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_all(namespace)

@spec get_all(term()) :: map()

Return all counters for namespace as %{field => count}.

get_latency_samples(key)

@spec get_latency_samples(term()) :: [non_neg_integer()]

Return all latency samples for key (unordered).

increment(namespace, field)

@spec increment(term(), atom()) :: integer()

Atomically increment counter field under namespace by 1.

push_latency(key, value_us)

@spec push_latency(term(), non_neg_integer()) :: :ok

Push a latency sample (microseconds) into the ring buffer for key.

The buffer is capped at 256 entries; oldest samples are dropped when the cap is reached.

reset(namespace)

@spec reset(term()) :: :ok

Reset all counters and latency samples for namespace.

start_link(opts)