defmodule NewRelic.Tracer do @moduledoc """ Function Tracing To enable function tracing in a particular module, `use NewRelic.Tracer`, and annotate the functions you want to `@trace`. Traced functions will report as: - Segments in Transaction Traces - Span Events in Distributed Traces - Special custom attributes on Transaction Events #### Notes: * Traced functions will *not* be tail-call-recursive. **Don't use this for recursive functions**. #### Example ```elixir defmodule MyModule do use NewRelic.Tracer @trace :func def func do # Will report as `MyModule.func/0` end end ``` #### Categories To categorize External Service calls you must give the trace annotation a category. You may also call `NewRelic.set_span` to provide better naming for metrics & spans, and additonally annotate the outgoing HTTP headers with the Distributed Tracing context to track calls across services. ```elixir defmodule MyExternalService do use NewRelic.Tracer @trace {:request, category: :external} def request(method, url, headers) do NewRelic.set_span(:http, url: url, method: method, component: "HttpClient") headers ++ NewRelic.distributed_trace_headers(:http) HttpClient.request(method, url, headers) end end ``` This will: * Post `External` metrics to APM * Add custom attributes to Transaction events: - `external_call_count` - `external_duration_ms` - `external.MyExternalService.query.call_count` - `external.MyExternalService.query.duration_ms` Transactions that call the traced `ExternalService` functions will contain `external_call_count` attribute ```elixir get "/endpoint" do ExternalService.request(:get, url, headers) send_resp(conn, 200, "ok") end ``` """ defmacro __using__(_args) do quote do require NewRelic.Tracer.Macro require NewRelic.Tracer.Report Module.register_attribute(__MODULE__, :nr_tracers, accumulate: true) Module.register_attribute(__MODULE__, :nr_last_tracer, accumulate: false) @before_compile NewRelic.Tracer.Macro @on_definition NewRelic.Tracer.Macro end end end