Packages
new_relic_agent
1.40.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/telemetry/phoenix.ex
defmodule NewRelic.Telemetry.Phoenix do
use GenServer
alias NewRelic.Tracer
@moduledoc """
Provides `Phoenix` instrumentation via `telemetry`.
This instrumentation adds extra Phoenix specific instrumentation
on top of the base `NewRelic.Telemetry.Plug` instrumentation.
You can opt-out of this instrumentation with `:phoenix_instrumentation_enabled` via configuration.
See `NewRelic.Config` for details.
"""
def start_link(_) do
config = %{
enabled?: NewRelic.Config.feature?(:phoenix_instrumentation),
handler_id: {:new_relic, :phoenix}
}
GenServer.start_link(__MODULE__, config, name: __MODULE__)
end
@phoenix_router_start [:phoenix, :router_dispatch, :start]
@phoenix_controller_render_start [:phoenix, :controller, :render, :start]
@phoenix_controller_render_stop [:phoenix, :controller, :render, :stop]
@phoenix_error [:phoenix, :error_rendered]
@phoenix_events [
@phoenix_router_start,
@phoenix_controller_render_start,
@phoenix_controller_render_stop,
@phoenix_error
]
@doc false
def init(%{enabled?: false}), do: :ignore
def init(%{enabled?: true} = config) do
:telemetry.attach_many(
config.handler_id,
@phoenix_events,
&__MODULE__.handle_event/4,
config
)
{:ok, config}
end
@doc false
def terminate(_reason, %{handler_id: handler_id}) do
:telemetry.detach(handler_id)
end
def handle_event(
@phoenix_router_start,
_measurements,
%{conn: conn} = meta,
_config
) do
[
phoenix_name: phoenix_name(meta),
"phoenix.endpoint": conn.private[:phoenix_endpoint] |> inspect(),
"phoenix.router": conn.private[:phoenix_router] |> inspect(),
"phoenix.controller": meta.plug |> inspect(),
"phoenix.action":
case meta.plug_opts do
action when is_atom(action) -> to_string(action)
action -> inspect(action)
end,
"phoenix.format": conn.private[:phoenix_format],
"phoenix.template": conn.private[:phoenix_template],
"phoenix.view": conn.private[:phoenix_view] && inspect(conn.private[:phoenix_view])
]
|> NewRelic.add_attributes()
end
def handle_event(
@phoenix_error,
_measurements,
%{conn: conn, status: 404} = meta,
_config
) do
[
phoenix_name: phoenix_name(meta),
"phoenix.endpoint": conn.private[:phoenix_endpoint] |> inspect(),
"phoenix.router": conn.private[:phoenix_router] |> inspect()
]
|> NewRelic.add_attributes()
end
def handle_event(
@phoenix_controller_render_start,
meas,
%{view: view, template: template, format: format} = meta,
_config
) do
Tracer.Direct.start_span(
meta.telemetry_span_context,
"#{inspect(view)}.show",
system_time: meas.system_time,
attributes: [
"phoenix.view": inspect(view),
"phoenix.template": template,
"phoenix.format": format
]
)
end
def handle_event(
@phoenix_controller_render_stop,
meas,
meta,
_config
) do
Tracer.Direct.stop_span(meta.telemetry_span_context, duration: meas.duration)
end
def handle_event(_event, _measurements, _meta, _config) do
:ignore
end
defp phoenix_name(%{phoenix_live_view: {module, action, _, _}}) when is_atom(action) do
"/Phoenix/#{inspect(module)}/#{action}"
end
defp phoenix_name(%{plug: controller, plug_opts: action}) when is_atom(action) do
"/Phoenix/#{inspect(controller)}/#{action}"
end
defp phoenix_name(%{conn: %{private: %{phoenix_endpoint: phoenix_endpoint}} = conn}) do
"/Phoenix/#{inspect(phoenix_endpoint)}/#{conn.method}"
end
defp phoenix_name(%{conn: conn}) do
"/Phoenix/#{conn.method}"
end
end