80 lines
1.8 KiB
JavaScript
80 lines
1.8 KiB
JavaScript
/**
|
|
* 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
|
|
}
|