diff --git a/src/metrics.js b/src/metrics.js index 309afea45..7efb206f3 100644 --- a/src/metrics.js +++ b/src/metrics.js @@ -15,9 +15,9 @@ const apps = require('./apps.js'), fs = require('node:fs'), net = require('node:net'), os = require('node:os'), - path = require('node:path'), { Readable } = require('node:stream'), safe = require('safetydance'), + shell = require('./shell.js')('metrics'), superagent = require('@cloudron/superagent'), _ = require('./underscore.js'); @@ -99,23 +99,29 @@ async function readCpuMetrics() { return { userMsecs, sysMsecs }; // these values are the times spent since system start } -async function readDiskMetrics() { +let gRootDiskName = null; +async function getRootDiskName() { + if (gRootDiskName) return gRootDiskName; + const mounts = await fs.promises.readFile('/proc/mounts', { encoding: 'utf8' }); - const rootLine = mounts.split('\n').find(line => line.split(' ')[1] === '/'); - if (!rootLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Root mount not found'); + const rootfsLine = mounts.split('\n').find(line => line.split(' ')[1] === '/'); + if (!rootfsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Root mount not found'); + const devicePath = rootfsLine.split(' ')[0]; // eg. /dev/foo . This can be a partition or a disk path - const devicePath = rootLine.split(' ')[0]; // e.g., "/dev/sda1" - const base = path.basename(devicePath); // remove /dev/ - const match = base.match(/^(.*?)(p?[0-9]+)?$/); - const blockDevice = match ? match[1] : base; - if (!blockDevice) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Could not find root block device name'); + // -n is no headings , -d is no holder devices or slaves , -o is output format . PKNAME is parent kernel name + const output = await shell.spawn('lsblk', [ '-ndo', 'PKNAME', devicePath ], { encoding: 'utf8' }); + gRootDiskName = output.trim() || devicePath.replace('/dev/', ''); + return gRootDiskName; +} +async function readDiskMetrics() { + const rootDiskName = await getRootDiskName(); const diskstats = await fs.promises.readFile('/proc/diskstats', { encoding: 'utf8' }); - const statsLine = diskstats.split('\n').find(l => l.includes(` ${blockDevice} `)); - if (!statsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Could not get disk stats'); + const statsLine = diskstats.split('\n').find(l => l.includes(` ${rootDiskName} `)); + if (!statsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, `Could not get disk stats of ${rootDiskName}`); const parts = statsLine.trim().split(/\s+/); - const sectorsRead = parseInt(parts[5], 10); // field 6 . one sectiro is 512 bytes + const sectorsRead = parseInt(parts[5], 10); // field 6 . one sector is 512 bytes const sectorsWrite = parseInt(parts[9], 10); // field 10 const blockRead = sectorsRead * 512; const blockWrite = sectorsWrite * 512;