defmodule Vibe.Web.RuntimeLive do @moduledoc """ LiveView runtime dashboard for Vibe's BEAM process. """ use Vibe.Web, :live_view alias Vibe.OTP @impl true def mount(_params, _session, socket) do if connected?(socket), do: :timer.send_interval(2_000, :refresh) {:ok, assign_runtime(socket)} end @impl true def handle_info(:refresh, socket), do: {:noreply, assign_runtime(socket)} @impl true def render(assigns) do ~H""" <.app_shell current={:runtime} title="Runtime" subtitle="Local Vibe server health, resource use, and background activity.">
<.panel title="Node">
OTP{@runtime.otp_release}
Elixir{@runtime.elixir}
Schedulers{@runtime.schedulers}
Active sessions{@active_count}
<.stat_card label="Processes" value={@runtime.process_count} /> <.stat_card label="ETS tables" value={length(@ets)} accent="text-vibe-accent" /> <.stat_card label="Memory MB" value={memory_mb(@runtime.memory[:total])} accent="text-cyan-300" />
<.panel title="Top processes by memory">
#PIDNameMemoryQueue
{process.index} {process.pid} {inspect(process.name || process.initial_call)} {process.memory} {process.message_queue_len}
<.panel title="Largest ETS tables">
NameSizeMemory
{inspect(table.name || table.id)} {table.size} {table.memory}
""" end defp assign_runtime(socket) do socket |> assign(:runtime, OTP.runtime_info()) |> assign(:top, OTP.top(:memory, limit: 12)) |> assign(:ets, OTP.ets_tables(limit: 12)) |> assign(:active_count, Vibe.Session.active_count()) end defp memory_mb(nil), do: 0 defp memory_mb(bytes), do: Float.round(bytes / 1_048_576, 1) end