Packages
new_relic_agent
1.19.3
1.40.3
1.40.2
1.40.1
1.40.0
1.39.0
1.38.0
1.37.0
1.36.0
1.35.0
1.34.0
1.33.0
1.32.0
1.31.1
1.31.0
1.30.0
1.29.0
1.28.0
1.27.8
1.27.7
1.27.6
1.27.5
1.27.4
1.27.3
1.27.2
1.27.1
1.27.0
1.26.0
1.25.3
1.25.2
1.25.1
1.25.0
1.24.5
1.24.4
1.24.3
1.24.2
1.24.1
1.24.0
1.24.0-rc.10
1.24.0-rc.9
1.24.0-rc.8
1.24.0-rc.7
1.23.6
1.23.5
1.23.4
1.23.3
1.23.2
1.23.1
1.23.0
1.23.0-rc.6
1.23.0-rc.5
1.23.0-rc.4
1.23.0-rc.3
1.23.0-rc.2
1.23.0-rc.1
1.22.6
1.22.5
1.22.4
1.22.3
1.22.2
1.22.1
1.22.0
1.21.2
1.21.1
1.21.0
1.21.0-rc.3
1.21.0-rc.1
1.20.0
1.20.0-rc.1
1.19.7
1.19.6
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.18.0-rc.5
1.18.0-rc.4
1.18.0-rc.2
1.18.0-rc.1
1.17.1
1.17.0
1.17.0-rc.4
1.17.0-rc.3
1.17.0-rc.2
1.17.0-rc.1
1.17.0-rc.0
1.16.7
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.16.0-rc.2
1.16.0-rc.1
1.16.0-rc.0
1.15.0
1.15.0-rc.3
1.15.0-rc.2
1.15.0-rc.1
1.14.0
1.13.1
1.13.0
1.12.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.12
1.9.11
1.9.10
1.9.9
1.9.8
1.9.7
1.9.6
1.9.5
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.0
1.7.0
1.6.2
1.6.1
1.6.0
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.0
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
New Relic's Open-Source Elixir Agent
Current section
Files
Jump to
Current section
Files
lib/new_relic/tracer/report.ex
defmodule NewRelic.Tracer.Report do
alias NewRelic.Transaction
# Helper functions that will report traced function events in their various forms
# - Transaction Trace segments
# - Distributed Trace spans
# - Transaction attributes
# - Metrics
# - Aggregate metric-like NRDB events
@moduledoc false
def call(
mfa,
trace_annotation,
pid,
edge,
timing
) do
{name, options} =
case trace_annotation do
{name, options} -> {name, options}
name -> {name, []}
end
category = Keyword.get(options, :category, :function)
report(
category,
options,
mfa,
name,
pid,
edge,
timing
)
end
defp report(
:external,
options,
{module, function, arguments},
name,
pid,
{id, parent_id},
{start_time, start_time_mono, end_time_mono, _child_duration_ms}
) do
duration_ms = duration_ms(start_time_mono, end_time_mono)
duration_s = duration_ms / 1000
arity = length(arguments)
args = inspect_args(arguments, Keyword.take(options, [:args]))
span_attrs = NewRelic.DistributedTrace.get_span_attrs()
function_name = function_name({module, function}, name)
function_arity_name = function_name({module, function, arity}, name)
Transaction.Reporter.add_trace_segment(%{
module: module,
function: function,
arity: arity,
name: name,
args: args,
pid: pid,
id: id,
parent_id: parent_id,
start_time: start_time,
start_time_mono: start_time_mono,
end_time_mono: end_time_mono
})
NewRelic.report_span(
timestamp_ms: System.convert_time_unit(start_time, :native, :millisecond),
duration_s: duration_s,
name: function_arity_name,
edge: [span: id, parent: parent_id],
category: "http",
attributes: Map.put(span_attrs, :args, args)
)
NewRelic.incr_attributes(
external_call_count: 1,
external_duration_ms: duration_ms,
"external.#{function_name}.call_count": 1,
"external.#{function_name}.duration_ms": duration_ms
)
NewRelic.report_aggregate(
%{
name: :FunctionTrace,
mfa: function_arity_name,
metric_category: :external
},
%{duration_ms: duration_ms, call_count: 1}
)
Transaction.Reporter.track_metric({:external, duration_s})
case span_attrs do
%{url: url, component: component, method: method} ->
NewRelic.report_metric({:external, url, component, method}, duration_s: duration_s)
Transaction.Reporter.track_metric({
{:external, url, component, method},
duration_s: duration_s
})
_ ->
NewRelic.report_metric({:external, function_name}, duration_s: duration_s)
Transaction.Reporter.track_metric({
{:external, function_name},
duration_s: duration_s
})
end
end
defp report(
:function,
options,
{module, function, arguments},
name,
pid,
{id, parent_id},
{start_time, start_time_mono, end_time_mono, child_duration_ms}
) do
duration_ms = duration_ms(start_time_mono, end_time_mono)
duration_s = duration_ms / 1000
exclusive_time_s = duration_s - child_duration_ms / 1000
arity = length(arguments)
args = inspect_args(arguments, Keyword.take(options, [:args]))
function_name = function_name({module, function, arity}, name)
Transaction.Reporter.add_trace_segment(%{
module: module,
function: function,
arity: arity,
name: name,
args: args,
pid: pid,
id: id,
parent_id: parent_id,
start_time: start_time,
start_time_mono: start_time_mono,
end_time_mono: end_time_mono
})
NewRelic.report_span(
timestamp_ms: System.convert_time_unit(start_time, :native, :millisecond),
duration_s: duration_s,
name: function_name,
edge: [span: id, parent: parent_id],
category: "generic",
attributes: Map.put(NewRelic.DistributedTrace.get_span_attrs(), :args, args)
)
NewRelic.report_aggregate(
%{name: :FunctionTrace, mfa: function_name},
%{duration_ms: duration_ms, call_count: 1}
)
NewRelic.report_metric(
{:function, function_name},
duration_s: duration_s,
exclusive_time_s: exclusive_time_s
)
Transaction.Reporter.track_metric({
{:function, function_name},
duration_s: duration_s, exclusive_time_s: exclusive_time_s
})
end
defp inspect_args(_arguments, args: false) do
"[DISABLED]"
end
defp inspect_args(arguments, _) do
if NewRelic.Config.feature?(:function_argument_collection) do
inspect(arguments, charlists: :as_lists, limit: 5, printable_limit: 10)
else
"[DISABLED]"
end
end
defp duration_ms(start_time_mono, end_time_mono),
do: System.convert_time_unit(end_time_mono - start_time_mono, :native, :millisecond)
defp function_name({m, f}, f), do: "#{inspect(m)}.#{f}"
defp function_name({m, f}, i), do: "#{inspect(m)}.#{f}:#{i}"
defp function_name({m, f, a}, f), do: "#{inspect(m)}.#{f}/#{a}"
defp function_name({m, f, a}, i), do: "#{inspect(m)}.#{f}:#{i}/#{a}"
end