From 9e5b3369a50ddf9545e0c2020529f84df81c9507 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Sat, 7 May 2022 10:48:40 -0600 Subject: [PATCH] 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 --- art/themes/luciano_blocktronics/theme.hjson | 16 ++++++++++++---- core/abracadabra.js | 2 +- core/bbs.js | 11 +++++------ core/client_connections.js | 2 +- core/connect.js | 2 +- core/event_scheduler.js | 2 +- core/misc_scheduled_events.js | 7 ++++++- core/predefined_mci.js | 4 +++- core/sys_event_user_log.js | 2 ++ core/system_property.js | 1 + core/user_login.js | 4 ++-- core/wfc.js | 17 +++++++++++++---- docs/_docs/art/mci.md | 1 + 13 files changed, 49 insertions(+), 22 deletions(-) diff --git a/art/themes/luciano_blocktronics/theme.hjson b/art/themes/luciano_blocktronics/theme.hjson index 9a7d208c..d89b4951 100644 --- a/art/themes/luciano_blocktronics/theme.hjson +++ b/art/themes/luciano_blocktronics/theme.hjson @@ -259,7 +259,7 @@ 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}" mainInfoFormat18: "|00|10{systemCurrentLoad} |02% |08/ |10{systemAvgLoad} |02load avg|08." @@ -279,22 +279,30 @@ error: |00|12E fatal: |00|28F } + quickLogLevelMessagePrefixes: { + trace : |00|02 + debug: |00|03 + info: |00|07 + warn: |00|14 + error: |00|12 + fatal: |00|28 + } } 0: { mci: { TL17: { width: 23 } TL18: { width: 23 } - TL19: { width: 13 } + TL19: { width: 14 } VM1: { height: 5 - widht: 37 + width: 36 itemFormat: "|00|11{node:<3.2} |10{userName:>13} |08> |02{action:<14.13} |14{serverName}" } VM2: { height: 5 width: 73 - itemFormat: "{levelIndicator} |15{timestamp} |07{message:<51.50}" + itemFormat: "|00|07{nodeId} {levelIndicator} |02{timestamp} {message:<51.50}" } } } diff --git a/core/abracadabra.js b/core/abracadabra.js index a8a72b1d..9dc4b79d 100644 --- a/core/abracadabra.js +++ b/core/abracadabra.js @@ -109,7 +109,7 @@ exports.getModule = class AbracadabraModule extends MenuModule { name : 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)) { theme.displayThemeArt( { client : self.client, name : self.config.tooManyArt }, function displayed() { diff --git a/core/bbs.js b/core/bbs.js index 8d5fc2f1..e1273130 100644 --- a/core/bbs.js +++ b/core/bbs.js @@ -295,10 +295,11 @@ function initialize(cb) { const StatLog = require('./stat_log'); const entries = [ - [ UserLogNames.UlFiles, [ SysProps.FileUlTodayCount, 'count' ] ], - [ UserLogNames.UlFileBytes, [ SysProps.FileUlTodayBytes, 'obj' ] ], - [ UserLogNames.DlFiles, [ SysProps.FileDlTodayCount, 'count' ] ], - [ UserLogNames.DlFileBytes, [ SysProps.FileDlTodayBytes, 'obj' ] ], + [ UserLogNames.UlFiles, [ SysProps.FileUlTodayCount, 'count' ] ], + [ UserLogNames.UlFileBytes, [ SysProps.FileUlTodayBytes, 'obj' ] ], + [ UserLogNames.DlFiles, [ SysProps.FileDlTodayCount, 'count' ] ], + [ UserLogNames.DlFileBytes, [ SysProps.FileDlTodayBytes, 'obj' ] ], + [ UserLogNames.NewUser, [ SysProps.NewUsersTodayCount, 'count' ] ], ]; async.each(entries, (entry, nextEntry) => { @@ -310,8 +311,6 @@ function initialize(cb) { date : moment(), }; - filter.logName = logName; - StatLog.findUserLogEntries(filter, (err, stat) => { if (!err) { if (resultType === 'obj') { diff --git a/core/client_connections.js b/core/client_connections.js index 393446b3..ca5061e6 100644 --- a/core/client_connections.js +++ b/core/client_connections.js @@ -105,7 +105,7 @@ function addNewClient(client, clientSock) { connInfo.family = clientSock.localFamily; } - client.log.info(connInfo, 'Client connected'); + client.log.info(connInfo, `Client connected (${connInfo.port}/${connInfo.serverName})`); Events.emit( Events.getSystemEvents().ClientConnected, diff --git a/core/connect.js b/core/connect.js index 7301e098..5aba7795 100644 --- a/core/connect.js +++ b/core/connect.js @@ -150,7 +150,7 @@ const ansiQuerySyncTermFontSupport = (client, cb) => { const [_, w] = pos; if (w === 1) { // 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; } }, diff --git a/core/event_scheduler.js b/core/event_scheduler.js index 4a464cd8..8ea9bcde 100644 --- a/core/event_scheduler.js +++ b/core/event_scheduler.js @@ -108,7 +108,7 @@ class ScheduledEvent { } 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) { const modulePath = path.join(__dirname, '../', this.action.location); // enigma-bbs base + supplied location (path/file.js') diff --git a/core/misc_scheduled_events.js b/core/misc_scheduled_events.js index 1650b697..fbcd84ce 100644 --- a/core/misc_scheduled_events.js +++ b/core/misc_scheduled_events.js @@ -10,7 +10,12 @@ function dailyMaintenanceScheduledEvent(args, cb) { // // 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); }); diff --git a/core/predefined_mci.js b/core/predefined_mci.js index 364a1e1c..c43cef43 100644 --- a/core/predefined_mci.js +++ b/core/predefined_mci.js @@ -299,8 +299,10 @@ const PREDEFINED_MCI_GENERATORS = { const byteSize = StatLog.getSystemStatNum(SysProps.FileDlTodayBytes); 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: ?? - Total users on system diff --git a/core/sys_event_user_log.js b/core/sys_event_user_log.js index 63ae0e55..57f17659 100644 --- a/core/sys_event_user_log.js +++ b/core/sys_event_user_log.js @@ -3,6 +3,7 @@ const Events = require('./events.js'); const LogNames = require('./user_log_name.js'); +const SysProps = require('./system_property.js'); const DefaultKeepForDays = 365; @@ -26,6 +27,7 @@ module.exports = function systemEventUserLogInit(statLog) { const detailHandler = { [ systemEvents.NewUser ] : (e) => { append(e, LogNames.NewUser, 1); + statLog.incrementNonPersistentSystemStat(SysProps.NewUsersTodayCount, 1); }, [ systemEvents.UserLogin ] : (e) => { append(e, LogNames.Login, 1); diff --git a/core/system_property.js b/core/system_property.js index f39b3a27..bbd8e058 100644 --- a/core/system_property.js +++ b/core/system_property.js @@ -39,4 +39,5 @@ module.exports = { SystemLoadStats : 'system_load_stats', // object { average, current }; non-persistent TotalUserCount : 'user_total_count', // non-persistent + NewUsersTodayCount : 'user_new_today_count', // non-persistent }; diff --git a/core/user_login.js b/core/user_login.js index 8c9e41b8..2f8c502d 100644 --- a/core/user_login.js +++ b/core/user_login.js @@ -86,7 +86,7 @@ function userLogin(client, username, password, options, cb) { username : user.username, userId : user.userId }, - 'Already logged in' + `User ${user.username} already logged in` ); 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.sessionId = client.session.uniqueId; // convenience diff --git a/core/wfc.js b/core/wfc.js index 66bf291f..6e0c6c94 100644 --- a/core/wfc.js +++ b/core/wfc.js @@ -188,6 +188,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { uploadBytesToday : StatLog.getSystemStatNum(SysProps.FileUlTodayBytes), downloadsToday : StatLog.getSystemStatNum(SysProps.FileDlTodayCount), downloadsBytesToday : StatLog.getSystemStatNum(SysProps.FileDlTodayBytes), + newUsersToday : StatLog.getSystemStatNum(SysProps.NewUsersTodayCount), // Current currentUserName : this.client.user.username, @@ -265,18 +266,26 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { fatal : 'F', }; + 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 level = bunyan.nameFromLevel[rec.level]; return { timestamp : moment(rec.time).format(quickLogTimestampFormat), level : rec.level, - levelIndicator : makeLevelIndicator(rec.level), - nodeId : rec.nodeId, + levelIndicator : makeLevelIndicator(level), + nodeId : rec.nodeId || '*', sessionId : rec.sessionId || '', - message : rec.msg, + message : prefixMssage(rec.msg, level), }; }); diff --git a/docs/_docs/art/mci.md b/docs/_docs/art/mci.md index 05fa9dd5..b1eb3395 100644 --- a/docs/_docs/art/mci.md +++ b/docs/_docs/art/mci.md @@ -104,6 +104,7 @@ There are many predefined MCI codes that can be used anywhere on the system (pla | `LT` | Time of last caller | | `LD` | Date of last caller | | `TU` | Total number of users on the system | +| `NT` | Total *new* users *today* | Some additional special case codes also exist: