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'),
|
fs = require('node:fs'),
|
||||||
net = require('node:net'),
|
net = require('node:net'),
|
||||||
os = require('node:os'),
|
os = require('node:os'),
|
||||||
path = require('node:path'),
|
|
||||||
{ Readable } = require('node:stream'),
|
{ Readable } = require('node:stream'),
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
|
shell = require('./shell.js')('metrics'),
|
||||||
superagent = require('@cloudron/superagent'),
|
superagent = require('@cloudron/superagent'),
|
||||||
_ = require('./underscore.js');
|
_ = require('./underscore.js');
|
||||||
|
|
||||||
@@ -99,23 +99,29 @@ async function readCpuMetrics() {
|
|||||||
return { userMsecs, sysMsecs }; // these values are the times spent since system start
|
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 mounts = await fs.promises.readFile('/proc/mounts', { encoding: 'utf8' });
|
||||||
const rootLine = mounts.split('\n').find(line => line.split(' ')[1] === '/');
|
const rootfsLine = mounts.split('\n').find(line => line.split(' ')[1] === '/');
|
||||||
if (!rootLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Root mount not found');
|
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"
|
// -n is no headings , -d is no holder devices or slaves , -o is output format . PKNAME is parent kernel name
|
||||||
const base = path.basename(devicePath); // remove /dev/
|
const output = await shell.spawn('lsblk', [ '-ndo', 'PKNAME', devicePath ], { encoding: 'utf8' });
|
||||||
const match = base.match(/^(.*?)(p?[0-9]+)?$/);
|
gRootDiskName = output.trim() || devicePath.replace('/dev/', '');
|
||||||
const blockDevice = match ? match[1] : base;
|
return gRootDiskName;
|
||||||
if (!blockDevice) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Could not find root block device name');
|
}
|
||||||
|
|
||||||
|
async function readDiskMetrics() {
|
||||||
|
const rootDiskName = await getRootDiskName();
|
||||||
const diskstats = await fs.promises.readFile('/proc/diskstats', { encoding: 'utf8' });
|
const diskstats = await fs.promises.readFile('/proc/diskstats', { encoding: 'utf8' });
|
||||||
const statsLine = diskstats.split('\n').find(l => l.includes(` ${blockDevice} `));
|
const statsLine = diskstats.split('\n').find(l => l.includes(` ${rootDiskName} `));
|
||||||
if (!statsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, 'Could not get disk stats');
|
if (!statsLine) throw new BoxError(BoxError.EXTERNAL_ERROR, `Could not get disk stats of ${rootDiskName}`);
|
||||||
|
|
||||||
const parts = statsLine.trim().split(/\s+/);
|
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 sectorsWrite = parseInt(parts[9], 10); // field 10
|
||||||
const blockRead = sectorsRead * 512;
|
const blockRead = sectorsRead * 512;
|
||||||
const blockWrite = sectorsWrite * 512;
|
const blockWrite = sectorsWrite * 512;
|
||||||
|
|||||||
Reference in New Issue
Block a user