UNPKG

@lodestar/beacon-node

Version:

A Typescript implementation of the beacon chain

130 lines 5.44 kB
// We want to keep `system` export to be used as namespace import os from "node:os"; import path from "node:path"; // We want to keep `system` export as it's more readable and easier to understand import system from "systeminformation"; /** * Singleton class to collect and provide system information */ class System { constructor() { // static data only needs to be collected once this.staticDataCollected = false; // disk I/O is not measurable in some environments this.diskIOMeasurable = true; this.cpuCores = 0; this.cpuThreads = 0; this.cpuNodeSystemSecondsTotal = 0; this.cpuNodeUserSecondsTotal = 0; // Note: CPU I/O wait is not measured by os.cpus() this.cpuNodeIOWaitSecondsTotal = 0; this.cpuNodeIdleSecondsTotal = 0; this.memoryNodeBytesTotal = 0; this.memoryNodeBytesFree = 0; this.memoryNodeBytesCached = 0; this.memoryNodeBytesBuffers = 0; this.diskNodeBytesTotal = 0; this.diskNodeBytesFree = 0; // Note: disk I/O seconds is currently unused by beaconcha.in this.diskNodeIOSeconds = 0; this.diskNodeReadsTotal = 0; this.diskNodeWritesTotal = 0; this.networkNodeBytesTotalReceive = 0; this.networkNodeBytesTotalTransmit = 0; this.miscNodeBootTsSeconds = 0; this.miscOs = "unk"; } /** * Collect system data and update cached values */ async collectData(logger) { const debug = (dataType, e) => logger.debug(`Failed to collect ${dataType} data`, {}, e); await Promise.all([ this.collectStaticData().catch((e) => debug("static system", e)), this.collectCpuData().catch((e) => debug("CPU", e)), this.collectMemoryData().catch((e) => debug("memory", e)), this.collectDiskData().catch((e) => debug("disk", e)), this.collectNetworkData().catch((e) => debug("network", e)), ]); this.miscNodeBootTsSeconds = this.getSystemBootTime(); } async collectStaticData() { if (this.staticDataCollected) return; const cpu = await system.cpu(); // Note: inside container this might be inaccurate as // physicalCores in some cases is the count of logical CPU cores this.cpuCores = cpu.physicalCores; this.cpuThreads = cpu.cores; this.miscOs = this.getNormalizedOsVersion(); this.staticDataCollected = true; } async collectCpuData() { const cpuTimes = {}; for (const cpu of os.cpus()) { // sum up CPU times per mode and convert to seconds for (const [mode, time] of Object.entries(cpu.times)) { if (cpuTimes[mode] == null) cpuTimes[mode] = 0; cpuTimes[mode] += Math.floor(time / 1000); } } // Note: currently beaconcha.in expects system CPU seconds to be everything this.cpuNodeSystemSecondsTotal = Object.values(cpuTimes).reduce((total, time) => total + time, 0); this.cpuNodeUserSecondsTotal = cpuTimes.user; this.cpuNodeIdleSecondsTotal = cpuTimes.idle; } async collectMemoryData() { const memory = await system.mem(); this.memoryNodeBytesTotal = memory.total; this.memoryNodeBytesFree = memory.free; this.memoryNodeBytesCached = memory.cached; this.memoryNodeBytesBuffers = memory.buffers; } async collectDiskData() { const fileSystems = await system.fsSize(); // get file system root, on windows this is the name of the hard disk partition const rootFs = process.platform === "win32" ? process.cwd().split(path.sep)[0] : "/"; // only consider root file system, if it does not exist use first entry in the list const fileSystem = fileSystems.find((fs) => fs.mount === rootFs) ?? fileSystems[0]; this.diskNodeBytesTotal = fileSystem.size; this.diskNodeBytesFree = fileSystem.available; if (this.diskIOMeasurable) { const disk = await system.disksIO(); if (disk != null && disk.rIO !== 0) { // Note: rIO and wIO might not be available inside container // see https://github.com/sebhildebrandt/systeminformation/issues/777 this.diskNodeReadsTotal = disk.rIO; this.diskNodeWritesTotal = disk.wIO; } else { this.diskIOMeasurable = false; } } } async collectNetworkData() { // defaults to first external network interface const [network] = await system.networkStats(); // Note: rx_bytes and tx_bytes will be inaccurate if process // runs inside container as it only captures local network traffic this.networkNodeBytesTotalReceive = network.rx_bytes; this.networkNodeBytesTotalTransmit = network.tx_bytes; } getNormalizedOsVersion() { switch (process.platform) { case "linux": return "lin"; case "darwin": return "mac"; case "win32": return "win"; default: return "unk"; } } getSystemBootTime() { return Math.floor(Date.now() / 1000 - os.uptime()); } } export default new System(); //# sourceMappingURL=system.js.map