/** * Active disk latency probe (embedded, no external ioping binary). * Enable: PEARDATA_IOPING=1 * Path: PEARDATA_IOPING_PATH=/tmp/.peardata-ioping */ import fs from 'fs' import path from 'path' import os from 'os' import { CollectorPlugin } from './plugin.js' import { registerChart } from '../../../shared/metrics.js' export function isIopingEnabled() { const v = process.env.PEARDATA_IOPING return v === '1' || v === 'on' || v === 'true' } function probePath() { return ( process.env.PEARDATA_IOPING_PATH || path.join(os.tmpdir(), '.peardata-ioping') ) } export class IopingCollector extends CollectorPlugin { constructor() { super({ name: 'ioping' }) } isEnabled() { return isIopingEnabled() } async collect() { const ts = Date.now() const p = probePath() const buf = Buffer.alloc(4096, 0x5a) let latency = 0 try { const t0 = process.hrtime.bigint() fs.writeFileSync(p, buf) fs.readFileSync(p) const t1 = process.hrtime.bigint() latency = Number(t1 - t0) / 1e6 try { fs.unlinkSync(p) } catch { // ignore } } catch { latency = -1 } registerChart({ id: 'disk.ioping', name: 'disk.ioping', context: 'disk.ioping', title: 'Disk probe latency', units: 'milliseconds', family: 'ioping', chartType: 'line', priority: 2100, plugin: 'ioping', dimensions: [{ id: 'latency', name: 'latency', algorithm: 'absolute' }], }) return [ { chart: 'disk.ioping', context: 'disk.ioping', ts, values: { latency: latency < 0 ? 0 : latency }, }, ] } } let singleton = null export function getIopingCollector() { if (!singleton) singleton = new IopingCollector() return singleton }