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

Metric data model — one metric record produced by
`Otel.Metrics.MetricExporter.collect/1` and consumed by
`Otel.OTLP.Encoder.encode_metrics/1` (`metrics/data-model.md`
§Metric L300-L391; Status: **Stable**).

Sibling to `Otel.Trace.Span` (Trace) and `Otel.Logs.LogRecord`
(Logs) — the unit that crosses the SDK→encoder boundary for
the Metrics pillar.

Unlike Span / LogRecord — which are constructed at the
*producer* side and flow through storage to the exporter —
the Metric struct is **transient**: producers (`Counter.add`,
`Histogram.record`, etc.) mutate per-attribute aggregation
cells in `MetricsStorage`, and `MetricExporter.collect/1`
builds Metric records on the fly by walking
`InstrumentsStorage` and reading the latest aggregation
snapshots from `MetricsStorage`. The struct exists only
between `collect/1` and `encode_metrics/1`.

Construct via `Otel.Metrics.Metric.new/1` — the canonical
constructor that fills proto3-aligned defaults plus
runtime-derived `scope` / `resource`.

## Field defaults — proto3-aligned

| Field | Default | Basis |
|---|---|---|
| `name` | `""` | proto `string`; `metrics.proto` Metric.name |
| `description` | `""` | proto `string`; `metrics.proto` Metric.description |
| `unit` | `""` | proto `string`; `metrics.proto` Metric.unit |
| `scope` | `Otel.InstrumentationScope.new()` | always overwritten by `collect/1` with the stream's instrument scope |
| `resource` | `Otel.Resource.new()` | always overwritten by `collect/1` with `meter_config.resource` |
| `kind` | `nil` | always populated; no spec-aligned default exists |
| `temporality` | `nil` | nil for Gauge / LastValue per `data-model.md` §Temporality (gauges have no aggregation temporality) |
| `is_monotonic` | `nil` | nil for non-Sum aggregations; `true` only for `Counter`, `false` for `UpDownCounter` |
| `datapoints` | `[]` | proto `repeated`; empty when no measurements were recorded for the stream in the collect window |

## References

- OTel Metrics Data Model §Metric: `opentelemetry-specification/specification/metrics/data-model.md` L300-L391
- OTLP proto `Metric`: `opentelemetry-proto/opentelemetry/proto/metrics/v1/metrics.proto`

# `t`

```elixir
@type t() :: %Otel.Metrics.Metric{
  datapoints: [Otel.Metrics.Aggregation.datapoint()],
  description: String.t(),
  is_monotonic: boolean() | nil,
  kind: Otel.Metrics.Instrument.kind() | nil,
  name: String.t(),
  resource: Otel.Resource.t(),
  scope: Otel.InstrumentationScope.t(),
  temporality: Otel.Metrics.Instrument.temporality() | nil,
  unit: String.t()
}
```

# `new`

```elixir
@spec new(opts :: map()) :: t()
```

**SDK** — Construct a Metric. Caller provides at least
`name`, `kind`, and `datapoints` via `opts`; remaining
fields default to proto3 zero values plus runtime-derived
`scope` / `resource`.

---

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