defmodule Microwaveprop.Instrument do
  @moduledoc """
  Thin wrapper around `:telemetry.span/3` so the rest of the codebase can
  instrument a block of work with a single call:

      Instrument.span([:hrrr, :fetch_grid], %{points: length(points)}, fn ->
        HrrrClient.fetch_grid(points, valid_time)
      end)

  Emits `[:microwaveprop | event_suffix] ++ [:start|:stop|:exception]`
  with the automatic `duration` measurement, so metrics registered in
  `MicrowavepropWeb.Telemetry` can key off the same prefix.
  """

  @type event_suffix :: [atom(), ...]

  @spec span(event_suffix(), map(), (-> term())) :: term()
  def span(event_suffix, metadata \\ %{}, fun) when is_list(event_suffix) and is_function(fun, 0) do
    event = [:microwaveprop | event_suffix]

    :telemetry.span(event, metadata, fn ->
      result = fun.()
      {result, Map.put(metadata, :result, :ok)}
    end)
  end
end
