From f69e545d6429aece0e55975c3b2426f20e91e545 Mon Sep 17 00:00:00 2001 From: Afonso Jorge Ramos Date: Sat, 20 Jun 2026 09:11:12 +0100 Subject: [PATCH] fix(truenas): report actual memory usage and pool free space (#6017) --- .../src/truenas/test/truenas-integration.spec.ts | 13 ++++++++----- .../integrations/src/truenas/truenas-integration.ts | 11 ++++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/integrations/src/truenas/test/truenas-integration.spec.ts b/packages/integrations/src/truenas/test/truenas-integration.spec.ts index 28ff3b8d1..91ab0662c 100644 --- a/packages/integrations/src/truenas/test/truenas-integration.spec.ts +++ b/packages/integrations/src/truenas/test/truenas-integration.spec.ts @@ -132,8 +132,9 @@ const happyResponder = (method: string) => { aggregations: emptyAggregations(), start: 0, end: 1, - legend: [], - data: [[1000, 8_000_000_000]], + // The "memory" graph reports available (free) memory: legend is ["time", "available"]. + legend: ["time", "available"], + data: [[1000, 6_000_000_000]], }, { name: "cputemp", @@ -194,15 +195,17 @@ describe("TrueNasIntegration", () => { version: "TrueNAS-SCALE-24.10", cpuModelName: "Intel Xeon", cpuTemp: 45, - memAvailableInBytes: 16_000_000_000, - memUsedInBytes: 8_000_000_000, + // physmem (16 GB) minus the reported available 6 GB leaves 10 GB used. + memAvailableInBytes: 6_000_000_000, + memUsedInBytes: 10_000_000_000, uptime: 3600, rebootRequired: false, availablePkgUpdates: 0, loadAverage: null, gpu: [], network: { up: 20_000, down: 10_000 }, - fileSystem: [{ deviceName: "tank", available: "1000", used: "500", percentage: 50 }], + // `available` is the free space left on the pool (free = 500), not its total size. + fileSystem: [{ deviceName: "tank", available: "500", used: "500", percentage: 50 }], smart: [{ deviceName: "tank", healthy: true, overallStatus: "ONLINE", temperature: null }], }); }); diff --git a/packages/integrations/src/truenas/truenas-integration.ts b/packages/integrations/src/truenas/truenas-integration.ts index adbe32b3b..21f526201 100644 --- a/packages/integrations/src/truenas/truenas-integration.ts +++ b/packages/integrations/src/truenas/truenas-integration.ts @@ -37,14 +37,19 @@ export class TrueNasIntegration extends Integration implements ISystemHealthMoni const upload = this.extractNetworkTrafficData(netdata, 2); // Index 2 is "sent" const download = this.extractNetworkTrafficData(netdata, 1); // Index 1 is "received" + // The "memory" reporting graph reports available (free) memory, its legend is ["time", "available"]. + // Used memory is therefore the physical total minus what is still available (clamped against timing skew). + const memAvailableInBytes = memoryData[1] ?? 0; // Index 0 is the UNIX timestamp, Index 1 is available bytes + const memUsedInBytes = Math.max(systemInformation.physmem - memAvailableInBytes, 0); + return { cpuUtilization: cpuData.reduce((acc, item) => acc + (item > 100 ? 0 : item), 0) / cpuData.length, cpuTemp: Math.max(...cpuTempData.filter((_item, index) => index > 0)), - memAvailableInBytes: systemInformation.physmem, - memUsedInBytes: memoryData[1] ?? 0, // Index 0 is UNIX timestamp, Index 1 is free space in bytes + memAvailableInBytes, + memUsedInBytes, fileSystem: datasets.map((dataset) => ({ deviceName: dataset.name, - available: `${dataset.size}`, // TODO: can we use number instead of string here? + available: `${dataset.free}`, // free space left on the pool used: `${dataset.allocated}`, percentage: (dataset.allocated / dataset.size) * 100, })),