metrics: fix root device detection
the existing logic does not work for device like /dev/md1 (on the dedis)
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user