# `Snodo.Instrumentation`
[🔗](https://github.com/joshrotenberg/snodo/blob/v0.2.0/lib/snodo/instrumentation.ex#L1)

Optional, dependency-free lifecycle instrumentation.

Instrumentation sinks receive telemetry-shaped event names, numeric
measurements, and deliberately bounded metadata. Sink failures are isolated:
observability cannot change protocol, transport, or Tasks behavior.

A sink may bridge events to `:telemetry`, OpenTelemetry, Logger, a metrics
process, or a test collector without making any of those systems a framework
dependency.

# `config`

```elixir
@type config() :: module() | {module(), term()} | Snodo.Instrumentation.Config.t()
```

# `event_name`

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

# `handle_event`

```elixir
@callback handle_event(
  event_name(),
  measurements :: map(),
  metadata :: map(),
  options :: term()
) :: term()
```

# `emit`

```elixir
@spec emit(Snodo.Instrumentation.Config.t() | nil, event_name(), map(), map()) :: :ok
```

Emits one event and isolates every sink failure.

# `normalize!`

```elixir
@spec normalize!(config() | nil) :: Snodo.Instrumentation.Config.t() | nil
```

Normalizes and validates an optional sink configuration.

---

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