Packages
new_relic_agent
1.40.0
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/direct.ex
defmodule NewRelic.Tracer.Direct do
@moduledoc false
@max_open_span_count Application.compile_env(:new_relic, :max_open_span_count, 20)
def start_span(id, name, options \\ []) do
case Process.get(:nr_open_span_count, 0) do
over when over >= @max_open_span_count ->
Process.put(:nr_open_span_count, over + 1)
NewRelic.incr_attributes(skipped_span_count: 1)
under ->
Process.put(:nr_open_span_count, under + 1)
system_time = Keyword.get(options, :system_time, System.system_time())
monotonic_time = Keyword.get(options, :monotonic_time, System.monotonic_time())
attributes = Keyword.get(options, :attributes, []) |> Map.new()
{span, previous_span, previous_span_attrs} =
NewRelic.DistributedTrace.set_current_span(
label: id,
ref: make_ref()
)
Process.put(
{:nr_span, id},
{name, system_time, monotonic_time, attributes, {span, previous_span, previous_span_attrs}}
)
end
:ok
end
def stop_span(id, options \\ []) do
case Process.delete({:nr_span, id}) do
nil ->
:no_such_span
{name, system_time, monotonic_start_time, start_attributes, {span, previous_span, previous_span_attrs}} ->
Process.put(:nr_open_span_count, Process.get(:nr_open_span_count) - 1)
{duration, duration_s} =
case Keyword.get(options, :duration) do
nil ->
duration = System.monotonic_time() - monotonic_start_time
{duration, System.convert_time_unit(duration, :native, :microsecond) / 1_000_000}
duration ->
{duration, System.convert_time_unit(duration, :native, :microsecond) / 1_000_000}
end
name = Keyword.get(options, :name, name)
timestamp_ms = System.convert_time_unit(system_time, :native, :millisecond)
stop_attributes = Keyword.get(options, :attributes, []) |> Map.new()
attributes =
start_attributes
|> Map.merge(NewRelic.DistributedTrace.get_span_attrs())
|> Map.merge(stop_attributes)
{primary_name, secondary_name} =
case name do
{primary_name, secondary_name} -> {primary_name, secondary_name}
name -> {name, ""}
end
NewRelic.Transaction.Reporter.add_trace_segment(%{
primary_name: primary_name,
secondary_name: secondary_name,
attributes: attributes,
pid: self(),
id: span,
parent_id: previous_span || :root,
start_time: system_time,
duration: duration
})
NewRelic.report_span(
timestamp_ms: timestamp_ms,
duration_s: duration_s,
name: primary_name,
edge: [span: span, parent: previous_span || :root],
category: "generic",
attributes: attributes
)
if NewRelic.Config.feature?(:extended_attributes) do
NewRelic.incr_attributes(
"span.#{primary_name}.call_count": 1,
"span.#{primary_name}.duration_ms": duration
)
end
NewRelic.report_metric({:function, primary_name}, duration_s: duration_s)
NewRelic.DistributedTrace.reset_span(
previous_span: previous_span,
previous_span_attrs: previous_span_attrs
)
end
:ok
end
end