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: