defmodule Integrations.Self.Display do
@moduledoc """
Dashboard panel for `Integrations.Self` (same package).
Nested under the monitor's own namespace deliberately — the package's
top-level module name never changes, and this module's name is
guaranteed distinct from any separately-published standalone display
package. `Display.BundledDefault` auto-hooks this whenever
`Integrations.Self` starts, the same as if they were still one module.
"""
use CodeNameRaven.Display, category: :system, size_hint: :large
def display_timezone, do: "America/Chicago"
@impl true
def display_name, do: "Application Health"
@impl true
def compatible_monitors, do: [Integrations.Self]
@impl true
def render(assigns) do
~H"""
<%!-- Header --%>
Application Health
<%= @result && @result.node %>
<.status_chip status={@status} />
<%!-- Version / uptime row --%>
<.info_card label="Elixir" value={"v#{@result.elixir_version}"} />
<.info_card label="OTP" value={"v#{@result.otp_version}"} />
<.info_card label="Uptime" value={format_uptime(@result.uptime_seconds)} />
<%!-- Memory --%>
Memory
<.memory_row label="Total" bytes={@result.memory.total} />
<.memory_row label="Processes" bytes={@result.memory.processes} />
<.memory_row label="Binary" bytes={@result.memory.binary} />
<.memory_row label="ETS" bytes={@result.memory.ets} />
<%!-- Process stats --%>
<.stat_card label="Processes" value={@result.process_count} />
<.stat_card label="Run Queue" value={@result.run_queue} />
<%!-- Footer --%>
Checked <%= CodeNameRaven.Timezone.format_datetime(@last_checked_at, __MODULE__) %>
"""
end
# ---------------------------------------------------------------------------
# Private components
# ---------------------------------------------------------------------------
defp status_chip(%{status: :up} = assigns) do
~H"""
Up
"""
end
defp status_chip(%{status: :degraded} = assigns) do
~H"""
Degraded
"""
end
defp status_chip(%{status: :down} = assigns) do
~H"""
Down
"""
end
defp status_chip(assigns) do
~H"""
Unknown
"""
end
defp info_card(assigns) do
~H"""
<%= @label %>
<%= @value %>
"""
end
defp memory_row(assigns) do
~H"""
<%= @label %>
<%= format_bytes(@bytes) %>
"""
end
defp stat_card(assigns) do
~H"""
<%= @label %>
<%= @value %>
"""
end
# ---------------------------------------------------------------------------
# Formatting helpers
# ---------------------------------------------------------------------------
defp format_bytes(bytes) when bytes >= 1_073_741_824,
do: "#{Float.round(bytes / 1_073_741_824, 1)} GB"
defp format_bytes(bytes) when bytes >= 1_048_576,
do: "#{Float.round(bytes / 1_048_576, 1)} MB"
defp format_bytes(bytes) when bytes >= 1_024,
do: "#{Float.round(bytes / 1_024, 1)} KB"
defp format_bytes(bytes),
do: "#{bytes} B"
defp format_uptime(seconds) do
days = div(seconds, 86_400)
hours = div(rem(seconds, 86_400), 3_600)
minutes = div(rem(seconds, 3_600), 60)
cond do
days > 0 -> "#{days}d #{hours}h"
hours > 0 -> "#{hours}h #{minutes}m"
true -> "#{minutes}m #{rem(seconds, 60)}s"
end
end
end