VDNT-Util01's / ran out of inodes (956 free of 60.8M) with 274G of space
left; every file create failed and Steward's page read healthy at 66%.
- Agent 1.13.0 reports each mount's inodes (statvfs; a filesystem reporting
none, like btrfs, is left without).
- Ingest records inodes_used_pct per mount, and disk_used_pct_worst is the
fullest mount by space or inodes, so existing disk-full rules and the
overview see it.
- The host's health strip, the Hosts widget and the host glance grade / by
whichever is fuller and name inodes when they are ("Disk / 66% · inodes
100%", "Inodes on / ... past its critical threshold").
Hosts pick up the inode figures once their agent is updated to 1.13.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
43 lines
3.0 KiB
HTML
43 lines
3.0 KiB
HTML
{# Host health header — live polled into the host hub: live or stale, the worst
|
|
reading against Settings → Thresholds, last seen, then CPU / memory / disk /
|
|
load tiles graded by the same cutoffs (`grades`; CPU, memory and load within
|
|
the host's own normal for the hour read healthy, and `usual` says so). Renders nothing until the agent
|
|
reports (the Agent panel below then shows provisioning). #}
|
|
{% from "_macros.html" import status_badge, stat_tile %}
|
|
{% macro pct(v) %}{{ '%.0f%%'|format(v) if v is not none else '—' }}{% endmacro %}
|
|
{% set grades = grades or {} %}
|
|
{% if reporting %}
|
|
<section class="card host-health" aria-label="Host health">
|
|
<div class="host-health-head">
|
|
{{ status_badge('stale' if stale else 'up', 'Stale' if stale else 'Live') }}
|
|
<span class="host-health-summary">
|
|
{%- if stale %}No report since {{ reg.last_seen_at|ago }}; the readings below are from then.
|
|
{%- elif worst %}<span class="tone-{{ worst[2] }}">{{ worst[0] }} {{ pct(worst[1]) }}</span> is past its {{ "critical" if worst[2] == "crit" else "warning" }} threshold.
|
|
{%- elif usual %}Every reading is within its thresholds or its usual level for this hour.
|
|
{%- else %}Every reading is within its thresholds.{% endif -%}
|
|
</span>
|
|
<span class="problem-detail">
|
|
{%- if not stale %}seen {{ reg.last_seen_at|ago }}{% endif %}
|
|
{%- if reg.agent_version %}{{ " · " if not stale }}agent v{{ reg.agent_version }}{% endif -%}
|
|
{%- if clock and clock[0] %} · <span{% if clock[1] in ('warn', 'crit') %} class="tone-{{ clock[1] }}" title="Further from Steward's clock than Settings → Thresholds allows: check what keeps this host's time in sync"{% endif %}>{{ clock[0] }}</span>{% endif -%}
|
|
</span>
|
|
</div>
|
|
<div class="stat-strip host-health-tiles" style="margin-bottom:0;">
|
|
{{ stat_tile("CPU", pct(cpu), state=(grades.cpu or [status_class(cpu, 'cpu')])[0], hint=sparks.cpu|safe) }}
|
|
{{ stat_tile("Memory", pct(mem), state=(grades.mem or [status_class(mem, 'mem')])[0], hint=sparks.mem|safe) }}
|
|
{%- set inodes_worse = inodes_root is defined and inodes_root is not none and (disk_root is none or inodes_root > disk_root) %}
|
|
{{ stat_tile("Disk /", pct(disk_root) ~ (" · inodes " ~ pct(inodes_root) if inodes_worse else ""),
|
|
state=(grades.disk or [status_class(disk_root, 'disk')])[0], hint=sparks.disk|safe) }}
|
|
{{ stat_tile("Load per core", pct(load_per_core), state=(grades.load or [status_class(load_per_core, 'load')])[0], hint=sparks.load|safe) }}
|
|
</div>
|
|
{% if usual and not stale %}
|
|
<p class="field-hint" style="margin-top:0.6rem;">{{ usual | join("; ") | capitalize }}.</p>
|
|
{% endif %}
|
|
{% if psi.cpu is not none or psi.mem is not none or psi.io is not none %}
|
|
<p class="field-hint" style="margin-top:0.6rem;" title="Pressure stall: the share of the last 10 s that tasks waited for the resource">
|
|
Pressure (10 s): cpu {{ pct(psi.cpu) }} · mem {{ pct(psi.mem) }} · io {{ pct(psi.io) }}
|
|
</p>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|