Packages
new_relic_agent
1.38.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/telemetry/ecto/handler.ex
defmodule NewRelic.Telemetry.Ecto.Handler do
@moduledoc false
alias NewRelic.Telemetry.Ecto.Metadata
def handle_event(
_event,
%{total_time: total_time} = measurements,
%{type: :ecto_sql_query, repo: repo} = metadata,
config
) do
end_time = System.system_time(:microsecond) / 1000
duration_ms = total_time |> to_ms
duration_s = duration_ms / 1000
start_time = end_time - duration_ms
query_time_ms = measurements[:query_time] |> to_ms
queue_time_ms = measurements[:queue_time] |> to_ms
decode_time_ms = measurements[:decode_time] |> to_ms
database = config.opts[:database] || "unknown"
hostname = config.opts[:hostname] || "unknown"
port = config.opts[:port] || "unknown"
query = (config.collect_db_query? && metadata.query) || "[NOT_COLLECTED]"
pid = inspect(self())
id = {:ecto_sql_query, make_ref()}
parent_id = Process.get(:nr_current_span) || :root
with {datastore, {operation, table}} <- Metadata.parse(metadata) do
metric_name = "Datastore/statement/#{datastore}/#{table}/#{operation}"
secondary_name = "#{inspect(repo)} #{hostname}:#{port}/#{database}"
NewRelic.Transaction.Reporter.add_trace_segment(%{
primary_name: metric_name,
secondary_name: secondary_name,
attributes: %{
sql: query,
collection: table,
operation: operation,
host: hostname,
database_name: database,
port_path_or_id: port |> to_string
},
pid: pid,
id: id,
parent_id: parent_id,
start_time: start_time,
end_time: end_time
})
NewRelic.report_span(
timestamp_ms: start_time,
duration_s: duration_s,
name: metric_name,
edge: [span: id, parent: parent_id],
category: "datastore",
attributes:
%{
component: datastore,
"span.kind": :client,
"db.statement": query,
"db.instance": database,
"peer.address": "#{hostname}:#{port}}",
"peer.hostname": hostname,
"db.table": table,
"db.operation": operation,
"ecto.repo": inspect(repo)
}
|> maybe_add("ecto.query_time.ms", query_time_ms)
|> maybe_add("ecto.queue_time.ms", queue_time_ms)
|> maybe_add("ecto.decode_time.ms", decode_time_ms)
)
NewRelic.report_metric(
{:datastore, datastore, table, operation},
duration_s: duration_s
)
NewRelic.Transaction.Reporter.track_metric({
{:datastore, datastore, table, operation},
duration_s: duration_s
})
NewRelic.incr_attributes(
databaseCallCount: 1,
databaseDuration: duration_s,
datastore_call_count: 1,
datastore_duration_ms: duration_ms
)
if NewRelic.Config.feature?(:extended_attributes) do
NewRelic.incr_attributes(
"datastore.#{table}.call_count": 1,
"datastore.#{table}.duration_ms": duration_ms
)
end
end
end
def handle_event(_event, _value, _metadata, _config) do
:ignore
end
defp to_ms(nil), do: nil
defp to_ms(ns), do: System.convert_time_unit(ns, :nanosecond, :microsecond) / 1000
defp maybe_add(map, _, nil), do: map
defp maybe_add(map, key, value), do: Map.put(map, key, value)
end