fix(docker): a container's memory is its processes' own; file cache shown on its page (#6030)
The agent sent Docker's working set (usage less inactive_file), which still counts recently used file cache. A file-heavy container with no limit read 191 GB while its processes held 2.2 GB, and the host's own figure, which already leaves cache out, disagreed with it. Agent 1.23.0 sends mem_used_bytes / mem_used_pct (anon + shmem, so Postgres's shared buffers count; v1: rss + shmem) and mem_cache_bytes apart. The new names keep the two meanings apart in history and in learned normals: docker_013 renames the columns, clears the old values and adds mem_cache_bytes. The Docker page, swarm by-node sums, Busiest Containers, container detail, normals and the MCP tools all read the new figure. File cache is shown only on the container's page and in get_container. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,16 +50,41 @@ def test_docker_cpu_pct_guards_bad_stats():
|
||||
}) == 0.0
|
||||
|
||||
|
||||
def test_docker_mem_subtracts_cache():
|
||||
def test_docker_mem_is_process_memory_not_file_cache():
|
||||
# cgroup v2, as curator_app read on 2026-10-17 (#6030): 315 GB charged to
|
||||
# it, 2.2 GB its own; Docker's working set (usage − inactive_file) said 191 GB.
|
||||
stats = {"memory_stats": {
|
||||
"usage": 200 * 1024 * 1024,
|
||||
"limit": 1000 * 1024 * 1024,
|
||||
"stats": {"cache": 50 * 1024 * 1024},
|
||||
"usage": 314_896_379_904,
|
||||
"limit": 405_493_768_192,
|
||||
"stats": {"anon": 2_241_888_256, "shmem": 106_496, "file": 312_003_436_544,
|
||||
"active_file": 188_779_880_448, "inactive_file": 123_223_449_600},
|
||||
}}
|
||||
usage, limit, pct = a._docker_mem(stats)
|
||||
assert usage == 150 * 1024 * 1024 # working set = usage − cache
|
||||
assert limit == 1000 * 1024 * 1024
|
||||
assert pct == 15.0
|
||||
used, limit, pct, cache = a._docker_mem(stats)
|
||||
assert used == 2_241_888_256 + 106_496
|
||||
assert limit == 405_493_768_192
|
||||
assert pct == 0.55
|
||||
assert cache == 312_003_436_544 - 106_496 # shmem is in file; counted as used, not cache
|
||||
|
||||
|
||||
def test_docker_mem_counts_shared_memory_as_used():
|
||||
# Postgres keeps its shared buffers in shmem: not anon, but not reclaimable.
|
||||
mib = 1024 * 1024
|
||||
stats = {"memory_stats": {"usage": 900 * mib, "limit": 1000 * mib,
|
||||
"stats": {"anon": 100 * mib, "shmem": 400 * mib, "file": 700 * mib}}}
|
||||
assert a._docker_mem(stats) == (500 * mib, 1000 * mib, 50.0, 300 * mib)
|
||||
|
||||
|
||||
def test_docker_mem_reads_cgroup_v1():
|
||||
# v1's rss leaves shmem out and its cache has it in.
|
||||
mib = 1024 * 1024
|
||||
stats = {"memory_stats": {"usage": 200 * mib, "limit": 1000 * mib,
|
||||
"stats": {"total_rss": 120 * mib, "total_shmem": 30 * mib,
|
||||
"total_cache": 80 * mib, "rss": 1, "cache": 1}}}
|
||||
assert a._docker_mem(stats) == (150 * mib, 1000 * mib, 15.0, 50 * mib)
|
||||
|
||||
|
||||
def test_docker_mem_without_stats_is_zero():
|
||||
assert a._docker_mem({}) == (0, 0, 0.0, 0)
|
||||
|
||||
|
||||
def test_docker_ports_keeps_only_published():
|
||||
@@ -162,7 +187,8 @@ def test_collect_docker_assembles_container(monkeypatch):
|
||||
"precpu_stats": {"cpu_usage": {"total_usage": 100_000_000},
|
||||
"system_cpu_usage": 1_000_000_000},
|
||||
"memory_stats": {"usage": 200 * 1024 * 1024, "limit": 1000 * 1024 * 1024,
|
||||
"stats": {"cache": 50 * 1024 * 1024}},
|
||||
"stats": {"anon": 140 * 1024 * 1024, "shmem": 10 * 1024 * 1024,
|
||||
"file": 60 * 1024 * 1024}},
|
||||
"networks": {"eth0": {"rx_bytes": 1000, "tx_bytes": 2000}},
|
||||
"blkio_stats": {"io_service_bytes_recursive": [
|
||||
{"op": "Read", "value": 4096}, {"op": "Write", "value": 8192}]},
|
||||
@@ -187,7 +213,8 @@ def test_collect_docker_assembles_container(monkeypatch):
|
||||
assert c["image"] == "nginx:latest"
|
||||
assert c["status"] == "running"
|
||||
assert c["cpu_pct"] == 40.0
|
||||
assert c["mem_pct"] == 15.0
|
||||
assert c["mem_used_bytes"] == 150 * 1024 * 1024 and c["mem_used_pct"] == 15.0
|
||||
assert c["mem_cache_bytes"] == 50 * 1024 * 1024
|
||||
assert c["ports"] == [{"host_port": 8080, "container_port": 80, "protocol": "tcp"}]
|
||||
# When it last started (inspect), not when it was created (2020).
|
||||
assert c["started_at"] == "2023-11-14T22:13:20.123456+00:00"
|
||||
|
||||
Reference in New Issue
Block a user