{% extends "base.html" %} {% from "_macros.html" import crumbs %} {% block title %}{{ host.name }} — Host Agent — Steward{% endblock %} {% block breadcrumb %}{{ crumbs([("Hosts", "/hosts/"), (host.name, "/hosts/" ~ host.id), ("Metrics", "")]) }}{% endblock %} {% macro fmt_bps(v) %} {%- if v is none -%}— {%- elif v >= 1048576 -%}{{ "%.1f"|format(v / 1048576) }} MB/s {%- elif v >= 1024 -%}{{ "%.1f"|format(v / 1024) }} KB/s {%- else -%}{{ "%.0f"|format(v) }} B/s {%- endif -%} {% endmacro %} {% macro fmt_bytes(v) %} {%- if v is none -%}— {%- elif v >= 1125899906842624 -%}{{ "%.1f"|format(v / 1125899906842624) }} PB {%- elif v >= 1099511627776 -%}{{ "%.1f"|format(v / 1099511627776) }} TB {%- elif v >= 1073741824 -%}{{ "%.1f"|format(v / 1073741824) }} GB {%- elif v >= 1048576 -%}{{ "%.0f"|format(v / 1048576) }} MB {%- else -%}{{ "%.0f"|format(v / 1024) }} KB {%- endif -%} {% endmacro %} {% macro bar(pct) %} {%- set p = pct if pct is not none else 0 -%}
{% endmacro %} {% block content %}

{{ host.name }}

{% if stale %}stale{% else %}live{% endif %}
{% for r in range_options %} {{ r }} {% endfor %}
{# ── Identity / metadata ─────────────────────────────────────────────────── #}
Address {{ host.address or "—" }} {% if reg %} {% if reg.distro %}OS {{ reg.distro }}{% endif %} {% if reg.kernel %}Kernel {{ reg.kernel }}{% endif %} {% if reg.arch %}Arch {{ reg.arch }}{% endif %} {% if reg.agent_version %}Agent v{{ reg.agent_version }}{% endif %} {% set up = hostlvl.get('uptime_secs') %} {% if up %}Uptime {{ (up // 86400)|int }}d {{ ((up % 86400) // 3600)|int }}h{% endif %} Last seen {{ reg.last_seen_at.strftime("%Y-%m-%d %H:%M:%S") ~ " UTC" if reg.last_seen_at else "never" }} {% else %} No agent registration found for this host. {% endif %}
{% if not hostlvl %}
No metrics reported yet. Once the agent checks in, CPU, memory, network, disk I/O, temperatures, and pressure will appear here.
{% else %} {# ── Current headline gauges ─────────────────────────────────────────────── #}
CPU
{% set c = hostlvl.get('cpu_pct') %} {% if c is not none %}{{ "%.0f"|format(c) }}%{% else %}—{% endif %}
{{ bar(c) }}
Memory
{% set mp = hostlvl.get('mem_used_pct') %} {% if mp is not none %}{{ "%.0f"|format(mp) }}%{% else %}—{% endif %}
{{ bar(mp) }}
avail {{ fmt_bytes(hostlvl.get('mem_available_bytes')) }} · cache {{ fmt_bytes(hostlvl.get('mem_cached_bytes')) }} · swap {{ fmt_bytes(hostlvl.get('swap_used_bytes')) }}
Load
{% if hostlvl.get('load_1m') is not none %}{{ "%.2f"|format(hostlvl.get('load_1m')) }}{% else %}—{% endif %}
5m {% if hostlvl.get('load_5m') is not none %}{{ "%.2f"|format(hostlvl.get('load_5m')) }}{% else %}—{% endif %} · 15m {% if hostlvl.get('load_15m') is not none %}{{ "%.2f"|format(hostlvl.get('load_15m')) }}{% else %}—{% endif %}
Network
{{ fmt_bps(hostlvl.get('net_rx_bps')) }}
{{ fmt_bps(hostlvl.get('net_tx_bps')) }}
Disk I/O
rd {{ fmt_bps(hostlvl.get('disk_read_bps')) }}
wr {{ fmt_bps(hostlvl.get('disk_write_bps')) }}
{% if hostlvl.get('temp_c_max') is not none %}
Temp (max)
{% set t = hostlvl.get('temp_c_max') %} {{ "%.0f"|format(t) }}°C
{% endif %} {% if hostlvl.get('psi_mem_some_avg10') is not none %}
Pressure (10s)
mem {{ "%.1f"|format(hostlvl.get('psi_mem_some_avg10')) }}%
{% if hostlvl.get('psi_cpu_some_avg10') is not none %}
cpu {{ "%.1f"|format(hostlvl.get('psi_cpu_some_avg10')) }}%
{% endif %} {% if hostlvl.get('psi_io_some_avg10') is not none %}
io {{ "%.1f"|format(hostlvl.get('psi_io_some_avg10')) }}%
{% endif %}
{% endif %}
{# ── Per-core CPU ─────────────────────────────────────────────────────────── #} {% if cores %}
Per-core CPU
{% for idx, pct in cores %}
core {{ idx }}{% if pct is not none %}{{ "%.0f"|format(pct) }}%{% else %}—{% endif %}
{{ bar(pct) }}
{% endfor %}
{% endif %} {# ── Filesystems ──────────────────────────────────────────────────────────── #} {% if mounts %}
Filesystems
{% for mount, m in mounts.items() %}
{{ mount }} {{ fmt_bytes(m.get('disk_used_bytes')) }} / {{ fmt_bytes(m.get('disk_total_bytes')) }}{% if m.get('disk_used_pct') is not none %} · {{ "%.0f"|format(m.get('disk_used_pct')) }}%{% endif %}
{{ bar(m.get('disk_used_pct')) }}
{% endfor %}
{% endif %} {# ── Interfaces / disks (short panels, side by side at natural height) ─────── #} {% if nets or disks_io %}
{% if nets %}
Interfaces
{% for iface, m in nets.items() %}
{{ iface }} ↓ {{ fmt_bps(m.get('net_rx_bps')) }} · ↑ {{ fmt_bps(m.get('net_tx_bps')) }}
{% endfor %}
{% endif %} {% if disks_io %}
Disks
{% for dev, m in disks_io.items() %}
{{ dev }} rd {{ fmt_bps(m.get('disk_read_bps')) }} · wr {{ fmt_bps(m.get('disk_write_bps')) }}
{% endfor %}
{% endif %}
{% endif %} {# ── Temperatures (full width; cores flow into a compact multi-column grid so a many-core CPU reads wide-and-short instead of one very tall column) ─────── #} {% if temps %}
Temperatures
{% for label, c in temps.items() %}
{{ label }} {% if c is not none %}{{ "%.0f"|format(c) }}°C{% else %}—{% endif %}
{% endfor %}
{% endif %} {# ── History charts ───────────────────────────────────────────────────────── #}
Utilization % — last {{ range_key }}
Throughput (B/s) — last {{ range_key }}
Load & pressure — last {{ range_key }}
{% endif %} {% endblock %}