Help with implementing a macro

I wish I could give multiple likes! Thank you for the detailed response and education. It helped me solve my problem :blush:

Below is a working version of my macro. I am dropping this in my test module to simulate Phoenix’s Instrumentation API so I can test my instrumenter:

defmodule Phoenix.Endpoint do

  defmacro instrument(event, runtime \\ Macro.escape(%{}), fun) do
    compile = Macro.escape(strip_caller(__ENV__))

    quote do
      result = NewRelix.Instrumenter.unquote(event)(:start, unquote(compile),
        unquote(runtime))
      start = :erlang.monotonic_time()
      try do
        unquote(fun).()
      after
        diff = :erlang.monotonic_time() - start
        NewRelix.Instrumenter.unquote(event)(:stop, diff, result)
      end
    end
  end

  defp strip_caller(%Macro.Env{module: mod, function: fun, file: file,
                                                            line: line}) do
    %{module: mod, function: form_fa(fun), file: file, line: line}
  end

  defp form_fa({name, arity}) do
    Atom.to_string(name) <> "." <> Integer.to_string(arity)
  end
  defp form_fa(nil), do: nil
end

I can then use it in my test like-so:

require __MODULE__.Phoenix.Endpoint

Phoenix.Endpoint.instrument :phoenix_controller_call, %Plug.Conn{}, fn ->
  :timer.sleep(500)
end

Also helpful was @sasajuric’s series on macros. This community is awesome!