defmodule Phoenix.LiveDashboard.ProcessInfoComponent do use Phoenix.LiveDashboard.Web, :live_component alias Phoenix.LiveDashboard.SystemInfo @info_keys [ :registered_name, :current_function, :initial_call, :status, :message_queue_len, :links, :monitors, :monitored_by, :trap_exit, :error_handler, :priority, :group_leader, :total_heap_size, :heap_size, :stack_size, :reductions, :garbage_collection, :suspending, :current_stacktrace ] @impl true def render(assigns) do ~L"""
<%= if @alive do %>
Registered name
<%= @registered_name %>
Current function
<%= @current_function %>
Initial call
<%= @initial_call %>
Status
<%= @status %>
Message queue length
<%= @message_queue_len %>
Links
<%= @links %>
Monitors
<%= @monitors %>
Monitored by
<%= @monitored_by %>
Trap exit
<%= @trap_exit %>
Error handler
<%= @error_handler %>
Priority
<%= @priority %>
Group leader
<%= @group_leader %>
Total heap size
<%= @total_heap_size %>
Heap size
<%= @heap_size %>
Stack size
<%= @stack_size %>
Reductions
<%= @reductions %>
Garbage collection
<%= @garbage_collection %>
Suspending
<%= @suspending %>
Current stacktrace
<%= @current_stacktrace %>
<% else %>
Process is not alive or does not exist.
<% end %>
""" end @impl true def mount(socket) do {:ok, Enum.reduce(@info_keys, socket, &assign(&2, &1, nil))} end @impl true def update(%{id: "PID" <> pid, path: path}, socket) do pid = :erlang.list_to_pid(String.to_charlist(pid)) {:ok, socket |> assign(:pid, pid) |> assign(:path, path) |> assign_info()} end defp assign_info(%{assigns: assigns} = socket) do case SystemInfo.fetch_process_info(assigns.pid, @info_keys) do {:ok, info} -> Enum.reduce(info, socket, fn {key, val}, acc -> assign(acc, key, format_info(key, val, assigns.path)) end) |> assign(alive: true) :error -> assign(socket, alive: false) end end defp format_info(key, val, live_dashboard_path) when key in [:links, :monitors, :monitored_by], do: format_value(val, live_dashboard_path) defp format_info(:current_function, val, _), do: format_call(val) defp format_info(:initial_call, val, _), do: format_call(val) defp format_info(:current_stacktrace, val, _), do: format_stacktrace(val) defp format_info(_key, val, live_dashboard_path), do: format_value(val, live_dashboard_path) end