# `Aerospike.Telemetry`
[🔗](https://github.com/luisgabrielroldan/aerospike_driver/blob/v0.3.1/lib/aerospike/telemetry.ex#L1)

Event-name constants for the telemetry taxonomy emitted by this driver.

All events live under the `[:aerospike, ...]` namespace. Callers attach
handlers via `:telemetry.attach/4` (or `:telemetry.attach_many/4`) using
the event names returned by the functions in this module. Emitters call
`:telemetry.span/3` or emit the concrete event names directly via
`:telemetry.execute/3` with those same names.

Using the constants from here is the contract. Handler code relies on
these exact event names and metadata keys; emitters must not invent
new names or forget to route through this module.

## Span versus instant events

Functions whose name ends with `_span` return the *prefix* expected by
`:telemetry.span/3`. `:telemetry` appends `:start`, `:stop`, or
`:exception` itself, producing three event names per span:

    prefix = Aerospike.Telemetry.pool_checkout_span()
    :telemetry.span(prefix, start_metadata, fn ->
      {result, stop_metadata}
    end)

Functions without the `_span` suffix return the full event name for an
instant event dispatched via `:telemetry.execute/3`:

    :telemetry.execute(
      Aerospike.Telemetry.node_transition(),
      measurements,
      metadata
    )

Operators that want one handler for the whole driver can attach to
`handler_events/0`, which expands the current taxonomy into concrete
event names suitable for `:telemetry.attach_many/4`.

The Telemetry And Runtime Metrics guide provides the operator-facing
metadata and measurement contract for each family.

## Taxonomy

Span events (prefix + `:start | :stop | :exception`):

  * `[:aerospike, :pool, :checkout]` — wraps every per-node pool checkout.
    Metadata: `:node_name`, `:pool_pid`, `:telemetry_span_context`.
    Measurements: `:system_time` and `:monotonic_time` on start;
    `:duration` on stop and exception.

  * `[:aerospike, :command, :send]` — wraps the send side of a
    per-attempt command on the transport. Metadata: `:node_name`,
    `:attempt` (0-indexed, matching the retry driver), `:deadline_ms`.
    Measurements: `:system_time` on start; `:duration` on stop and
    exception.

  * `[:aerospike, :command, :recv]` — wraps the receive side of a
    per-attempt command. Metadata: `:node_name`, `:attempt`,
    `:deadline_ms`. Measurements: `:duration` on stop and exception,
    plus `:bytes` metadata on stop.

  * `[:aerospike, :info, :rpc]` — wraps every info RPC (Tender cycles
    and transport login/authenticate handshakes). Metadata:
    `:node_name`, `:commands` (the list of info keys requested, or
    `[:login]` for auth). Measurements: `:system_time` on start;
    `:duration` on stop and exception.

  * `[:aerospike, :tender, :tend_cycle]` — wraps one full tend cycle.
    Cluster-wide (one pair per cycle). Metadata: none. Measurements:
    `:system_time` on start; `:duration` on stop and exception.

  * `[:aerospike, :tender, :partition_map_refresh]` — wraps the
    partition-map refresh stage of the tend cycle (the most expensive
    sub-step). Cluster-wide, nested inside a `:tend_cycle` span.
    Metadata: none. Measurements: `:system_time` on start; `:duration`
    on stop and exception.

Instant events (dispatched via `:telemetry.execute/3`):

  * `[:aerospike, :node, :transition]` — lifecycle flip for a node.
    Metadata: `:node_name`, `:from` (`:active | :inactive | :unknown`),
    `:to` (same enum), `:reason` (`:bootstrap | :peer_discovery |
    :recovery | :failure_threshold | :dropped`). Measurements:
    `:system_time`.

  * `[:aerospike, :retry, :attempt]` — one event per retry attempt
    beyond the first. Metadata: `:classification` (`:rebalance |
    :transport | :circuit_open`), `:attempt`, `:node_name`.
    Measurements: `:remaining_budget_ms`.

# `event_name`

```elixir
@type event_name() :: [atom()]
```

Telemetry event name used with `:telemetry.attach/4`.

# `retry_classification`

```elixir
@type retry_classification() :: :rebalance | :transport | :circuit_open | atom()
```

Retry classification reported by `emit_retry_attempt/4`.

# `span_event_name`

```elixir
@type span_event_name() :: [atom()]
```

Concrete telemetry span event name after a suffix has been appended.

# `span_prefix`

```elixir
@type span_prefix() :: [atom()]
```

Telemetry span prefix used with `:telemetry.span/3`.

Concrete span events are produced by appending `:start`, `:stop`, or
`:exception` to this prefix.

# `command_recv_span`

```elixir
@spec command_recv_span() :: span_prefix()
```

Event prefix for the command-recv span.

Paired with the command-send span. Measurements include `:bytes`
on `:stop` so handlers can track payload size alongside latency.

# `command_send_span`

```elixir
@spec command_send_span() :: span_prefix()
```

Event prefix for the command-send span.

Wraps the send side of a single attempt against one node. Retry
iterations emit a new span per attempt; `:attempt` in metadata
distinguishes them.

# `emit_retry_attempt`

```elixir
@spec emit_retry_attempt(
  String.t() | nil,
  non_neg_integer(),
  retry_classification(),
  integer()
) :: :ok
```

Emits one retry-attempt event beyond the first command attempt.

Unary and batch executors share this helper so the retry metadata stays
aligned across execution paths.

Measurements:

  * `:remaining_budget_ms` — non-negative retry budget remaining after this
    attempt decision

Metadata:

  * `:classification` — retry reason, usually `:rebalance`, `:transport`, or
    `:circuit_open`
  * `:attempt` — zero-based attempt index
  * `:node_name` — node associated with the retry, or `nil`

# `handler_events`

```elixir
@spec handler_events() :: [span_event_name() | event_name()]
```

Returns the concrete event names operators can attach to directly.

Span prefixes are expanded to the standard `:start`, `:stop`, and
`:exception` event names, then instant events are appended.

# `info_rpc_span`

```elixir
@spec info_rpc_span() :: span_prefix()
```

Event prefix for the info-RPC span.

Covers Tender info calls and transport login/authenticate RPCs.
Metadata `:commands` carries the list of info keys, or `[:login]`
for auth handshakes.

# `instant_event_names`

```elixir
@spec instant_event_names() :: [event_name()]
```

Returns every instant-event name in the supported telemetry taxonomy.

# `node_transition`

```elixir
@spec node_transition() :: event_name()
```

Event name for a node lifecycle transition.

Instant event dispatched via `:telemetry.execute/3`. Metadata carries
`:from`, `:to`, `:reason`, and `:node_name`.

# `partition_map_refresh_span`

```elixir
@spec partition_map_refresh_span() :: span_prefix()
```

Event prefix for the partition-map-refresh span.

Wraps the `maybe_refresh_partition_maps/1` stage specifically so
operators can separate fetching partition-generation from decoding
the full replicas payload.

# `pool_checkout_span`

```elixir
@spec pool_checkout_span() :: span_prefix()
```

Event prefix for the pool-checkout span.

This prefix names the checkout telemetry family. The current emitter
dispatches the concrete `:start`, `:stop`, and `:exception` names
directly so it can keep the same metadata on every suffix.

# `retry_attempt`

```elixir
@spec retry_attempt() :: event_name()
```

Event name for a retry attempt beyond the first.

Instant event dispatched via `:telemetry.execute/3`. Metadata carries
the retry classification, attempt index, and node name.

# `span_prefixes`

```elixir
@spec span_prefixes() :: [span_prefix()]
```

Returns every span prefix in the supported telemetry taxonomy.

This is the stable list for code that needs to derive concrete
`:start`/`:stop`/`:exception` event names without hard-coding them in
multiple places.

# `tend_cycle_span`

```elixir
@spec tend_cycle_span() :: span_prefix()
```

Event prefix for the tend-cycle span.

Wraps one tend-cycle invocation. The partition map refresh is a nested span;
both fire during a normal cycle.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
