New live stat: Total new users today

* Add NT (Obv/2 throwback) MCI for new users today
* Keep live stat up to date in stat log
* Exposed via WFC
This commit is contained in:
Bryan Ashby 2022-05-07 10:48:40 -06:00
parent bb86f386e9
commit 9e5b3369a5
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
13 changed files with 49 additions and 22 deletions

View File

@ -259,7 +259,7 @@
mainInfoFormat15: "|00|10{lastLoginUserName:<26} |02{lastLogin}" mainInfoFormat15: "|00|10{lastLoginUserName:<26} |02{lastLogin}"
mainInfoFormat16: "" mainInfoFormat16: "|00|10{newUsersToday}"
mainInfoFormat17: "|00|10{freeMemoryBytes!sizeWithoutAbbr} |02{freeMemoryBytes!sizeAbbr} free |08/ |10{totalMemoryBytes!sizeWithoutAbbr} |02{totalMemoryBytes!sizeAbbr}" mainInfoFormat17: "|00|10{freeMemoryBytes!sizeWithoutAbbr} |02{freeMemoryBytes!sizeAbbr} free |08/ |10{totalMemoryBytes!sizeWithoutAbbr} |02{totalMemoryBytes!sizeAbbr}"
mainInfoFormat18: "|00|10{systemCurrentLoad} |02% |08/ |10{systemAvgLoad} |02load avg|08." mainInfoFormat18: "|00|10{systemCurrentLoad} |02% |08/ |10{systemAvgLoad} |02load avg|08."
@ -279,22 +279,30 @@
error: |00|12E error: |00|12E
fatal: |00|28F fatal: |00|28F
} }
quickLogLevelMessagePrefixes: {
trace : |00|02
debug: |00|03
info: |00|07
warn: |00|14
error: |00|12
fatal: |00|28
}
} }
0: { 0: {
mci: { mci: {
TL17: { width: 23 } TL17: { width: 23 }
TL18: { width: 23 } TL18: { width: 23 }
TL19: { width: 13 } TL19: { width: 14 }
VM1: { VM1: {
height: 5 height: 5
widht: 37 width: 36
itemFormat: "|00|11{node:<3.2} |10{userName:>13} |08> |02{action:<14.13} |14{serverName}" itemFormat: "|00|11{node:<3.2} |10{userName:>13} |08> |02{action:<14.13} |14{serverName}"
} }
VM2: { VM2: {
height: 5 height: 5
width: 73 width: 73
itemFormat: "{levelIndicator} |15{timestamp} |07{message:<51.50}" itemFormat: "|00|07{nodeId} {levelIndicator} |02{timestamp} {message:<51.50}"
} }
} }
} }

View File

