forked from snxraven/peardock
Expand server history samples with network/block rates and longer retention, and rebuild the details Stats tab with live KPIs, 1m–30m windows, auto-scale, pause, CSV export, and CPU/memory/net/disk charts.
76 lines
1.9 KiB
JavaScript
76 lines
1.9 KiB
JavaScript
/**
|
|
* Ring-buffer stats history for per-container charts.
|
|
* Samples include CPU, memory, and optional network / block I/O rates.
|
|
*/
|
|
const DEFAULT_MAX_POINTS = Number(process.env.PEARDOCK_STATS_HISTORY_POINTS) || 900
|
|
|
|
/** @type {Map<string, Array<object>>} */
|
|
const history = new Map()
|
|
|
|
/**
|
|
* @param {string} containerId
|
|
* @param {{
|
|
* cpu: number,
|
|
* memory: number,
|
|
* memoryLimit?: number,
|
|
* netRxRate?: number,
|
|
* netTxRate?: number,
|
|
* blkReadRate?: number,
|
|
* blkWriteRate?: number,
|
|
* }} sample
|
|
*/
|
|
export function recordSample(containerId, sample) {
|
|
if (!containerId) return
|
|
let series = history.get(containerId)
|
|
if (!series) {
|
|
series = []
|
|
history.set(containerId, series)
|
|
}
|
|
series.push({
|
|
t: Date.now(),
|
|
cpu: Number(sample.cpu) || 0,
|
|
memory: Number(sample.memory) || 0,
|
|
memoryLimit: Number(sample.memoryLimit) || 0,
|
|
netRxRate: Number(sample.netRxRate) || 0,
|
|
netTxRate: Number(sample.netTxRate) || 0,
|
|
blkReadRate: Number(sample.blkReadRate) || 0,
|
|
blkWriteRate: Number(sample.blkWriteRate) || 0,
|
|
})
|
|
while (series.length > DEFAULT_MAX_POINTS) series.shift()
|
|
}
|
|
|
|
/**
|
|
* @param {string} containerId
|
|
* @param {{ limit?: number, since?: number }} [opts]
|
|
*/
|
|
export function getHistory(containerId, opts = {}) {
|
|
let series = history.get(containerId) || []
|
|
const since = Number(opts.since)
|
|
if (Number.isFinite(since) && since > 0) {
|
|
series = series.filter((p) => p.t >= since)
|
|
}
|
|
const cap = Math.min(
|
|
Number(opts.limit) || DEFAULT_MAX_POINTS,
|
|
DEFAULT_MAX_POINTS
|
|
)
|
|
return series.slice(-cap)
|
|
}
|
|
|
|
/**
|
|
* @param {string[]} activeIds
|
|
*/
|
|
export function pruneMissing(activeIds) {
|
|
const set = new Set(activeIds)
|
|
for (const id of history.keys()) {
|
|
if (!set.has(id)) history.delete(id)
|
|
}
|
|
}
|
|
|
|
export function clearHistory() {
|
|
history.clear()
|
|
}
|
|
|
|
export function maxHistoryPoints() {
|
|
return DEFAULT_MAX_POINTS
|
|
}
|