refactor(docker): container CPU and memory live in the one metric store (#5752)
#5752 "Container CPU and memory history lives in the one metric store; docker_metrics and docker_metrics_hourly are retired". Container cpu_pct and mem_pct already went to plugin_metrics for alerting; now mem_usage_bytes does too, and every snapshot in an ingest (backlog included) is recorded at its own time. The container history chart, Busiest Containers, a service's history and the MCP container tools read plugin_metrics under resource "<host>/<container>", rolled up and pruned by the shared metric retention. docker_012_drop_metrics drops both tables. Their history is not copied (lesson #5221 "A data migration's cost is set by the live table"); the store already holds 7 days of container CPU and memory %. Docker retention now prunes only lifecycle events, and Settings -> Thresholds has one "Metric retention" card for every source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"""Integration: Busiest Containers bars average each container's samples per
|
||||
time bucket in one query (#5214). Two samples share a bucket and must merge
|
||||
(lesson #5262). Requires STEWARD_DATABASE_URL."""
|
||||
time bucket in one query (#5214), read from the one metric store (#5752). Two
|
||||
samples share a bucket and must merge (lesson #5262). Requires
|
||||
STEWARD_DATABASE_URL."""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
@@ -33,7 +34,7 @@ def _docker(sub):
|
||||
|
||||
def test_recent_usage_averages_each_containers_bucket(app):
|
||||
from steward.models.hosts import Host
|
||||
DockerMetric = _docker("models").DockerMetric
|
||||
from steward.models.metrics import PluginMetric
|
||||
service = _docker("service")
|
||||
bar_slots, recent_usage = service.bar_slots, service.recent_usage
|
||||
|
||||
@@ -43,16 +44,18 @@ def test_recent_usage_averages_each_containers_bucket(app):
|
||||
at = slots[-2] # a whole bucket, in the past
|
||||
|
||||
def m(name, secs, cpu, mem):
|
||||
return DockerMetric(host_id=hid, container_name=name, scraped_at=at + timedelta(seconds=secs),
|
||||
cpu_pct=cpu, mem_pct=0.0, mem_usage_bytes=mem)
|
||||
when = at + timedelta(seconds=secs)
|
||||
return [PluginMetric(source_module="docker", resource_name=f"dock-{tag}/{name}",
|
||||
metric_name=metric, value=value, recorded_at=when)
|
||||
for metric, value in (("cpu_pct", cpu), ("mem_usage_bytes", mem))]
|
||||
|
||||
async def go():
|
||||
async with app.db_sessionmaker() as s:
|
||||
async with s.begin():
|
||||
s.add(Host(id=hid, name=f"dock-{tag}", address="10.9.9.4"))
|
||||
async with s.begin():
|
||||
s.add_all([m(f"a-{tag}", 10, 100.0, 1000), m(f"a-{tag}", 70, 300.0, 3000),
|
||||
m(f"b-{tag}", 10, 50.0, 500)])
|
||||
s.add_all(m(f"a-{tag}", 10, 100.0, 1000) + m(f"a-{tag}", 70, 300.0, 3000)
|
||||
+ m(f"b-{tag}", 10, 50.0, 500))
|
||||
async with s.begin():
|
||||
return await recent_usage(s, {(hid, f"a-{tag}")}, slots[0], width)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user