{% extends "base.html" %} {% block title %}{{ _("System stats") }}{% endblock %} {% block content %}
{{ panel_icon('users')|safe }} {{ _("Users") }}
{{ user_count }}
{{ totals.bots }} {{ ngettext("bot", "bots", totals.bots, count=totals.bots) }} {{ _("total") }}
{{ panel_icon('check')|safe }} {{ _("Running bots") }}
{{ totals.running }}
{{ _("out of") }} {{ totals.bots }}
{{ panel_icon('cpu')|safe }} {{ _("Host CPU") }}
{{ host.cpu_percent }}%
{{ host.cpu_count }} {{ ngettext("core", "cores", host.cpu_count, count=host.cpu_count) }}
{{ panel_icon('db')|safe }} {{ _("Host RAM") }}
{{ host.ram_percent }}%
{{ host.ram_used_mb }} / {{ host.ram_total_mb }} MB
{# ======================== Bot status breakdown ======================== #} {# Per-status counts across the whole fleet. Always shows every known status (running / building / error / sleeping / pending / stopped / starting) even when the count is 0 — keeps the column order stable for ops monitoring. #}
{{ panel_icon('bot')|safe }} {{ _("Bot fleet by status") }}
{% for key, label, tone in [ ('running', _('Running'), 'tone-success'), ('building', _('Building'), 'tone-accent'), ('starting', _('Starting'), 'tone-accent'), ('sleeping', _('Sleeping'), 'tone-warning'), ('error', _('Error'), 'tone-error'), ('pending', _('Pending'), ''), ('stopped', _('Stopped'), ''), ] %} {% set count = totals.bots_by_status.get(key, 0) %}
{{ label }}
{{ count }}
{% endfor %}
{# ======================== Host resource bars ======================== #}
{{ panel_icon('cpu')|safe }} {{ _("Host machine load") }}
{{ _("CPU —") }} {{ host.cpu_count }} {{ ngettext("core", "cores", host.cpu_count, count=host.cpu_count) }} {{ host.cpu_percent }}%
{{ _("RAM") }} {{ host.ram_used_mb }} / {{ host.ram_total_mb }} MB ({{ host.ram_percent }}%)
{{ _("Disk") }} ({{ host.disk_total_mb }} MB {{ _("total") }}) {{ host.disk_used_mb }} MB ({{ host.disk_percent }}%)

{{ _("This is the machine the panel process itself runs on. Bots deployed in") }} legacy_space {{ _("mode run on their own separate HF Space and aren't reflected in this host's CPU/RAM — only in the per-user table below (allocated quota, not live usage). Bots running in") }} multitenant {{ _("mode (subprocess inside this Space) do show live CPU/RAM in the \"live\" columns.") }}

{# ======================== Per-user table ======================== #}

{{ _("Per-user usage") }}

{{ _("Bot counts and resource footprint by account.") }}
{% for row in rows %} {% else %} {% endfor %}
{{ _("User") }} {{ _("Bots") }} {{ _("Running") }} {{ _("By status") }} {{ _("Live CPU") }} {{ _("(multitenant)") }} {{ _("Live RAM") }} {{ _("(multitenant)") }} {{ _("Allocated CPU") }} {{ _("Allocated RAM") }} {{ _("Storage used") }}
{{ row.user.username[:2]|upper }}
{{ row.user.username }}
{{ row.bots_total }} {% if row.bots_running %} {{ row.bots_running }} {% else %} 0 {% endif %} {# Compact status pills: 🟢3 🔨1 💤2 etc. #} {% if row.bots_by_status %}
{% for key in ['running', 'building', 'starting', 'sleeping', 'error', 'pending', 'stopped'] %} {% set n = row.bots_by_status.get(key, 0) %} {% if n > 0 %} {% set icon = {'running':'🟢','building':'🔨','starting':'⏳','sleeping':'💤','error':'🔴','pending':'⏸','stopped':'⏹'}[key] %} {{ icon }}{{ n }} {% endif %} {% endfor %}
{% else %} — {% endif %}
{{ row.cpu_live_percent }}% {{ row.ram_live_mb }} MB {{ row.cpu_alloc_cores }} / {{ row.user.cpu_quota_cores }} {{ _("cores") }} {{ row.ram_alloc_mb }} / {{ row.user.ram_quota_mb }} MB {{ row.storage_used_mb }} / {{ row.user.storage_quota_mb }} MB
{{ _("No users yet.") }}
{% endblock %}