dotfiles/app/lib/prymn_web/components/system_info.ex
2024-02-01 23:54:23 +02:00

110 lines
3.1 KiB
Elixir

defmodule PrymnWeb.SystemInfo do
use PrymnWeb, :live_component
require Logger
alias Phoenix.LiveView.AsyncResult
@impl true
def update(assigns, socket) do
{:ok,
socket
|> assign(:agent, assigns.agent)
|> assign(:sys_info, AsyncResult.loading())}
# |> start_async(:get_sys_info, fn ->
# Prymn.Agents.get_sys_info(assigns.agent)
# end)}
end
@impl true
def render(assigns) do
~H"""
<div class="flex justify-between space-x-4 rounded bg-gray-800 p-5 text-white">
<.async_result :let={sys_info} assign={@sys_info}>
<:loading>
<div>
<.spinner size="sm" />
<p class="text-xl">Loading system statistics...</p>
</div>
</:loading>
<div>
<p class="text-xl"><%= sys_info.uptime || "" %>s</p>
<p class="text-sm">Uptime</p>
</div>
<div>
<p class="text-xl"><%= Enum.count(sys_info.cpus || []) %></p>
<p class="text-sm">CPUs</p>
</div>
<div>
<p class="text-xl"><%= calculate_cpu_usage(sys_info.cpus) %></p>
<p class="text-sm">CPU%</p>
</div>
<div>
<p class="text-xl">
<%= bytes_to_gigabytes(sys_info.mem_total_bytes - sys_info.mem_avail_bytes) %>
<span>/</span>
<%= bytes_to_gigabytes(sys_info.mem_total_bytes) %>
<span>GiB</span>
</p>
<p class="text-sm">Memory</p>
</div>
<div>
<p class="text-xl">
<%= calculate_disk_used_percent(sys_info.disks) %>
<span>%</span>
</p>
<p class="text-sm">Used Disk</p>
</div>
</.async_result>
</div>
"""
end
# @impl true
# def handle_async(:get_sys_info, {:ok, %SysInfoResponse{} = sys_info}, socket) do
# %{sys_info: sys_info_result, agent: agent} = socket.assigns
# {:noreply,
# socket
# |> assign(:sys_info, AsyncResult.ok(sys_info_result, sys_info))
# |> start_async(:get_sys_info, fn ->
# # 10 seconds is >5 which is gun's timeout duration (which might have a race
# # condition if they are equal)
# Process.sleep(:timer.seconds(10))
# Prymn.Agents.get_sys_info(agent)
# end)}
# end
# def handle_async(:get_sys_info, {:ok, {:error, grpc_error}}, socket) do
# %{sys_info: sys_info_result} = socket.assigns
# {:noreply,
# socket
# |> assign(:sys_info, AsyncResult.failed(sys_info_result, grpc_error))}
# end
# def handle_async(:get_sys_info, {:exit, _reason}, socket) do
# {:noreply, socket}
# end
defp calculate_cpu_usage(cpus) do
(Enum.reduce(cpus, 0, fn x, acc -> x.usage + acc end) / Enum.count(cpus))
|> Float.round(2)
end
defp bytes_to_gigabytes(bytes) do
Float.round(bytes / Integer.pow(1024, 3), 2)
end
defp calculate_disk_used_percent(disks) do
0
# alias PrymnProto.Prymn.SysInfoResponse.Disk
# {used, total} =
# Enum.reduce(disks, {0, 0}, fn %Disk{} = disk, {used, total} ->
# {used + disk.total_bytes - disk.avail_bytes, total + disk.total_bytes}
# end)
# Float.round(100 * used / total, 2)
end
end