@ -109,7 +109,7 @@ exports.getModule = class AbracadabraModule extends MenuModule {
name : self.config.name, name : self.config.name,
activeCount : activeDoorNodeInstances[self.config.name] activeCount : activeDoorNodeInstances[self.config.name]
}, },
'Too many active instances'); `Too many active instances of door "${self.config.name}"`);
if(_.isString(self.config.tooManyArt)) { if(_.isString(self.config.tooManyArt)) {
theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() { theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() {

View File

@ -299,6 +299,7 @@ function initialize(cb) {
[ UserLogNames.UlFileBytes, [ SysProps.FileUlTodayBytes, 'obj' ] ], [ UserLogNames.UlFileBytes, [ SysProps.FileUlTodayBytes, 'obj' ] ],
[ UserLogNames.DlFiles, [ SysProps.FileDlTodayCount, 'count' ] ], [ UserLogNames.DlFiles, [ SysProps.FileDlTodayCount, 'count' ] ],
[ UserLogNames.DlFileBytes, [ SysProps.FileDlTodayBytes, 'obj' ] ], [ UserLogNames.DlFileBytes, [ SysProps.FileDlTodayBytes, 'obj' ] ],
[ UserLogNames.NewUser, [ SysProps.NewUsersTodayCount, 'count' ] ],
]; ];
async.each(entries, (entry, nextEntry) => { async.each(entries, (entry, nextEntry) => {
@ -310,8 +311,6 @@ function initialize(cb) {
date : moment(), date : moment(),
}; };
filter.logName = logName;
StatLog.findUserLogEntries(filter, (err, stat) => { StatLog.findUserLogEntries(filter, (err, stat) => {
if (!err) { if (!err) {
if (resultType === 'obj') { if (resultType === 'obj') {

View File

@ -105,7 +105,7 @@ function addNewClient(client, clientSock) {
connInfo.family = clientSock.localFamily; connInfo.family = clientSock.localFamily;
} }
client.log.info(connInfo, 'Client connected'); client.log.info(connInfo, `Client connected (${connInfo.port}/${connInfo.serverName})`);
Events.emit( Events.emit(
Events.getSystemEvents().ClientConnected, Events.getSystemEvents().ClientConnected,

View File

@ -150,7 +150,7 @@ const ansiQuerySyncTermFontSupport = (client, cb) => {
const [_, w] = pos; const [_, w] = pos;
if (w === 1) { if (w === 1) {
// cursor didn't move // cursor didn't move
client.log.info('Client supports SyncTERM fonts or properly ignores unknown ESC sequence'); client.log.info('Enabling SyncTERM font support');
client.term.syncTermFontsEnabled = true; client.term.syncTermFontsEnabled = true;
} }
}, },

View File

@ -108,7 +108,7 @@ class ScheduledEvent {
} }
executeAction(reason, cb) { executeAction(reason, cb) {
Log.info( { eventName : this.name, action : this.action, reason : reason }, 'Executing scheduled event action...'); Log.info( { eventName : this.name, action : this.action, reason : reason }, `Executing scheduled event "${this.name}"...`);
if('method' === this.action.type) { if('method' === this.action.type) {
const modulePath = path.join(__dirname, '../', this.action.location); // enigma-bbs base + supplied location (path/file.js') const modulePath = path.join(__dirname, '../', this.action.location); // enigma-bbs base + supplied location (path/file.js')

View File

@ -10,7 +10,12 @@ function dailyMaintenanceScheduledEvent(args, cb) {
// //
// Various stats need reset daily // Various stats need reset daily
// //
[ SysProps.LoginsToday, SysProps.MessagesToday ].forEach(prop => { // :TODO: files/etc. here
const resetProps = [
SysProps.LoginsToday, SysProps.MessagesToday, SysProps.NewUsersTodayCount,
];
resetProps.forEach(prop => {
StatLog.setNonPersistentSystemStat(prop, 0); StatLog.setNonPersistentSystemStat(prop, 0);
}); });

View File

@ -299,8 +299,10 @@ const PREDEFINED_MCI_GENERATORS = {
const byteSize = StatLog.getSystemStatNum(SysProps.FileDlTodayBytes); const byteSize = StatLog.getSystemStatNum(SysProps.FileDlTodayBytes);
return formatByteSize(byteSize, true); // true=withAbbr return formatByteSize(byteSize, true); // true=withAbbr
}, },
NT : function totalNewUsersToday() { // Obv/2
return StatLog.getSystemStatNum(SysProps.NewUsersTodayCount);
},
// :TODO: NT - New users today (Obv/2)
// :TODO: TZ - Average *system* post/call ratio (iNiQUiTY) // :TODO: TZ - Average *system* post/call ratio (iNiQUiTY)
// :TODO: ?? - Total users on system // :TODO: ?? - Total users on system

View File

@ -3,6 +3,7 @@
const Events = require('./events.js'); const Events = require('./events.js');
const LogNames = require('./user_log_name.js'); const LogNames = require('./user_log_name.js');
const SysProps = require('./system_property.js');
const DefaultKeepForDays = 365; const DefaultKeepForDays = 365;
@ -26,6 +27,7 @@ module.exports = function systemEventUserLogInit(statLog) {
const detailHandler = { const detailHandler = {
[ systemEvents.NewUser ] : (e) => { [ systemEvents.NewUser ] : (e) => {
append(e, LogNames.NewUser, 1); append(e, LogNames.NewUser, 1);
statLog.incrementNonPersistentSystemStat(SysProps.NewUsersTodayCount, 1);
}, },
[ systemEvents.UserLogin ] : (e) => { [ systemEvents.UserLogin ] : (e) => {
append(e, LogNames.Login, 1); append(e, LogNames.Login, 1);

View File

@ -39,4 +39,5 @@ module.exports = {
SystemLoadStats : 'system_load_stats', // object { average, current }; non-persistent SystemLoadStats : 'system_load_stats', // object { average, current }; non-persistent
TotalUserCount : 'user_total_count', // non-persistent TotalUserCount : 'user_total_count', // non-persistent
NewUsersTodayCount : 'user_new_today_count', // non-persistent
}; };

View File

@ -86,7 +86,7 @@ function userLogin(client, username, password, options, cb) {
username : user.username, username : user.username,
userId : user.userId userId : user.userId
}, },
'Already logged in' `User ${user.username} already logged in`
); );
return cb(Errors.BadLogin( return cb(Errors.BadLogin(
@ -104,7 +104,7 @@ function userLogin(client, username, password, options, cb) {
} }
); );
client.log.info('Successful login'); client.log.info(`User ${user.username} successfully logged in`);
// User's unique session identifier is the same as the connection itself // User's unique session identifier is the same as the connection itself
user.sessionId = client.session.uniqueId; // convenience user.sessionId = client.session.uniqueId; // convenience

View File

@ -188,6 +188,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
uploadBytesToday : StatLog.getSystemStatNum(SysProps.FileUlTodayBytes), uploadBytesToday : StatLog.getSystemStatNum(SysProps.FileUlTodayBytes),
downloadsToday : StatLog.getSystemStatNum(SysProps.FileDlTodayCount), downloadsToday : StatLog.getSystemStatNum(SysProps.FileDlTodayCount),
downloadsBytesToday : StatLog.getSystemStatNum(SysProps.FileDlTodayBytes), downloadsBytesToday : StatLog.getSystemStatNum(SysProps.FileDlTodayBytes),
newUsersToday : StatLog.getSystemStatNum(SysProps.NewUsersTodayCount),
// Current // Current
currentUserName : this.client.user.username, currentUserName : this.client.user.username,
@ -265,18 +266,26 @@ exports.getModule = class WaitingForCallerModule extends MenuModule {
fatal : 'F', fatal : 'F',
}; };
const makeLevelIndicator = (level) => { const makeLevelIndicator = (level) => {
return levelIndicators[bunyan.nameFromLevel[level]] || '?'; return levelIndicators[level] || '?';
};
const quickLogLevelMessagePrefixes = this.config.quickLogLevelMessagePrefixes || {};
const prefixMssage = (message, level) => {
const prefix = quickLogLevelMessagePrefixes[level] || '';
return `${prefix}${message}`;
}; };
const logItems = records.map(rec => { const logItems = records.map(rec => {
const level = bunyan.nameFromLevel[rec.level];
return { return {
timestamp : moment(rec.time).format(quickLogTimestampFormat), timestamp : moment(rec.time).format(quickLogTimestampFormat),
level : rec.level, level : rec.level,
levelIndicator : makeLevelIndicator(rec.level), levelIndicator : makeLevelIndicator(level),
nodeId : rec.nodeId, nodeId : rec.nodeId || '*',
sessionId : rec.sessionId || '', sessionId : rec.sessionId || '',
message : rec.msg, message : prefixMssage(rec.msg, level),
}; };
}); });

View File

@ -104,6 +104,7 @@ There are many predefined MCI codes that can be used anywhere on the system (pla
| `LT` | Time of last caller | | `LT` | Time of last caller |
| `LD` | Date of last caller | | `LD` | Date of last caller |
| `TU` | Total number of users on the system | | `TU` | Total number of users on the system |
| `NT` | Total *new* users *today* |
Some additional special case codes also exist: Some additional special case codes also exist: