From 5fb9716dc64a775f5d366082e3bc52ff8c4dd66c Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sun, 22 Nov 2020 18:54:49 -0700 Subject: [PATCH] Add some new MCI codes --- WHATSNEW.md | 1 + core/predefined_mci.js | 28 ++++++++++++++++++--- core/stat_log.js | 56 ++++++++++++++++++++++++++++++++++++++++- core/stat_log_system.js | 28 --------------------- core/system_property.js | 7 ++---- core/wfc.js | 1 + docs/art/mci.md | 6 +++++ 7 files changed, 90 insertions(+), 37 deletions(-) delete mode 100644 core/stat_log_system.js diff --git a/WHATSNEW.md b/WHATSNEW.md index acef4338..a0d48acf 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -8,6 +8,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * An explicit prompt file previously specified by `general.promptFile` in `config.hjson` is no longer necessary. Instead, this now simply part of the `prompts` section in `menu.hjson`. The default setup still creates a separate prompt HJSON file, but it is `includes`ed in `menu.hjson`. With the removal of prompts the `PromptsChanged` event will no longer be fired. * New `PV` ACS check for arbitrary user properties. See [ACS](/docs/configuration/acs.md) for details. * The `message` arg used by `msg_list` has been deprecated. Please starting using `messageIndex` for this purpose. Support for `message` will be removed in the future. +* A number of new MCI codes (see [MCI](./docs/art/mci.md)) ## 0.0.11-beta * Upgraded from `alpha` to `beta` -- The software is far along and mature enough at this point! diff --git a/core/predefined_mci.js b/core/predefined_mci.js index 222b8cc3..50de9304 100644 --- a/core/predefined_mci.js +++ b/core/predefined_mci.js @@ -35,6 +35,11 @@ function init(cb) { (callback) => { return setNextRandomRumor(callback); }, + (callback) => { + // by fetching a memory or load we'll force a refresh now + StatLog.getSystemStat(SysProps.SystemMemoryStats); + return callback(null); + } ], err => { return cb(err); @@ -42,6 +47,7 @@ function init(cb) { ); } +// :TODO: move this to stat_log.js like system memory is handled function setNextRandomRumor(cb) { StatLog.getSystemLogEntries(SysLogKeys.UserAddedRumorz, StatLog.Order.Random, 1, (err, entry) => { if(entry) { @@ -218,9 +224,25 @@ const PREDEFINED_MCI_GENERATORS = { .trim(); }, - // :TODO: use new live stat - MB : function totalMemoryBytes() { return getTotalMemoryBytes(); }, - MF : function totalMemoryFreeBytes() { return getTotalMemoryFreeBytes(); }, + MB : function totalMemoryBytes() { + const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || { totalBytes : 0 }; + return formatByteSize(stats.totalBytes, true); // true=withAbbr + }, + MF : function totalMemoryFreeBytes() { + const stats = StatLog.getSystemStat(SysProps.SystemMemoryStats) || { freeBytes : 0 }; + return formatByteSize(stats.freeBytes, true); // true=withAbbr + }, + LA : function systemLoadAverage() { + const stats = StatLog.getSystemStat(SysProps.SystemLoadStats) || { average : 0.0 }; + return stats.average.toLocaleString(); + }, + CL : function systemCurrentLoad() { + const stats = StatLog.getSystemStat(SysProps.SystemLoadStats) || { current : 0 }; + return `${stats.current}%`; + }, + UU : function systemUptime() { + return moment.duration(process.uptime(), 'seconds').humanize(); + }, // :TODO: MCI for core count, e.g. os.cpus().length diff --git a/core/stat_log.js b/core/stat_log.js index 5355f0c1..55c4620a 100644 --- a/core/stat_log.js +++ b/core/stat_log.js @@ -6,10 +6,12 @@ const { getISOTimestampString } = require('./database.js'); const Errors = require('./enig_error.js'); +const SysProps = require('./system_property.js'); // deps const _ = require('lodash'); const moment = require('moment'); +const SysInfo = require('systeminformation'); /* System Event Log & Stats @@ -26,6 +28,7 @@ const moment = require('moment'); class StatLog { constructor() { this.systemStats = {}; + this.lastSysInfoStatsRefresh = 0; } init(cb) { @@ -107,7 +110,15 @@ class StatLog { ); } - getSystemStat(statName) { return this.systemStats[statName]; } + getSystemStat(statName) { + const stat = this.systemStats[statName]; + + // Some stats are refreshed periodically when they are + // being accessed (e.g. "looked at"). This is handled async. + this._refreshSystemStat(statName); + + return stat; + } getFriendlySystemStat(statName, defaultValue) { return (this.getSystemStat(statName) || defaultValue).toLocaleString(); @@ -377,6 +388,49 @@ class StatLog { systemEventUserLogInit(this); return cb(null); } + + _refreshSystemStat(statName) { + switch (statName) { + case SysProps.SystemLoadStats : + case SysProps.SystemMemoryStats : + return this._refreshSysInfoStats(); + } + } + + _refreshSysInfoStats() { + const now = Math.floor(Date.now() / 1000); + if (now < this.lastSysInfoStatsRefresh + 5) { + return; + } + + this.lastSysInfoStatsRefresh = now; + + const basicSysInfo = { + mem : 'total, free', + currentLoad : 'avgload, currentLoad', + }; + + SysInfo.get(basicSysInfo) + .then(sysInfo => { + const memStats = { + totalBytes : sysInfo.mem.total, + freeBytes : sysInfo.mem.free, + }; + + this.setNonPersistentSystemStat(SysProps.SystemMemoryStats, memStats); + + const loadStats = { + // Not avail on BSD, yet. + average : _.get(sysInfo, 'currentLoad.avgload', 0), + current : _.get(sysInfo, 'currentLoad.currentLoad', 0), + }; + + this.setNonPersistentSystemStat(SysProps.SystemLoadStats, loadStats); + }) + .catch(err => { + // :TODO: log me + }); + } } module.exports = new StatLog(); diff --git a/core/stat_log_system.js b/core/stat_log_system.js deleted file mode 100644 index f027c455..00000000 --- a/core/stat_log_system.js +++ /dev/null @@ -1,28 +0,0 @@ - -// deps -const SysInfo = require('systeminformation'); -const _ = require('lodash'); - -exports.getSystemInfoStats = getSystemInfoStats; - -function getSystemInfoStats(cb) { - const basicSysInfo = { - mem : 'total, free', - currentLoad : 'avgload, currentLoad', - }; - - SysInfo.get(basicSysInfo) - .then(sysInfo => { - return cb(null, { - totalMemoryBytes : sysInfo.mem.total, - freeMemoryBytes : sysInfo.mem.free, - - // Not avail on BSD, yet. - systemAvgLoad : _.get(sysInfo, 'currentLoad.avgload', 0), - systemCurrentLoad : _.get(sysInfo, 'currentLoad.currentLoad', 0), - }); - }) - .catch(err => { - return cb(err); - }); -} diff --git a/core/system_property.js b/core/system_property.js index a74a57d8..a7ebae9d 100644 --- a/core/system_property.js +++ b/core/system_property.js @@ -32,10 +32,7 @@ module.exports = { NextRandomRumor : 'random_rumor', // begin system stat non-persistent... - TotalMemoryBytes : 'sys_total_memory_bytes', - FreeMemoryBytes : 'sys_free_memory_bytes', - AverageLoad : 'sys_average_load', - CurrentLoad : 'sys_current_load', - + SystemMemoryStats : 'system_memory_stats', // object { totalBytes, freeBytes } + SystemLoadStats : 'system_load_stats', // object { average, current } // end system stat non persistent }; diff --git a/core/wfc.js b/core/wfc.js index 53fea670..b8bcc184 100644 --- a/core/wfc.js +++ b/core/wfc.js @@ -121,6 +121,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { }; // Some async work required... + // :TODO: replace with stat log stats const basicSysInfo = { mem : 'total, free', currentLoad : 'avgload, currentLoad', diff --git a/docs/art/mci.md b/docs/art/mci.md index 32c60e4a..099c5f04 100644 --- a/docs/art/mci.md +++ b/docs/art/mci.md @@ -80,6 +80,12 @@ for a full listing. Many codes attempt to pay homage to Oblivion/2, iNiQUiTY, et | `TB` | Total amount of files on the system (formatted to appropriate bytes/megs/gigs/etc.) | | `TP` | Total messages posted/imported to the system *currently* | | `PT` | Total messages posted/imported to the system *today* | +| `MB` | System memory | +| `MF` | System _free_ memory | +| `LA` | System load average (e.g. 0.25)
(Not available for all platforms) | +| `CL` | System current load percentage
(Not available for all platforms) | +| `UU` | System uptime in friendly format | + Some additional special case codes also exist: