Last active
April 14, 2022 01:27
-
-
Save cblavier/faaee0e3969de708737ed0e6c623d3dd to your computer and use it in GitHub Desktop.
A Phoenix Telemetry agent to monitor all LiveView events & errors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule AppSignalTelemetry do | |
use GenServer | |
require Appsignal.Utils | |
import Appsignal.Utils, only: [module_name: 1] | |
@tracer Appsignal.Utils.compile_env(:appsignal, :appsignal_tracer, Appsignal.Tracer) | |
@span Appsignal.Utils.compile_env(:appsignal, :appsignal_span, Appsignal.Span) | |
@appsignal_namespace "live_view" | |
def start_link do | |
GenServer.start_link(__MODULE__, [], name: __MODULE__) | |
end | |
def init(_opts) do | |
events = [ | |
{"live_view.mount", [:phoenix, :live_view, :mount]}, | |
{"live_view.handle_params", [:phoenix, :live_view, :handle_params]}, | |
{"live_view.handle_event", [:phoenix, :live_view, :handle_event]}, | |
{"live_component.handle_event", [:phoenix, :live_component, :handle_event]} | |
] | |
for {name, event} <- events do | |
:telemetry.attach("#{name}.start", event ++ [:start], &handle_event_start/4, name) | |
:telemetry.attach("#{name}.stop", event ++ [:stop], &handle_event_stop/4, name) | |
:telemetry.attach("#{name}.exception", event ++ [:exception], &handle_event_exception/4, name) | |
end | |
{:ok, nil} | |
end | |
defp handle_event_start(_event, _params, metadata, event_name) do | |
@appsignal_namespace | |
|> @tracer.create_span(@tracer.current_span(), | |
start_time: :os.system_time(), | |
pid: metadata.socket.root_pid | |
) | |
|> @span.set_name(module_name(metadata.socket.view)) | |
|> @span.set_attribute("type", event_type(event_name)) | |
|> @span.set_attribute("appsignal:category", event_name) | |
|> maybe_set_sample_data(metadata[:params], :params) | |
|> maybe_set_sample_data(metadata[:session], :session_data) | |
|> maybe_set_attribute(metadata[:uri], :uri) | |
|> maybe_set_attribute(metadata[:event], :event) | |
end | |
defp handle_event_stop(_event, _params, metadata, _event_name) do | |
metadata.socket.root_pid | |
|> @tracer.current_span() | |
|> @tracer.close_span(end_time: :os.system_time()) | |
end | |
defp handle_event_exception(_event, _params, metadata, _event_name) do | |
metadata.socket.root_pid | |
|> @tracer.current_span() | |
|> @span.add_error(metadata.kind, metadata.reason, metadata.stacktrace) | |
|> @tracer.close_span(end_time: :os.system_time()) | |
@tracer.ignore(metadata.socket.root_pid) | |
end | |
defp event_type(event_name), do: event_name |> String.split(".") |> Enum.at(-1) | |
defp maybe_set_sample_data(span, val, key) when is_map(val) do | |
case @span.set_sample_data(span, to_string(key), val) do | |
nil -> span | |
span -> span | |
end | |
end | |
defp maybe_set_sample_data(span, _val, _key), do: span | |
defp maybe_set_attribute(span, val, key) when is_binary(val) do | |
case @span.set_attribute(span, to_string(key), val) do | |
nil -> span | |
span -> span | |
end | |
end | |
defp maybe_set_attribute(span, _val, _key), do: span | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for making this available, it saved me a HEAP of time. I made a few minor changes here: https://gist.github.com/terrcin/76ec781a586f159fc348b29756b3a449
Most notable was resolving the warnings around how the event handlers were being specified: