OtelTelemetryMetrics (otel_telemetry_metrics v0.1.0)

BASED ON THIS PR: https://github.com/open-telemetry/opentelemetry-erlang-contrib/pull/303

If we can get this generally working, it would be nice to contribute the changes back.

OtelTelemetryMetrics.start_link/1 creates OpenTelemetry Instruments for Telemetry.Metric metrics and records to them when their corresponding events are triggered.

metrics = [
  last_value("vm.memory.binary", unit: :byte),
  counter("vm.memory.total"),
  counter("db.query.duration", tags: [:table, :operation]),
  summary("http.request.response_time",
    tag_values: fn
      %{foo: :bar} -> %{bar: :baz}
    end,
    tags: [:bar],
    drop: fn metadata ->
      metadata[:boom] == :pow
    end
  ),
  sum("telemetry.event_size.metadata",
    measurement: &__MODULE__.metadata_measurement/2
  ),
  distribution("phoenix.endpoint.stop.duration",
    measurement: &__MODULE__.measurement/1
  )
]

{:ok, _} = OtelTelemetryMetrics.start_link([metrics: metrics])

Then either in your Application code or a dependency execute telemetry events conataining the measurements. For example, an event that will result in the metrics vm.memory.total and vm.memory.binary being recorded to:

:telemetry.execute([:vm, :memory], %{binary: 100, total: 200}, %{})

OpenTelemetry does not support a summary type metric, the summary http.request.response_time is recorded as a single bucket histogram.

In Telemetry.Metrics the counter type refers to counting the number of times an event is triggered, this is represented as a sum in OpenTelemetry and when recording the value is sent as a 1 every time.

Metrics of type last_value are ignored because last_value is not yet an aggregation supported on synchronous instruments in Erlang/Elixir OpenTelemetry. When it is added to the SDK this library will be updated to no longer ignore metrics of this type.

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.

handle_event(event_name, measurements, metadata, map)

start_link(options)