hive-agent: warn + emit an OTEL gauge on a grown CLAUDE.md

This commit is contained in:
damocles 2026-08-26 18:17:46 +02:00 committed by mara
commit 2e6f38dc6c
4 changed files with 219 additions and 0 deletions

View file

@ -18,6 +18,11 @@
//! from `handle_turn`. The `PeriodicReader` still batches + exports on its
//! own interval; only the recording is event-driven, not the export.
//!
//! [`record_claude_md_lines`] is the one exception, sharing this module's
//! exporter setup rather than [`record`]'s per-turn call site — `CLAUDE.md`
//! size *is* continuously live (like hive-c0re's cgroup values), so
//! [`crate::claude_md_watch`] records it from its own periodic tick instead.
//!
//! Resource attributes (`service.name`, `agent`, `hive`, `swarm`) are picked
//! up automatically by the SDK from the container-wide `OTEL_RESOURCE_ATTRIBUTES`
//! env var (same mechanism `hive-metric` relies on) — nothing to set here.
@ -46,6 +51,11 @@ struct Instruments {
session_count: Counter<u64>,
open_threads: Gauge<u64>,
open_reminders: Gauge<u64>,
/// Recorded from [`crate::claude_md_watch`]'s own tick, not from
/// [`record`] — `CLAUDE.md` size is a continuously-live value (like
/// hive-c0re's container gauges), not a once-per-turn one, so it has
/// its own entry point rather than riding `record`'s per-turn call.
claude_md_lines: Gauge<u64>,
}
/// Lazily built on the first call to [`record`]. `None` when OTEL isn't
@ -87,6 +97,18 @@ pub fn record(row: &TurnStatRow, fresh_session: bool) {
}
}
/// Record the current `CLAUDE.md` line count. Called from
/// [`crate::claude_md_watch`]'s periodic tick (every ~15 minutes, not
/// per turn) — see the field doc on [`Instruments::claude_md_lines`] for
/// why this doesn't ride [`record`]. No-op when OTEL isn't configured,
/// same as `record`.
pub fn record_claude_md_lines(lines: u64) {
let Some(inst) = INSTRUMENTS.get_or_init(build).as_ref() else {
return;
};
inst.claude_md_lines.record(lines, &[]);
}
fn build() -> Option<Instruments> {
if !enabled() {
tracing::debug!("otel turn-metrics: no endpoint configured, exporter disabled");
@ -110,6 +132,7 @@ fn build() -> Option<Instruments> {
open_reminders: meter
.u64_gauge("hyperhive.agent.loose_ends.reminders")
.build(),
claude_md_lines: meter.u64_gauge("hyperhive.agent.claude_md.lines").build(),
_provider: provider,
})
}