Files
peardata/shared/metrics.js
T
Raven Scott c541c27ad8
CI / test (push) Successful in 1m17s
Release rolling / release (push) Successful in 8m15s
Prune work
2026-07-30 12:38:17 -04:00

946 lines
25 KiB
JavaScript

/**
* Metric contexts, charts, and dimension catalog.
*
* Context IDs follow family.metric style (e.g. system.cpu).
* Static charts cover host-wide system stats; instance charts
* (per-CPU, per-disk, per-iface, per-mount) are registered at runtime.
*/
import { DEEP_STATIC_CHARTS } from './metrics-deep.js'
import { MORE_STATIC_CHARTS } from './metrics-more.js'
export const SAMPLE_INTERVAL_MS = 1000
export {
makeDiskAwaitChart,
makeDiskAvgszChart,
makeDiskQopsChart,
makeDiskBusyChart,
makeDiskIotimeChart,
makeDiskDiscardChart,
makeNetSpeedChart,
makeCgroupCpuChart,
makeCgroupMemChart,
makeCgroupIoChart,
makeSensorTempChart,
makeThermalZoneChart,
} from './metrics-deep.js'
export {
makeDiskSvctmChart,
makeDiskMergedChart,
makeDiskFlushChart,
makeNetDuplexChart,
makeNetMtuChart,
makeNetQueueChart,
makeIrqChart,
makeCpuIdleChart,
makeNumaNodeMemChart,
makeCgroupMemDetailChart,
makeCgroupThrottleChart,
} from './metrics-more.js'
/**
* @typedef {{ id: string, name: string, algorithm: 'absolute'|'incremental', multiplier?: number, divisor?: number }} DimensionDef
* @typedef {{
* id: string,
* name: string,
* context: string,
* title: string,
* units: string,
* family: string,
* chartType: 'line'|'area'|'stacked',
* priority: number,
* dimensions: DimensionDef[],
* plugin?: string,
* }} ChartDef
*/
/** @type {ChartDef[]} */
export const STATIC_CHART_DEFS = [
// ── CPU / scheduler ───────────────────────────────────────
{
id: 'system.cpu',
name: 'system.cpu',
context: 'system.cpu',
title: 'Total CPU utilization',
units: 'percentage',
family: 'cpu',
chartType: 'stacked',
priority: 100,
plugin: 'proc',
dimensions: [
{ id: 'guest_nice', name: 'guest_nice', algorithm: 'absolute' },
{ id: 'guest', name: 'guest', algorithm: 'absolute' },
{ id: 'steal', name: 'steal', algorithm: 'absolute' },
{ id: 'softirq', name: 'softirq', algorithm: 'absolute' },
{ id: 'irq', name: 'irq', algorithm: 'absolute' },
{ id: 'user', name: 'user', algorithm: 'absolute' },
{ id: 'system', name: 'system', algorithm: 'absolute' },
{ id: 'nice', name: 'nice', algorithm: 'absolute' },
{ id: 'iowait', name: 'iowait', algorithm: 'absolute' },
{ id: 'idle', name: 'idle', algorithm: 'absolute' },
],
},
{
id: 'system.intr',
name: 'system.intr',
context: 'system.intr',
title: 'CPU Interrupts',
units: 'interrupts/s',
family: 'interrupts',
chartType: 'line',
priority: 110,
plugin: 'proc',
dimensions: [{ id: 'interrupts', name: 'interrupts', algorithm: 'incremental' }],
},
{
id: 'system.ctxt',
name: 'system.ctxt',
context: 'system.ctxt',
title: 'CPU Context Switches',
units: 'context switches/s',
family: 'processes',
chartType: 'line',
priority: 120,
plugin: 'proc',
dimensions: [{ id: 'switches', name: 'switches', algorithm: 'incremental' }],
},
{
id: 'system.forks',
name: 'system.forks',
context: 'system.forks',
title: 'Started Processes',
units: 'processes/s',
family: 'processes',
chartType: 'line',
priority: 130,
plugin: 'proc',
dimensions: [{ id: 'started', name: 'started', algorithm: 'incremental' }],
},
{
id: 'system.processes',
name: 'system.processes',
context: 'system.processes',
title: 'System Processes',
units: 'processes',
family: 'processes',
chartType: 'line',
priority: 140,
plugin: 'proc',
dimensions: [
{ id: 'running', name: 'running', algorithm: 'absolute' },
{ id: 'blocked', name: 'blocked', algorithm: 'absolute' },
],
},
{
id: 'system.active_processes',
name: 'system.active_processes',
context: 'system.active_processes',
title: 'System Active Processes',
units: 'processes',
family: 'processes',
chartType: 'line',
priority: 145,
plugin: 'proc',
dimensions: [{ id: 'active', name: 'active', algorithm: 'absolute' }],
},
{
id: 'system.load',
name: 'system.load',
context: 'system.load',
title: 'System Load Average',
units: 'load',
family: 'load',
chartType: 'line',
priority: 150,
plugin: 'proc',
dimensions: [
{ id: 'load1', name: 'load1', algorithm: 'absolute' },
{ id: 'load5', name: 'load5', algorithm: 'absolute' },
{ id: 'load15', name: 'load15', algorithm: 'absolute' },
],
},
{
id: 'system.uptime',
name: 'system.uptime',
context: 'system.uptime',
title: 'System Uptime',
units: 'seconds',
family: 'uptime',
chartType: 'line',
priority: 160,
plugin: 'proc',
dimensions: [{ id: 'uptime', name: 'uptime', algorithm: 'absolute' }],
},
{
id: 'system.entropy',
name: 'system.entropy',
context: 'system.entropy',
title: 'Available Entropy',
units: 'entropy',
family: 'entropy',
chartType: 'line',
priority: 170,
plugin: 'proc',
dimensions: [{ id: 'entropy', name: 'entropy', algorithm: 'absolute' }],
},
// ── Memory ────────────────────────────────────────────────
{
id: 'system.ram',
name: 'system.ram',
context: 'system.ram',
title: 'System RAM',
units: 'MiB',
family: 'ram',
chartType: 'stacked',
priority: 200,
plugin: 'proc',
dimensions: [
{ id: 'free', name: 'free', algorithm: 'absolute' },
{ id: 'used', name: 'used', algorithm: 'absolute' },
{ id: 'cached', name: 'cached', algorithm: 'absolute' },
{ id: 'buffers', name: 'buffers', algorithm: 'absolute' },
],
},
{
id: 'mem.available',
name: 'mem.available',
context: 'mem.available',
title: 'Available RAM for applications',
units: 'MiB',
family: 'ram',
chartType: 'area',
priority: 210,
plugin: 'proc',
dimensions: [{ id: 'avail', name: 'avail', algorithm: 'absolute' }],
},
{
id: 'mem.swap',
name: 'mem.swap',
context: 'mem.swap',
title: 'System Swap',
units: 'MiB',
family: 'swap',
chartType: 'stacked',
priority: 220,
plugin: 'proc',
dimensions: [
{ id: 'free', name: 'free', algorithm: 'absolute' },
{ id: 'used', name: 'used', algorithm: 'absolute' },
],
},
{
id: 'mem.swap_cached',
name: 'mem.swap_cached',
context: 'mem.swap_cached',
title: 'Swap Cached',
units: 'MiB',
family: 'swap',
chartType: 'area',
priority: 225,
plugin: 'proc',
dimensions: [{ id: 'cached', name: 'cached', algorithm: 'absolute' }],
},
{
id: 'mem.kernel',
name: 'mem.kernel',
context: 'mem.kernel',
title: 'Memory Used by Kernel',
units: 'MiB',
family: 'kernel',
chartType: 'stacked',
priority: 230,
plugin: 'proc',
dimensions: [
{ id: 'slab', name: 'slab', algorithm: 'absolute' },
{ id: 'kernel_stack', name: 'kernel_stack', algorithm: 'absolute' },
{ id: 'page_tables', name: 'page_tables', algorithm: 'absolute' },
{ id: 'vmalloc_used', name: 'vmalloc_used', algorithm: 'absolute' },
{ id: 'percpu', name: 'percpu', algorithm: 'absolute' },
],
},
{
id: 'mem.slab',
name: 'mem.slab',
context: 'mem.slab',
title: 'Reclaimable Kernel Memory',
units: 'MiB',
family: 'slab',
chartType: 'stacked',
priority: 235,
plugin: 'proc',
dimensions: [
{ id: 'reclaimable', name: 'reclaimable', algorithm: 'absolute' },
{ id: 'unreclaimable', name: 'unreclaimable', algorithm: 'absolute' },
],
},
{
id: 'mem.writeback',
name: 'mem.writeback',
context: 'mem.writeback',
title: 'Writeback Memory',
units: 'MiB',
family: 'writeback',
chartType: 'line',
priority: 240,
plugin: 'proc',
dimensions: [
{ id: 'dirty', name: 'dirty', algorithm: 'absolute' },
{ id: 'writeback', name: 'writeback', algorithm: 'absolute' },
{ id: 'FuseWriteback', name: 'FuseWriteback', algorithm: 'absolute' },
{ id: 'NfsWriteback', name: 'NfsWriteback', algorithm: 'absolute' },
{ id: 'Bounce', name: 'Bounce', algorithm: 'absolute' },
],
},
{
id: 'mem.committed',
name: 'mem.committed',
context: 'mem.committed',
title: 'Committed (Allocated) Memory',
units: 'MiB',
family: 'committed',
chartType: 'area',
priority: 245,
plugin: 'proc',
dimensions: [{ id: 'Committed_AS', name: 'Committed_AS', algorithm: 'absolute' }],
},
{
id: 'mem.swapio',
name: 'mem.swapio',
context: 'mem.swapio',
title: 'Swap I/O',
units: 'KiB/s',
family: 'swap',
chartType: 'area',
priority: 250,
plugin: 'proc',
dimensions: [
{ id: 'in', name: 'in', algorithm: 'incremental' },
{ id: 'out', name: 'out', algorithm: 'incremental' },
],
},
{
id: 'system.pgpgio',
name: 'system.pgpgio',
context: 'system.pgpgio',
title: 'Memory Page I/O',
units: 'KiB/s',
family: 'pgpgio',
chartType: 'area',
priority: 260,
plugin: 'proc',
dimensions: [
{ id: 'in', name: 'in', algorithm: 'incremental' },
{ id: 'out', name: 'out', algorithm: 'incremental' },
],
},
{
id: 'system.pgfaults',
name: 'system.pgfaults',
context: 'system.pgfaults',
title: 'Memory Page Faults',
units: 'faults/s',
family: 'pgfaults',
chartType: 'line',
priority: 270,
plugin: 'proc',
dimensions: [
{ id: 'minor', name: 'minor', algorithm: 'incremental' },
{ id: 'major', name: 'major', algorithm: 'incremental' },
],
},
// ── Aggregate disk / network ──────────────────────────────
{
id: 'system.io',
name: 'system.io',
context: 'system.io',
title: 'Disk I/O',
units: 'KiB/s',
family: 'disk',
chartType: 'area',
priority: 400,
plugin: 'proc',
dimensions: [
{ id: 'in', name: 'in', algorithm: 'incremental' },
{ id: 'out', name: 'out', algorithm: 'incremental' },
],
},
{
id: 'system.net',
name: 'system.net',
context: 'system.net',
title: 'Physical Network Interfaces Bandwidth',
units: 'kilobits/s',
family: 'network',
chartType: 'area',
priority: 500,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
},
{
id: 'system.ip',
name: 'system.ip',
context: 'system.ip',
title: 'IP Bandwidth',
units: 'kilobits/s',
family: 'ip',
chartType: 'area',
priority: 600,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
},
{
id: 'system.ipv6',
name: 'system.ipv6',
context: 'system.ipv6',
title: 'IPv6 Bandwidth',
units: 'kilobits/s',
family: 'ipv6',
chartType: 'area',
priority: 610,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
},
// ── IP / TCP / UDP aggregates ─────────────────────────────
{
id: 'ip.tcppackets',
name: 'ip.tcppackets',
context: 'ip.tcppackets',
title: 'TCP Packets',
units: 'packets/s',
family: 'tcp',
chartType: 'line',
priority: 700,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
},
{
id: 'ip.tcperrors',
name: 'ip.tcperrors',
context: 'ip.tcperrors',
title: 'TCP Errors',
units: 'packets/s',
family: 'tcp',
chartType: 'line',
priority: 710,
plugin: 'proc',
dimensions: [
{ id: 'InErrs', name: 'InErrs', algorithm: 'incremental' },
{ id: 'InCsumErrors', name: 'InCsumErrors', algorithm: 'incremental' },
{ id: 'RetransSegs', name: 'RetransSegs', algorithm: 'incremental' },
],
},
{
id: 'ip.tcpopens',
name: 'ip.tcpopens',
context: 'ip.tcpopens',
title: 'TCP Connections',
units: 'connections/s',
family: 'tcp',
chartType: 'line',
priority: 720,
plugin: 'proc',
dimensions: [
{ id: 'active', name: 'active', algorithm: 'incremental' },
{ id: 'passive', name: 'passive', algorithm: 'incremental' },
],
},
{
id: 'ip.tcpsock',
name: 'ip.tcpsock',
context: 'ip.tcpsock',
title: 'TCP Connections Current',
units: 'connections',
family: 'tcp',
chartType: 'line',
priority: 725,
plugin: 'proc',
dimensions: [{ id: 'connections', name: 'connections', algorithm: 'absolute' }],
},
{
id: 'ipv4.packets',
name: 'ipv4.packets',
context: 'ipv4.packets',
title: 'IPv4 Packets',
units: 'packets/s',
family: 'packets',
chartType: 'line',
priority: 740,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
{ id: 'forwarded', name: 'forwarded', algorithm: 'incremental' },
{ id: 'delivered', name: 'delivered', algorithm: 'incremental' },
],
},
{
id: 'ipv4.errors',
name: 'ipv4.errors',
context: 'ipv4.errors',
title: 'IPv4 Errors',
units: 'packets/s',
family: 'errors',
chartType: 'line',
priority: 750,
plugin: 'proc',
dimensions: [
{ id: 'InDiscards', name: 'InDiscards', algorithm: 'incremental' },
{ id: 'OutDiscards', name: 'OutDiscards', algorithm: 'incremental' },
{ id: 'InHdrErrors', name: 'InHdrErrors', algorithm: 'incremental' },
{ id: 'OutNoRoutes', name: 'OutNoRoutes', algorithm: 'incremental' },
],
},
{
id: 'ipv4.udppackets',
name: 'ipv4.udppackets',
context: 'ipv4.udppackets',
title: 'IPv4 UDP Packets',
units: 'packets/s',
family: 'udp',
chartType: 'line',
priority: 760,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
},
{
id: 'ipv4.udperrors',
name: 'ipv4.udperrors',
context: 'ipv4.udperrors',
title: 'IPv4 UDP Errors',
units: 'packets/s',
family: 'udp',
chartType: 'line',
priority: 770,
plugin: 'proc',
dimensions: [
{ id: 'RcvbufErrors', name: 'RcvbufErrors', algorithm: 'incremental' },
{ id: 'SndbufErrors', name: 'SndbufErrors', algorithm: 'incremental' },
{ id: 'InErrors', name: 'InErrors', algorithm: 'incremental' },
{ id: 'NoPorts', name: 'NoPorts', algorithm: 'incremental' },
],
},
// ── Pressure stall (PSI) ──────────────────────────────────
{
id: 'system.cpu_some_pressure',
name: 'system.cpu_some_pressure',
context: 'system.cpu_some_pressure',
title: 'CPU Some Pressure',
units: 'percentage',
family: 'pressure',
chartType: 'line',
priority: 800,
plugin: 'proc',
dimensions: [
{ id: 'some10', name: 'some10', algorithm: 'absolute' },
{ id: 'some60', name: 'some60', algorithm: 'absolute' },
{ id: 'some300', name: 'some300', algorithm: 'absolute' },
],
},
{
id: 'system.memory_some_pressure',
name: 'system.memory_some_pressure',
context: 'system.memory_some_pressure',
title: 'Memory Some Pressure',
units: 'percentage',
family: 'pressure',
chartType: 'line',
priority: 810,
plugin: 'proc',
dimensions: [
{ id: 'some10', name: 'some10', algorithm: 'absolute' },
{ id: 'some60', name: 'some60', algorithm: 'absolute' },
{ id: 'some300', name: 'some300', algorithm: 'absolute' },
],
},
{
id: 'system.io_some_pressure',
name: 'system.io_some_pressure',
context: 'system.io_some_pressure',
title: 'I/O Some Pressure',
units: 'percentage',
family: 'pressure',
chartType: 'line',
priority: 820,
plugin: 'proc',
dimensions: [
{ id: 'some10', name: 'some10', algorithm: 'absolute' },
{ id: 'some60', name: 'some60', algorithm: 'absolute' },
{ id: 'some300', name: 'some300', algorithm: 'absolute' },
],
},
...DEEP_STATIC_CHARTS,
...MORE_STATIC_CHARTS,
]
/** @type {Map<string, ChartDef>} */
const runtimeCharts = new Map()
/** Static (host-wide catalog) chart ids — used for warm HyperDB cardinality gating. */
const STATIC_CHART_IDS = new Set(STATIC_CHART_DEFS.map((c) => c.id))
/**
* Whether a chart should be flushed to HyperDB warm storage.
* High-cardinality instance charts (per-disk, per-iface, cgroup, docker, …)
* stay in RAM rings only unless PEARDATA_WARM_ALL_CHARTS=1.
*
* @param {string} chartId
* @returns {boolean}
*/
export function isWarmPersistableChart(chartId) {
const all = process.env.PEARDATA_WARM_ALL_CHARTS
if (all === '1' || all === 'true' || all === 'on') return true
return STATIC_CHART_IDS.has(String(chartId))
}
/**
* Register or refresh a dynamic instance chart (per-cpu / disk / iface / mount).
* @param {ChartDef} def
*/
export function registerChart(def) {
runtimeCharts.set(def.id, def)
}
/**
* @returns {ChartDef[]}
*/
export function getAllChartDefs() {
return [...STATIC_CHART_DEFS, ...runtimeCharts.values()]
}
/** Alias — prefer getAllChartDefs() when instance charts matter. */
export const CHART_DEFS = STATIC_CHART_DEFS
export const CHART_BY_ID = {
get(id) {
const sid = String(id)
return STATIC_CHART_DEFS.find((c) => c.id === sid) || runtimeCharts.get(sid) || null
},
has(id) {
return this.get(id) != null
},
keys() {
return getAllChartDefs().map((c) => c.id)
},
values() {
return getAllChartDefs()
},
get size() {
return getAllChartDefs().length
},
}
export function getContextIds() {
return [...new Set(getAllChartDefs().map((c) => c.context))]
}
/** @deprecated use getContextIds() */
export const CONTEXT_IDS = {
map(fn) {
return getContextIds().map(fn)
},
includes(id) {
return getContextIds().includes(id)
},
[Symbol.iterator]() {
return getContextIds()[Symbol.iterator]()
},
get length() {
return getContextIds().length
},
}
/**
* @param {string} context
*/
export function chartsForContext(context) {
return getAllChartDefs().filter((c) => c.context === context)
}
/**
* Instance chart helpers
*/
export function makeCpuCoreChart(coreId) {
return {
id: `cpu.cpu${coreId}`,
name: `cpu.cpu${coreId}`,
context: 'cpu.cpu',
title: `Core ${coreId} utilization`,
units: 'percentage',
family: `cpu${coreId}`,
chartType: 'stacked',
priority: 1000 + Number(coreId),
plugin: 'proc',
dimensions: STATIC_CHART_DEFS.find((c) => c.id === 'system.cpu').dimensions.slice(),
}
}
export function makeDiskIoChart(disk) {
return {
id: `disk_io.${disk}`,
name: `disk_io.${disk}`,
context: 'disk.io',
title: `Disk ${disk} I/O`,
units: 'KiB/s',
family: disk,
chartType: 'area',
priority: 2000,
plugin: 'proc',
dimensions: [
{ id: 'reads', name: 'reads', algorithm: 'incremental' },
{ id: 'writes', name: 'writes', algorithm: 'incremental' },
],
}
}
export function makeDiskOpsChart(disk) {
return {
id: `disk_ops.${disk}`,
name: `disk_ops.${disk}`,
context: 'disk.ops',
title: `Disk ${disk} Completed I/O Operations`,
units: 'operations/s',
family: disk,
chartType: 'line',
priority: 2010,
plugin: 'proc',
dimensions: [
{ id: 'reads', name: 'reads', algorithm: 'incremental' },
{ id: 'writes', name: 'writes', algorithm: 'incremental' },
],
}
}
export function makeDiskUtilChart(disk) {
return {
id: `disk_util.${disk}`,
name: `disk_util.${disk}`,
context: 'disk.util',
title: `Disk ${disk} Utilization Time`,
units: '% of time working',
family: disk,
chartType: 'area',
priority: 2020,
plugin: 'proc',
dimensions: [{ id: 'utilization', name: 'utilization', algorithm: 'absolute' }],
}
}
export function makeNetChart(iface) {
return {
id: `net.${iface}`,
name: `net.${iface}`,
context: 'net.net',
title: `Bandwidth ${iface}`,
units: 'kilobits/s',
family: iface,
chartType: 'area',
priority: 3000,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
],
}
}
export function makeNetPacketsChart(iface) {
return {
id: `net_packets.${iface}`,
name: `net_packets.${iface}`,
context: 'net.packets',
title: `Packets ${iface}`,
units: 'packets/s',
family: iface,
chartType: 'line',
priority: 3010,
plugin: 'proc',
dimensions: [
{ id: 'received', name: 'received', algorithm: 'incremental' },
{ id: 'sent', name: 'sent', algorithm: 'incremental' },
{ id: 'multicast', name: 'multicast', algorithm: 'incremental' },
],
}
}
export function makeNetErrorsChart(iface) {
return {
id: `net_errors.${iface}`,
name: `net_errors.${iface}`,
context: 'net.errors',
title: `Interface ${iface} Errors`,
units: 'errors/s',
family: iface,
chartType: 'line',
priority: 3020,
plugin: 'proc',
dimensions: [
{ id: 'inbound', name: 'inbound', algorithm: 'incremental' },
{ id: 'outbound', name: 'outbound', algorithm: 'incremental' },
],
}
}
export function makeNetDropsChart(iface) {
return {
id: `net_drops.${iface}`,
name: `net_drops.${iface}`,
context: 'net.drops',
title: `Interface ${iface} Drops`,
units: 'drops/s',
family: iface,
chartType: 'line',
priority: 3030,
plugin: 'proc',
dimensions: [
{ id: 'inbound', name: 'inbound', algorithm: 'incremental' },
{ id: 'outbound', name: 'outbound', algorithm: 'incremental' },
],
}
}
export function makeDiskSpaceChart(mountId, mountPath) {
return {
id: `disk_space.${mountId}`,
name: `disk_space.${mountId}`,
context: 'disk.space',
title: `Disk Space Usage ${mountPath}`,
units: 'GiB',
family: mountPath,
chartType: 'stacked',
priority: 4000,
plugin: 'diskspace',
dimensions: [
{ id: 'avail', name: 'avail', algorithm: 'absolute' },
{ id: 'used', name: 'used', algorithm: 'absolute' },
{ id: 'reserved_for_root', name: 'reserved_for_root', algorithm: 'absolute' },
],
}
}
export function makeDiskInodesChart(mountId, mountPath) {
return {
id: `disk_inodes.${mountId}`,
name: `disk_inodes.${mountId}`,
context: 'disk.inodes',
title: `Disk Files (inodes) Usage ${mountPath}`,
units: 'inodes',
family: mountPath,
chartType: 'stacked',
priority: 4010,
plugin: 'diskspace',
dimensions: [
{ id: 'avail', name: 'avail', algorithm: 'absolute' },
{ id: 'used', name: 'used', algorithm: 'absolute' },
{ id: 'reserved_for_root', name: 'reserved_for_root', algorithm: 'absolute' },
],
}
}
/** Static aggregate when Docker collector is enabled */
export const DOCKER_CONTAINERS_CHART = {
id: 'docker.containers',
name: 'docker.containers',
context: 'docker.containers',
title: 'Running containers',
units: 'containers',
family: 'containers',
chartType: 'line',
priority: 5000,
plugin: 'docker',
dimensions: [
{ id: 'running', name: 'running', algorithm: 'absolute' },
{ id: 'total', name: 'total', algorithm: 'absolute' },
],
}
export function makeDockerCpuChart(shortId, name) {
const id = shortId.replace(/[^a-zA-Z0-9_.-]/g, '_').slice(0, 64)
const display = name || `container ${id}`
return {
id: `docker.cpu.${id}`,
name: `docker.cpu.${id}`,
context: 'docker.cpu',
title: `${display} · CPU`,
units: 'percentage',
family: display,
chartType: 'area',
priority: 5100,
plugin: 'docker',
dimensions: [{ id: 'usage', name: 'usage', algorithm: 'absolute' }],
}
}
export function makeDockerMemChart(shortId, name) {
const id = shortId.replace(/[^a-zA-Z0-9_.-]/g, '_').slice(0, 64)
const display = name || `container ${id}`
return {
id: `docker.mem.${id}`,
name: `docker.mem.${id}`,
context: 'docker.mem',
title: `${display} · memory`,
units: 'MiB',
family: display,
chartType: 'area',
priority: 5200,
plugin: 'docker',
dimensions: [
{ id: 'usage', name: 'usage', algorithm: 'absolute' },
{ id: 'limit', name: 'limit', algorithm: 'absolute' },
],
}
}
/**
* Build a chart summary object for discovery APIs.
* @param {ChartDef} def
* @param {{ firstEntry?: number, lastEntry?: number, updateEvery?: number }} [meta]
*/
export function chartSummary(def, meta = {}) {
const dimensions = {}
for (const d of def.dimensions) {
dimensions[d.id] = {
name: d.name,
algorithm: d.algorithm,
multiplier: d.multiplier ?? 1,
divisor: d.divisor ?? 1,
}
}
return {
id: def.id,
name: def.name,
type: def.plugin || 'system',
family: def.family,
context: def.context,
title: def.title,
units: def.units,
chart_type: def.chartType,
priority: def.priority,
plugin: def.plugin || 'proc',
update_every: meta.updateEvery ?? SAMPLE_INTERVAL_MS / 1000,
first_entry: meta.firstEntry ?? 0,
last_entry: meta.lastEntry ?? 0,
dimensions,
}
}