Otel.Metrics.Counter (otel v0.4.1)

Copy Markdown View Source

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 def with an explicit Meter.t() handle — macro-free, Dialyzer-visible, consistent with the Tracer and Meter facades project-wide
  • no implicit context threaded through add/3 — synchronous metric measurements are not context-associated at the API boundary; the SDK attaches context per Otel.Ctx if relevant

All functions are safe for concurrent use (spec L1351-L1352, §Concurrency §Instrument).

Public API

FunctionRole
create/3Application (OTel API MUST) — Counter creation (L510-L542)
add/3Application (OTel API MUST) — Counter Add (L545-L598)

References

  • OTel Metrics API §Counter: opentelemetry-specification/specification/metrics/api.md L497-L598
  • OTel Metrics API §Synchronous Instrument API: opentelemetry-specification/specification/metrics/api.md L302-L348
  • OTel Metrics API §Concurrency §Instrument: opentelemetry-specification/specification/metrics/api.md L1351-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

primitive()

@type primitive() ::
  String.t() | {:bytes, binary()} | boolean() | integer() | float() | nil

primitive_any()

@type primitive_any() ::
  primitive() | [primitive_any()] | %{required(String.t()) => primitive_any()}

Functions

add(instrument, value, attributes \\ %{})

@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.

create(name, opts \\ [])

@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.