Synchronous Counter instrument facade (OTel
metrics/api.md §Counter, Status: Stable, L497-L598).
A Counter supports monotonically increasing non-negative increments recorded synchronously at the call site (spec L499-L500). Example uses: bytes received, requests completed, accounts created, HTTP 5xx error counts (spec L504-L508).
Created exclusively through a Meter per spec L512
"MUST NOT be any API for creating a Counter other than
with a Meter".
Non-negative value contract
Per spec L561-L564, the increment value is expected to be non-negative. The API:
- SHOULD be documented to communicate the non-negative expectation (satisfied here)
- SHOULD NOT validate — validation is the SDK's responsibility
A negative value passed to add/3 will be accepted at
the API boundary and forwarded to the SDK, which decides
how to handle it. If the domain supports bidirectional
motion, use Otel.Metrics.UpDownCounter instead.
BEAM representation
opentelemetry-erlang implements this as a defmacro
that resolves the meter implicitly via
opentelemetry_experimental:get_meter/1 at expansion
time and injects OpenTelemetry.Ctx.get_current() into
:otel_counter.add/5 (lib/open_telemetry/counter.ex).
We take a different path:
- plain
defwith an explicitMeter.t()handle — macro-free, Dialyzer-visible, consistent with theTracerandMeterfacades project-wide - no implicit context threaded through
add/3— synchronous metric measurements are not context-associated at the API boundary; the SDK attaches context perOtel.Ctxif relevant
All functions are safe for concurrent use (spec L1351-L1352, §Concurrency §Instrument).
Public API
| Function | Role |
|---|---|
create/3 | Application (OTel API MUST) — Counter creation (L510-L542) |
add/3 | Application (OTel API MUST) — Counter Add (L545-L598) |
References
- OTel Metrics API §Counter:
opentelemetry-specification/specification/metrics/api.mdL497-L598 - OTel Metrics API §Synchronous Instrument API:
opentelemetry-specification/specification/metrics/api.mdL302-L348 - OTel Metrics API §Concurrency §Instrument:
opentelemetry-specification/specification/metrics/api.mdL1351-L1352
Summary
Functions
Application (OTel API MUST) — "Add" (metrics/api.md
§Counter operations — Add, L545-L598).
Application (OTel API MUST) — "Counter creation"
(metrics/api.md §Counter creation, L510-L542).
Types
@type primitive_any() :: primitive() | [primitive_any()] | %{required(String.t()) => primitive_any()}
Functions
@spec add( instrument :: Otel.Metrics.Instrument.t(), value :: number(), attributes :: %{required(String.t()) => primitive_any()} ) :: :ok
Application (OTel API MUST) — "Add" (metrics/api.md
§Counter operations — Add, L545-L598).
Increments the Counter by value. Per spec L561-L564 the
value is expected to be non-negative; the API does not
validate (SHOULD NOT validate per spec — SDK's job).
Attributes default to %{} per spec L565-L570 "MUST be
structured to accept a variable number of attributes,
including none".
Delegates to Otel.Metrics.Meter.record/3 — both
Counter.add and the synchronous siblings share a single
Meter dispatch.
@spec create( name :: String.t(), opts :: Otel.Metrics.Instrument.create_opts() ) :: Otel.Metrics.Instrument.t()
Application (OTel API MUST) — "Counter creation"
(metrics/api.md §Counter creation, L510-L542).
Creates the instrument handle via the given Meter. Per spec L512, there is no other API surface for creating a Counter.
Options (per §Synchronous Instrument API L302-L348):
:unit— case-sensitive ASCII string, max 63 chars:description— opaque string (BMP Plane 0), at least 1023 chars supported:advisory— advisory parameters
Delegates to Otel.Metrics.Meter.create_counter/3.