From c875223db7baeb11c5d6467fb61360793d4f154b Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 15 Oct 2026 00:06:47 +0200 Subject: [PATCH] hive-c0re: the container stats comments and docs name the OTEL exporter as the consumer, not the removed tab --- docs/scheduler/coordinator.md | 3 ++- docs/scheduler/observability.md | 6 +++--- hive-c0re/src/agent_config/resource_limits.rs | 2 +- hive-c0re/src/main.rs | 6 +++--- hive-c0re/src/stats/container_stats.rs | 14 +++++++------- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/scheduler/coordinator.md b/docs/scheduler/coordinator.md index f1c3cbc7..74500d3e 100644 --- a/docs/scheduler/coordinator.md +++ b/docs/scheduler/coordinator.md @@ -548,7 +548,8 @@ wants it. Two things to know about the weights: - They're **hive-wide** — unlike the caps there is no per-agent - setting, so every agent carries the same value and the weight does _not_ rank agents against each other. + setting, so every agent carries the same value and the weight does _not_ + rank agents against each other. What `80` buys is that agents yield to everything **not** on this drop-in path: host services (nginx and dnsmasq among them) and the infra containers (`hive-forge`, `hive-gateway`, `hive-matrix`), which diff --git a/docs/scheduler/observability.md b/docs/scheduler/observability.md index 8749d221..41c4922e 100644 --- a/docs/scheduler/observability.md +++ b/docs/scheduler/observability.md @@ -291,8 +291,8 @@ cleanly and the affected level button goes on returning zero rows: When OTEL is enabled, **hive-c0re itself** also exports each agent -container's resource load — the same cgroup gauges shown on the dashboard -LOAD tab — to this hive's own collector, exactly like an agent does and with +container's resource load — the same cgroup gauges — +to this hive's own collector, exactly like an agent does and with no separate toggle. These come from the host, not the in-container Claude SDK, so they cover containers even when their agent is idle. @@ -312,7 +312,7 @@ exists, so off-the-shelf OTEL/Grafana container dashboards work. Resource | `hyperhive.container.memory.limit` | `By` | gauge | `memory.max` (custom — semconv has no `.limit` metric; omitted when unlimited) | | `hyperhive.container.memory.peak` | `By` | gauge | `memory.peak` (custom — no semconv metric; omitted if unavailable) | | `hyperhive.container.storage.usage` | `By` | gauge | `state/` + `work/` + writable rootfs, measured by `hive-priv` every 30 min (custom — semconv only has `disk.io`; omitted while unknown: not measured yet, or the last measurement failed) | -| `hyperhive.container.cpu.percent` | `%` | gauge | host-normalised percent (custom — the value the dashboard LOAD tab shows, no `rate()` needed) | +| `hyperhive.container.cpu.percent` | `%` | gauge | host-normalised percent (custom — no `rate()` needed) | The `hyperhive.`-prefixed metrics have no semconv equivalent (memory limit + peak, on-disk footprint, and an instantaneous cpu percent kept diff --git a/hive-c0re/src/agent_config/resource_limits.rs b/hive-c0re/src/agent_config/resource_limits.rs index 2adc3623..d9e058c9 100644 --- a/hive-c0re/src/agent_config/resource_limits.rs +++ b/hive-c0re/src/agent_config/resource_limits.rs @@ -19,7 +19,7 @@ //! absent field all fall back to the hive-wide //! `services.hyperhive.agentCpuQuota` / `agentMemoryMax`. So a swarm cap on //! memory alone leaves CPU on the hive default — see -//! [`effective_from_with_swarm`]. +//! [`effective_from`]. //! //! Read path: `lifecycle::host_config::write_dropins`, on every spawn //! and every rebuild. diff --git a/hive-c0re/src/main.rs b/hive-c0re/src/main.rs index 4ebfec67..c0ff3bed 100644 --- a/hive-c0re/src/main.rs +++ b/hive-c0re/src/main.rs @@ -404,9 +404,9 @@ async fn cmd_serve( // ~hundreds of KB, and the /stats + hive-stats views read it // directly; pruning it would just lose trend history for no gain.) // Slow per-container disk sampler: hive-priv measures each agent's state/ - // + work/ + writable rootfs every 30 min, cached so the 5s container-load - // poll stays cheap cgroup-only reads. Feeds `disk_bytes` on the LOAD - // tab. See container_stats::disk_sampler_loop. + // + work/ + writable rootfs every 30 min, cached so a sample only reads + // cgroup files. Feeds `disk_bytes` to the OTEL exporter. See + // container_stats::disk_sampler_loop. crate::container_stats::spawn_disk_sampler(); // Per-agent container-resource OTEL export: rides the same // cgroup gauges out to the configured OTLP endpoint, reusing the hive diff --git a/hive-c0re/src/stats/container_stats.rs b/hive-c0re/src/stats/container_stats.rs index 99b4a26a..0612b2e9 100644 --- a/hive-c0re/src/stats/container_stats.rs +++ b/hive-c0re/src/stats/container_stats.rs @@ -1,6 +1,6 @@ //! Live per-agent-container resource load (CPU + memory, plus the slow -//! disk sample from hive-priv in [`disk_sampler_loop`]) for the -//! dashboard. Reads cgroup v2 stat files for each running agent +//! disk sample from hive-priv in [`disk_sampler_loop`]) for the OTEL +//! exporter. Reads cgroup v2 stat files for each running agent //! machine directly — same privsep-clean posture as the turn-stats //! sqlite reads (`cpu.stat` / `memory.*` are world-readable; no //! `hive-priv` needed). Runs host-side in hive-c0re, where @@ -31,8 +31,8 @@ use utoipa::ToSchema; use crate::coordinator::Coordinator; -/// Sampling interval for the two CPU reads. Short enough to keep the -/// endpoint snappy, long enough that the delta isn't dominated by read +/// Sampling interval for the two CPU reads. Short enough to keep a sample +/// quick, long enough that the delta isn't dominated by read /// jitter. const CPU_SAMPLE: Duration = Duration::from_millis(200); @@ -72,8 +72,8 @@ pub struct ContainerResource { const DISK_SAMPLE_INTERVAL: Duration = Duration::from_mins(30); /// Last per-agent disk measurement, keyed by agent name; `None` is a failed -/// one. Written by [`disk_sampler_loop`], read by [`gather`] so the hot -/// poll never measures. +/// one. Written by [`disk_sampler_loop`], read by [`gather`], so a sample +/// never measures. fn disk_cache() -> &'static RwLock>> { static CACHE: OnceLock>>> = OnceLock::new(); CACHE.get_or_init(|| RwLock::new(HashMap::new())) @@ -100,7 +100,7 @@ fn disk_reading(name: &hive_types::Ident, measured: anyhow::Result) -> Opti /// Background loop: every [`DISK_SAMPLE_INTERVAL`], remeasure disk usage /// for every kept-state agent and refresh [`disk_cache`]. The first pass -/// runs immediately so the dashboard shows disk shortly after boot. +/// runs immediately so the exporter has disk shortly after boot. /// Runs forever; spawn once at hive-c0re startup via [`spawn_disk_sampler`]. pub async fn disk_sampler_loop() { loop {