From 16d3c457828a60bc90e6c6034eb07d3e5c10e41a Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 22 Feb 2021 13:23:20 -0500 Subject: [PATCH] feat: report login statistics from analytics data, instead of its own zset --- src/controllers/admin/dashboard.js | 33 ++++++++++++++++++++++++++++-- src/user/auth.js | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/controllers/admin/dashboard.js b/src/controllers/admin/dashboard.js index 57ac7aca97..0b8cb89d1c 100644 --- a/src/controllers/admin/dashboard.js +++ b/src/controllers/admin/dashboard.js @@ -115,9 +115,9 @@ async function getStats() { return cachedStats; } - const results = await Promise.all([ + let results = await Promise.all([ getStatsForSet('ip:recent', 'uniqueIPCount'), - getStatsForSet('sessions:recent', 'loginCount'), + getStatsFromAnalytics('logins', 'loginCount'), getStatsForSet('users:joindate', 'userCount'), getStatsForSet('posts:pid', 'postCount'), getStatsForSet('topics:tid', 'topicCount'), @@ -127,6 +127,12 @@ async function getStats() { results[2].name = '[[admin/dashboard:new-users]]'; results[3].name = '[[admin/dashboard:posts]]'; results[4].name = '[[admin/dashboard:topics]]'; + + ({ results } = await plugins.hooks.fire('filter:admin.getStats', { + results, + helpers: { getStatsForSet, getStatsFromAnalytics }, + })); + cache.set('admin:stats', results, 600000); return results; } @@ -149,6 +155,29 @@ async function getStatsForSet(set, field) { alltime: getGlobalField(field), }); + return calculateDeltas(results); +} + +async function getStatsFromAnalytics(set, field) { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + const data = await analytics.getDailyStatsForSet(`analytics:${set}`, today, 60); + const sum = arr => arr.reduce((memo, cur) => memo + cur, 0); + const results = { + yesterday: sum(data.slice(-2)), + today: data.slice(-1), + lastweek: sum(data.slice(-14)), + thisweek: sum(data.slice(-7)), + lastmonth: sum(data.slice(0)), // entire set + thismonth: sum(data.slice(-30)), + alltime: await getGlobalField(field), + }; + + return calculateDeltas(results); +} + +function calculateDeltas(results) { function textClass(num) { if (num > 0) { return 'text-success'; diff --git a/src/user/auth.js b/src/user/auth.js index d8cf7d531a..abc972ea24 100644 --- a/src/user/auth.js +++ b/src/user/auth.js @@ -111,7 +111,7 @@ module.exports = function (User) { return; } await cleanExpiredSessions(uid); - await db.sortedSetsAdd([`uid:${uid}:sessions`, 'sessions:recent'], Date.now(), sessionId); + await db.sortedSetAdd([`uid:${uid}:sessions`], Date.now(), sessionId); await revokeSessionsAboveThreshold(uid, meta.config.maxUserSessions); };