# `Otel.Metrics.Meter`
[🔗](https://github.com/yangbancode/otel/blob/main/lib/otel/metrics/meter.ex#L1)

SDK implementation of the `Otel.Metrics.Meter`
behaviour (`metrics/sdk.md` §Meter L870-L943).

Handles instrument creation with case-insensitive duplicate detection.
Instruments are stored in the `Otel.Metrics.InstrumentsStorage`
ETS table; the GenServer that owns it is started by
`Otel.Application.start/2`.

All functions are safe for concurrent use, satisfying spec
`metrics/sdk.md` L1351-L1352 — *"Instrument — synchronous and
asynchronous instrument operations MUST be safe to be called
concurrently."*

## Public API

| Callback | Role |
|---|---|
| `create_*` (counter, histogram, gauge, updown_counter) | **SDK** (OTel API MUST) — `metrics/api.md` §Instruments |
| `record/3` | **SDK** (OTel API MUST) — synchronous instrument measurement |

Asynchronous (Observable) instruments are intentionally not
implemented — minikube targets the BEAM-native `:telemetry`
ecosystem for poll-based measurements (see project memory
`project_pivot_beginner_focused.md`). A telemetry-handler
bridge (analogous to `Otel.LoggerHandler`) is planned but not
part of this module.

## Design notes

### Duplicate registration

`register_instrument/3` keys instruments by
`downcased_name` and uses `:ets.insert_new/2` so the
first registration wins. Subsequent `create_*` calls for the same
key return the already-stored struct unchanged. This satisfies the
case-insensitive identity requirement of
`metrics/sdk.md` L945-L958 *"The name of an Instrument is defined to
be case-insensitive."*.

The spec's SHOULD-log clauses for identifying-field conflicts
(`sdk.md` L904-L958, L990) are not currently emitted; a caller
that re-creates an instrument with a different `kind`, `unit`,
or `description` gets the original instrument back silently. This
matches the project's happy-path policy and will be revisited in
the finalization error-handling pass.

### Aggregation / bucket boundaries

Each instrument carries a hardcoded `aggregation_module`
derived from `:kind` at registration (Counter →
`Sum`, Histogram → `ExplicitBucketHistogram`, etc.).
`metrics/sdk.md` L1003-L1005 advisory
`:explicit_bucket_boundaries` flow into the histogram
aggregation's `aggregation_opts` when present.

## References

- OTel Metrics SDK §Meter: `opentelemetry-specification/specification/metrics/sdk.md` L870-L943
- OTel Metrics API §Meter: `opentelemetry-specification/specification/metrics/api.md` L156-L499

# `create_counter`

# `create_gauge`

# `create_histogram`

# `create_updown_counter`

# `record`

---

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