Dependency-free in-memory aggregator for x402 telemetry events.
For deployments without LiveDashboard or a Telemetry.Metrics reporter:
attach/1 subscribes to every event in X402.Telemetry.events/0 and
keeps per-event counters (total and per status) plus simple latency
statistics for span events that carry a :duration measurement, in a
lazily created ETS table. snapshot/1 reads them back:
:ok = X402.Telemetry.Stats.attach()
# ... traffic ...
X402.Telemetry.Stats.snapshot()
#=> %{
# [:x402, :plug, :payment_verified] => %{count: 42, by_status: %{}, latency: nil},
# [:x402, :facilitator, :verify, :stop] => %{
# count: 42,
# by_status: %{ok: 40, error: 2},
# latency: %{count: 42, min_us: 812, max_us: 9_120, mean_us: 2_310, sum_us: 97_020}
# },
# ...
# }Status is read from the :status metadata (:ok / :error events) or
derived from :success (facilitator spans). Counters are ETS atomics;
latency minima and maxima are compare-and-swap updates, so concurrent
events never lose samples.
The table needs no supervision. Call detach/1 to stop aggregating and
drop it, or reset/1 to zero the counters while attached.
Summary
Types
Aggregated statistics for one event.
Latency statistics in microseconds for span events.
Snapshot of every event seen since attaching (or the last reset).
Functions
Attaches the aggregator to the x402 telemetry events.
Detaches the aggregator and drops its table.
Zeroes every counter while staying attached.
Returns the aggregated statistics per event.
Types
@type event_stats() :: %{ count: non_neg_integer(), by_status: %{optional(atom()) => non_neg_integer()}, latency: latency() | nil }
Aggregated statistics for one event.
@type latency() :: %{ count: pos_integer(), min_us: non_neg_integer(), max_us: non_neg_integer(), mean_us: non_neg_integer(), sum_us: non_neg_integer() }
Latency statistics in microseconds for span events.
@type snapshot() :: %{optional(X402.Telemetry.event()) => event_stats()}
Snapshot of every event seen since attaching (or the last reset).
Functions
@spec attach(keyword()) :: :ok | {:error, :already_attached}
Attaches the aggregator to the x402 telemetry events.
Returns {:error, :already_attached} when a handler for :name exists.
Options
:name(atom/0) - ETS table name (also used to derive the telemetry handler id). The default value isX402.Telemetry.Stats.:events(list of list ofatom/0) - Events to aggregate. Defaults toX402.Telemetry.events/0.
@spec detach(atom()) :: :ok
Detaches the aggregator and drops its table.
@spec reset(atom()) :: :ok
Zeroes every counter while staying attached.
Returns the aggregated statistics per event.
Events that were never observed are absent from the map.