Emits the closed, value-free telemetry surface for keyed-effect admission.
Out-of-the-box metrics attachment
The library emits events but does NOT attach a handler — a fresh application sees nothing
until it attaches one. Call attach/0 (or attach/1 with options) from your application
startup (e.g. your start/2 callback's supervised children, after the repo is started) to
attach the default handler, which routes the closed event surface into standard
Telemetry.Metrics counter and summary definitions. This mirrors Oban.Telemetry.attach_default_logger/1
and Ash.Telemetry — an opt-in helper so a consumer does not hand-roll a handler.
# in your application startup, once per VM
AshOnetime.Telemetry.attach()If you already maintain a Telemetry.Metrics reporter (StatsD, Prometheus), you may prefer
to declare the metric definitions in your own MyApp.Telemetry rather than using this
helper — see metrics/0 for the canonical definition list the helper attaches.
Summary
Functions
Emits [:ash_onetime, :admission] with :duration and result_class in
[:admitted, :rejected, :failed]. The classified outcome of an admission attempt.
Attaches the default metrics handler to the closed [:ash_onetime, *] event surface.
Emits [:ash_onetime, :cache] with result_class in
[:hit, :miss, :stale, :corrupt, :failure, :timeout, :stored, :expired, :oversized, :disabled].
The optional completed-response cache outcome for an idempotency admission.
Emits [:ash_onetime, :cleanup] with :count and result_class in
[:claims_deleted, :partitions_dropped, :partitions_created]. A bounded cleanup run.
Emits [:ash_onetime, :conflict] with result_class in
[:complete, :processing, :nonce_used, :malformed]. A collision on an in-flight or
completed claim under the same logical key.
Undoes attach/1 by detaching the handler.
Emits [:ash_onetime, :encoding] with :duration and result_class in
[:stored, :rejected, :rollback, :failed]. The outcome of encoding a response payload
for storage/replay.
Emits [:ash_onetime, :external_recovery] with :duration and result_class in
[:processing_committed, :execute_succeeded, :recover_succeeded, :absence_proven, :outcome_unknown, :external_effect_unavailable, :finalize_locked, :replayed]. The stage
outcomes of the committed external-effect recovery protocol.
Emits [:ash_onetime, :fingerprint_mismatch] with result_class: :rejected. A stored
response whose fingerprint does not match the incoming request is rejected (no replay).
The unique id used to attach the default metrics handler.
Emits [:ash_onetime, :reap] with :count and result_class: :claims_reaped. The count
of abandoned processing recovery points reaped by a bounded reaper run.
Emits [:ash_onetime, :replay] with :duration and result_class in
[:returned, :rejected]. The replayed-vs-rejected decision on a stored response.
Emits [:ash_onetime, :store_uncertainty] with result_class in
[:sent, :unknown, :disconnected, :lock_timeout, :worker_timeout]. The authoritative-state-
unavailable conditions on the committed-claim path; all fail closed (see operations.md).
Emits [:ash_onetime, :untracked_execution] with result_class: :checkout_unavailable.
An idempotent action executed without a stored admission after a checkout failure — correct
by design but worth visibility (the optional :execute_untracked path).
Emits [:ash_onetime, :verification] with :duration and result_class in
[:verified, :rejected, :timeout]. The outcome of a token/proof verification.
Functions
@spec admission(non_neg_integer(), atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :admission] with :duration and result_class in
[:admitted, :rejected, :failed]. The classified outcome of an admission attempt.
@spec attach(keyword()) :: :ok | {:error, :already_exists}
Attaches the default metrics handler to the closed [:ash_onetime, *] event surface.
The handler re-emits each event as a downstream [:ash_onetime, event, :metric] event
carrying the same atoms-only metadata and a normalized :count or :duration measurement.
This gives a consumer a single attach point to consume via their own Telemetry.Metrics
reporter or custom aggregation, without hand-rolling the event list and the count/duration
split.
The handler is a pure router — it adds no state and emits nothing the upstream validator did
not already permit, so the value-free guarantee is preserved. It does NOT depend on
telemetry_metrics; a consumer running a Telemetry.Metrics reporter declares the metric
definitions in their own MyApp.Telemetry (see the documentation/telemetry.md runnable
example for the canonical counter/summary definitions).
Idempotent per name — safe to call once at boot; a second attach with the same name
returns {:error, :already_exists} without detaching the first.
Options
:name— scope the handler to a unique id (defaultnil, one handler per VM). Use a distinct name to attach alongside another consumer's handler.
Examples
# once at boot, in your app's start/2 after the repo starts
AshOnetime.Telemetry.attach()
# attach a second, separately-scoped handler
AshOnetime.Telemetry.attach(name: :edge)
@spec cache(atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :cache] with result_class in
[:hit, :miss, :stale, :corrupt, :failure, :timeout, :stored, :expired, :oversized, :disabled].
The optional completed-response cache outcome for an idempotency admission.
@spec cleanup(atom(), module(), atom(), non_neg_integer(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :cleanup] with :count and result_class in
[:claims_deleted, :partitions_dropped, :partitions_created]. A bounded cleanup run.
@spec conflict(atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :conflict] with result_class in
[:complete, :processing, :nonce_used, :malformed]. A collision on an in-flight or
completed claim under the same logical key.
@spec detach(keyword()) :: :ok | {:error, :not_found}
Undoes attach/1 by detaching the handler.
Pass the same :name used when attaching to detach a scoped handler.
Examples
:ok = AshOnetime.Telemetry.attach()
:ok = AshOnetime.Telemetry.detach()
:ok = AshOnetime.Telemetry.attach(name: :edge)
:ok = AshOnetime.Telemetry.detach(name: :edge)
@spec encoding(non_neg_integer(), atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :encoding] with :duration and result_class in
[:stored, :rejected, :rollback, :failed]. The outcome of encoding a response payload
for storage/replay.
@spec external_recovery(non_neg_integer(), atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :external_recovery] with :duration and result_class in
[:processing_committed, :execute_succeeded, :recover_succeeded, :absence_proven, :outcome_unknown, :external_effect_unavailable, :finalize_locked, :replayed]. The stage
outcomes of the committed external-effect recovery protocol.
@spec fingerprint_mismatch(atom(), module(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :fingerprint_mismatch] with result_class: :rejected. A stored
response whose fingerprint does not match the incoming request is rejected (no replay).
The unique id used to attach the default metrics handler.
Without an argument the id is the constant "ash-onetime-default-metrics". When a name
is provided the id is suffixed with the inspected name, which allows multiple scoped
handlers (e.g. one per OTP node in a multi-node setup) to coexist.
@spec reap(atom(), module(), atom(), non_neg_integer(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :reap] with :count and result_class: :claims_reaped. The count
of abandoned processing recovery points reaped by a bounded reaper run.
@spec replay(non_neg_integer(), atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :replay] with :duration and result_class in
[:returned, :rejected]. The replayed-vs-rejected decision on a stored response.
@spec store_uncertainty(atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :store_uncertainty] with result_class in
[:sent, :unknown, :disconnected, :lock_timeout, :worker_timeout]. The authoritative-state-
unavailable conditions on the committed-claim path; all fail closed (see operations.md).
@spec untracked_execution(atom(), module(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :untracked_execution] with result_class: :checkout_unavailable.
An idempotent action executed without a stored admission after a checkout failure — correct
by design but worth visibility (the optional :execute_untracked path).
@spec verification(non_neg_integer(), atom(), module(), atom(), atom()) :: :ok | {:error, AshOnetime.Error.t()}
Emits [:ash_onetime, :verification] with :duration and result_class in
[:verified, :rejected, :timeout]. The outcome of a token/proof verification.