Otel.TelemetryReporter (otel v0.3.0)

Copy Markdown View Source

Telemetry.Metrics reporter that bridges BEAM :telemetry events into the OTel Metrics pipeline. Mirror of Otel.LoggerHandler for the metrics pillar.

Add it to your supervision tree with a list of Telemetry.Metrics definitions:

defmodule MyApp.Application do
  use Application

  @impl true
  def start(_type, _args) do
    children = [
      {Otel.TelemetryReporter, metrics: metrics()}
    ]
    Supervisor.start_link(children, strategy: :one_for_one)
  end

  defp metrics do
    import Telemetry.Metrics

    [
      counter("phoenix.endpoint.stop.duration"),
      summary("phoenix.endpoint.stop.duration",
        unit: {:native, :millisecond}
      ),
      last_value("vm.memory.total", unit: {:byte, :kilobyte})
    ]
  end
end

Type mapping

Telemetry.MetricsOTel instrumentdispatch
counter/2Otel.Metrics.CounterCounter.add(inst, 1, attrs) — measurement ignored
sum/2Otel.Metrics.UpDownCounterUpDownCounter.add(inst, value, attrs)
last_value/2Otel.Metrics.GaugeGauge.record(inst, value, attrs)
summary/2Otel.Metrics.HistogramHistogram.record(inst, value, attrs)
distribution/2Otel.Metrics.HistogramHistogram.record(inst, value, attrs) (uses buckets)

Telemetry.Metrics.Sum carries no monotonic flag, so the reporter conservatively maps it to UpDownCounter. If your source values are guaranteed non-negative and you want monotonic Sum semantics, pass reporter_options: [monotonic: true]:

sum("http.request.bytes_sent", reporter_options: [monotonic: true])

Tags / tag_values

metric.tags selects which metadata keys to use as OTel attribute keys; metric.tag_values (default identity) can pre-process metadata before extraction. Tag values are string-coerced (atoms via Atom.to_string/1, others kept as-is) on dispatch.

Unit conversion

Unit conversion is performed by Telemetry.Metrics itself at metric-definition time: when you pass unit: {from, to}, the metric's :measurement field is wrapped to convert values into the target unit before they reach this reporter. We forward the resulting target-unit atom (e.g. :millisecond, :kilobyte) to the OTel instrument's unit field. Note byte conversions are decimal per Telemetry.Metrics convention (1 kB = 1000 B).

:keep / :drop predicates

Honored per Telemetry.Metrics: when :keep returns false or :drop returns true, the measurement is skipped — the OTel instrument is not updated.

Lifecycle

The reporter is a GenServer with trap_exit: true. Each registered telemetry event gets a :telemetry.attach keyed by {__MODULE__, event_name, self()}. On terminate/2 (supervisor shutdown), every handler is detached so reloads / restarts don't leave dangling handlers.

References

Summary

Functions

Returns a specification to start this module under a supervisor.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)

@spec start_link(opts :: keyword()) :: GenServer.on_start()