fix(host_agent): sensors are judged from the raw week, not only its rollups (#5783)
Rollups exist only for hours older than the raw window (7 days by default), so the first deploy read an empty week and judged nothing. refresh now averages the raw samples by the hour and adds any rolled-up hours in the window. Sensors are named from plugin_metric_latest, so each series is read through its index instead of a pattern over every host_agent row. An integration test covers both halves against Postgres. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,13 +111,34 @@ def judge_hosts(rows) -> dict[str, dict[str, str]]:
|
||||
|
||||
async def refresh(session, now: datetime) -> dict[str, dict[str, str]]:
|
||||
"""Re-judge every host's sensors from the last WINDOW of hourly averages,
|
||||
and keep the verdicts for ingest and the pages."""
|
||||
and keep the verdicts for ingest and the pages.
|
||||
|
||||
Hourly rollups exist only for hours older than the raw window
|
||||
(metrics.retention.raw_days, 7 days by default), so the recent hours are
|
||||
averaged from the raw samples here. Retention deletes the raw rows it
|
||||
rolls up, so the two never cover the same hour. The sensors are named
|
||||
from plugin_metric_latest, so each series is read by its index rather
|
||||
than by a pattern over every host_agent row."""
|
||||
global _unwired
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy import func, select
|
||||
from steward.models.metrics import PluginMetric as M
|
||||
from steward.models.metrics import PluginMetricHourly as H
|
||||
rows = (await session.execute(
|
||||
from steward.models.metrics import PluginMetricLatest as L
|
||||
since = now - WINDOW
|
||||
names = (await session.execute(
|
||||
select(L.resource_name).where(L.source_module == "host_agent", L.metric_name == "temp_c"))).scalars().all()
|
||||
if not names:
|
||||
_unwired = {}
|
||||
return _unwired
|
||||
hour = func.date_trunc("hour", M.recorded_at)
|
||||
raw = (await session.execute(
|
||||
select(M.resource_name, hour, func.avg(M.value))
|
||||
.where(M.source_module == "host_agent", M.metric_name == "temp_c",
|
||||
M.resource_name.in_(names), M.recorded_at >= since)
|
||||
.group_by(M.resource_name, hour))).all()
|
||||
rolled = (await session.execute(
|
||||
select(H.resource_name, H.bucket, H.value_avg)
|
||||
.where(H.source_module == "host_agent", H.metric_name == "temp_c",
|
||||
H.resource_name.like("%:temp:%"), H.bucket >= now - WINDOW))).all()
|
||||
_unwired = judge_hosts(rows)
|
||||
H.resource_name.in_(names), H.bucket >= since))).all()
|
||||
_unwired = judge_hosts([*rolled, *raw])
|
||||
return _unwired
|
||||
|
||||
Reference in New Issue
Block a user