fix: make host memory usage ZFS ARC-aware (#1547)

This commit is contained in:
Anso
2026-07-01 23:08:49 -04:00
committed by GitHub
parent 0adc2b5eb2
commit 98667e0d6f
12 changed files with 574 additions and 30 deletions
+9 -9
View File
@@ -10,6 +10,7 @@ import { FleetUpdateTrackerService, type UpdateTracker, type TerminalStatus, UPD
import { NodeRegistry } from '../services/NodeRegistry';
import { computeNodeNetworkingSummary, type NodeNetworkingSummary } from '../services/network/networkingSummary';
import DockerController from '../services/DockerController';
import { getHostMemory } from '../helpers/hostMemory';
import { FileSystemService } from '../services/FileSystemService';
import { ComposeService } from '../services/ComposeService';
import { StackOpLockService } from '../services/StackOpLockService';
@@ -222,11 +223,11 @@ async function getCompareTarget(gatewayVersion: string | null) {
async function fetchLocalNodeOverview(node: Node): Promise<FleetNodeOverview> {
try {
const composeDir = path.resolve(NodeRegistry.getInstance().getComposeDir(node.id));
const [allContainers, stacks, currentLoad, mem, fsSize] = await Promise.all([
const [allContainers, stacks, currentLoad, hostMem, fsSize] = await Promise.all([
DockerController.getInstance(node.id).getAllContainers(),
FileSystemService.getInstance(node.id).getStacks(),
si.currentLoad(),
si.mem(),
getHostMemory(),
si.fsSize(),
]);
@@ -255,13 +256,12 @@ async function fetchLocalNodeOverview(node: Node): Promise<FleetNodeOverview> {
systemStats: {
cpu: { usage: currentLoad.currentLoad.toFixed(1), cores: currentLoad.cpus.length },
memory: {
total: mem.total,
// Percentage is keyed off mem.active (the real working set), not mem.used:
// on Linux/BSD/macOS mem.used counts reclaimable page cache and reads ~99%
// on a busy host. mem.available is total - active, so used + free = total.
used: mem.active,
free: mem.available,
usagePercent: ((mem.active / mem.total) * 100).toFixed(1),
total: hostMem.total,
// ZFS ARC aware: reclaimable ARC is added back into available so a
// large ARC cache is not reported as hard-used. See helpers/hostMemory.ts.
used: hostMem.used,
free: hostMem.free,
usagePercent: hostMem.usagePercent.toFixed(1),
},
disk: mainDisk ? {
total: mainDisk.size,
+9 -9
View File
@@ -9,6 +9,7 @@ import { PilotTunnelManager } from '../services/PilotTunnelManager';
import { authMiddleware } from '../middleware/auth';
import { requireAdmin } from '../middleware/tierGates';
import { STATS_CACHE_TTL_MS, SYSTEM_STATS_CACHE_TTL_MS } from '../helpers/constants';
import { getHostMemory } from '../helpers/hostMemory';
import { isDebugEnabled } from '../utils/debug';
import { getErrorMessage } from '../utils/errors';
import { isManagedByComposeDir } from '../utils/managed-containers';
@@ -296,9 +297,9 @@ metricsRouter.get('/system/stats', authMiddleware, async (req: Request, res: Res
async () => {
// Remote-node requests are intercepted and proxied upstream before
// reaching here; this fetcher only runs for local nodes.
const [currentLoad, mem, fsSize] = await Promise.all([
const [currentLoad, hostMem, fsSize] = await Promise.all([
si.currentLoad(),
si.mem(),
getHostMemory(),
si.fsSize(),
]);
@@ -310,13 +311,12 @@ metricsRouter.get('/system/stats', authMiddleware, async (req: Request, res: Res
cores: currentLoad.cpus.length,
},
memory: {
total: mem.total,
// Percentage is keyed off mem.active (the real working set), not mem.used:
// on Linux/BSD/macOS mem.used counts reclaimable page cache and reads ~99%
// on a busy host. mem.available is total - active, so used + free = total.
used: mem.active,
free: mem.available,
usagePercent: ((mem.active / mem.total) * 100).toFixed(1),
total: hostMem.total,
// ZFS ARC aware: reclaimable ARC is added back into available so a
// large ARC cache is not reported as hard-used. See helpers/hostMemory.ts.
used: hostMem.used,
free: hostMem.free,
usagePercent: hostMem.usagePercent.toFixed(1),
},
disk: mainDisk ? {
fs: mainDisk.fs,