Current section

Files

Jump to
new_relic_agent lib new_relic tracer.ex
Raw

lib/new_relic/tracer.ex

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 with `@trace`.
Traced functions will report as:
- Segments in Transaction Traces
- Span Events in Distributed Traces
- Special custom attributes on Transaction Events
> #### Warning {: .error}
>
> Traced functions will *not* be tail-call-recursive. **Don't use this for recursive functions**.
#### Example
Trace a function:
```elixir
defmodule MyModule do
use NewRelic.Tracer
@trace :my_function
def my_function do
# Will report as `MyModule.my_function/0`
end
@trace :alias
def my_function do
# Will report as `MyModule.my_function:alias/0`
end
end
```
#### Arguments
By default, arguments are inspected and recorded along with traces. You can opt-out of function argument tracing on individual tracers:
```elixir
defmodule SecretModule do
use NewRelic.Tracer
@trace {:login, args: false}
def login(username, password) do
# do something secret...
end
end
```
This will prevent the argument values from becoming part of Transaction Traces.
This may also be configured globally via `Application` config. See `NewRelic.Config` for details.
#### External Service calls
> #### Finch {: .warning}
>
> `Finch` requests are auto-instrumented, so you don't need to use `category: :external` tracers or call `set_span` if you use `Finch`.
> You may still want to use a normal tracer for functions that make HTTP requests if they do additional work worth instrumenting.
> Automatic `Finch` instrumentation can not inject Distributed Trace headers, so that must still be done manually.
To manually instrument External Service calls you must give the trace annotation a category.
You may also call `NewRelic.set_span/2` to provide better naming for metrics & spans, and additionally 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
```
"""
defmacro __using__(_args) do
quote do
require NewRelic
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