mrfrys-node-server/scripts/serverStats.js
2021-04-28 17:38:55 +02:00

408 lines
9.5 KiB
JavaScript

// -----------------------------------------------------------------
// CONFIG
// -----------------------------------------------------------------
const cols = process.stdout.columns
// const rows = process.stdout.rows
const maxStatLength = Math.floor(cols / 4)
const statNameSpacing = 5
const beforeRowSpace = 13
const coloredWords = {
red: ['lred', 'thanks'],
cyan: [
'getveteranpw',
'pwrequest',
'getpw',
'availablepws',
'login',
'logout',
],
green: [
'manual',
'todos',
'allquestions',
'subjectbrowser',
'contribute',
'feedback',
'ranklist',
'allqr',
'possibleAnswers',
'irc',
'faq',
'/script'
],
blue: ['isadding', 'ask'],
magenta: [
'addPost',
'tiszai',
'install',
'discord',
'postfeedback',
'votetodo',
'registerscript',
'quickvote',
'comment',
'react'
],
}
const filterFromDailyStats = [
'savedQuestions',
'sio/f',
'sound/',
'/img/',
'.php',
'/wordpress/',
'/wp/',
'/wp-includes/',
'favicon',
'robots.txt',
'ads.txt',
'/f/',
'.git',
'apple-touch-icon',
'/.env'
]
// -----------------------------------------------------------------
const fs = require('fs') // eslint-disable-line
const dir = process.argv[2]
if (!dir) {
console.log('No params')
process.exit()
}
function getDayIndex(offset) {
if (!offset) {
offset = 0
}
const date = new Date()
if (offset) {
date.setDate(date.getDate() + offset)
}
return (
date.getFullYear() +
'-' +
('0' + (date.getMonth() + 1)).slice(-2) +
'-' +
('0' + date.getDate()).slice(-2)
)
}
function hr(char) {
console.log(C('blue') + getLetterNTimes(char || '=', cols) + C())
}
function printHeader(text) {
hr()
console.log(C('green') + text + C())
hr()
}
function C(color) {
if (color !== undefined) {
color = color.toLowerCase()
}
if (color === 'redbg') {
return '\x1b[41m'
}
if (color === 'bluebg') {
return '\x1b[44m'
}
if (color === 'green') {
return '\x1b[32m'
}
if (color === 'red') {
return '\x1b[31m'
}
if (color === 'yellow') {
return '\x1b[33m'
}
if (color === 'blue') {
return '\x1b[34m'
}
if (color === 'magenta') {
return '\x1b[35m'
}
if (color === 'cyan') {
return '\x1b[36m'
}
return '\x1b[0m'
}
function readJSON(name) {
return JSON.parse(fs.readFileSync(name, 'utf8'))
}
function tail(text, number) {
const splitedText = text.split('\n')
return splitedText.slice(Math.max(splitedText.length - number, 1)).join('\n')
}
function head(text, number) {
return text
.split('\n')
.slice(0, number)
.join('\n')
}
function countLinesMatching(text, toMatch) {
let count = 0
text.split('\n').forEach((line) => {
if (line.includes(toMatch.toLowerCase())) {
count++
}
})
return count
}
function readFile(name) {
if (fs.existsSync(name)) {
return fs.readFileSync(name, 'utf8')
}
}
function getLetterNTimes(letter, number) {
let res = ''
while (res.length < number) {
res += letter
}
return res
}
function pCols(cols, rowTitles, colorNames, firstRowColor, showDiff) {
// console.log(cols)
let maxLength = 0
Object.keys(cols).forEach((key) => {
if (cols[key].length > maxLength) {
maxLength = cols[key].length
}
})
for (let i = 0; i < maxLength; i++) {
const row = []
const lastItems = []
Object.keys(cols)
.reverse()
.forEach((key) => {
const val = cols[key]
if (!val[i]) {
return
}
lastItems.push(val[i])
const keyName = val[i].name || val[i]
let slicedName = keyName.slice(0, maxStatLength)
const toColor = colorNames
? Object.keys(coloredWords).reduce((acc, key) => {
const colorArray = coloredWords[key]
const includes = colorArray.some((colorableIdName) => {
return keyName
.toLowerCase()
.includes(colorableIdName.toLowerCase())
})
if (includes) {
return key
}
return acc
}, '')
: false
const sep = (i + 1) % 5 === 0 ? '.' : ' '
while (slicedName.length < maxStatLength) {
slicedName = slicedName + sep
}
let ammount = val[i].val ? val[i].val.toString() : ''
while (ammount.length < 4) {
ammount = ammount + ' '
}
if (toColor) {
row.push(C(toColor) + slicedName + ' ' + ammount + C())
} else {
row.push(slicedName + ' ' + ammount)
}
})
// ROW TITLE ---------------------------------------------------
let currRowTitle =
rowTitles && rowTitles[i]
? rowTitles[i]
: getLetterNTimes(' ', beforeRowSpace)
while (currRowTitle.length < beforeRowSpace) {
currRowTitle = currRowTitle + ' '
}
currRowTitle = C('blue') + currRowTitle + C()
// COLORING ----------------------------------------------------
let res = ''
if (firstRowColor && i === 0) {
res =
currRowTitle +
C('green') +
row.join(getLetterNTimes(' ', statNameSpacing)) +
C()
} else {
res = currRowTitle + row.join(getLetterNTimes(' ', statNameSpacing))
}
// SHOW DIFF ---------------------------------------------------
if (showDiff && i !== 0) {
let diff =
lastItems[lastItems.length - 1] - lastItems[lastItems.length - 2]
if (diff > 0) {
diff = '+' + diff.toString()
}
res += C('blue') + diff + C()
}
console.log(res)
}
}
// ------------------------------------------------------------------------------
printHeader('Daily stats')
const dailyStats = readJSON(`${dir}stats/vstats`)
function preProcessDailyStats(obj) {
const formatted = Object.keys(obj).reduce((acc, key) => {
const includes = filterFromDailyStats.some((keyword) => {
return key.toLowerCase().includes(keyword.toLowerCase())
})
if (!includes) {
acc.push({ name: key, val: obj[key] })
}
return acc
}, [])
return formatted.sort((a, b) => {
if (a.name > b.name) {
return 1
} else if (a.name < b.name) {
return -1
} else {
return 0
}
})
}
pCols(
[
preProcessDailyStats(dailyStats[getDayIndex()]),
preProcessDailyStats(dailyStats[getDayIndex(-1)]),
preProcessDailyStats(dailyStats[getDayIndex(-2)]),
],
null,
true
)
// ------------------------------------------------------------------------------
printHeader('User id test solving')
const userIdTestSolving = readJSON(`${dir}stats/idvstats`)
function preProcessUIdTestSolving(obj, minLength) {
if (!obj) {
return '0'
}
if (minLength) {
return Object.keys(obj)
.filter((key) => {
return obj[key] > minLength
})
.length.toString()
} else {
return Object.keys(obj).length.toString()
}
}
pCols(
[
['Today', preProcessUIdTestSolving(userIdTestSolving[getDayIndex()])],
['Yesterday', preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-1)])],
[
'Before yesterday',
preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-2)]),
],
],
null,
false,
'green'
)
// ------------------------------------------------------------------------------
printHeader('User id requests')
const clientIdTestSolving = readJSON(`${dir}stats/uvstats`)
pCols(
[
[
'Today',
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex()]),
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex()], 2),
],
[
'Yesterday',
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-1)]),
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-1)], 2),
],
[
'Before Yesterday',
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-2)]),
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-2)], 2),
],
],
['', 'All', 'More than 2'],
false,
'green'
)
// ------------------------------------------------------------------------------
printHeader('Daily data count')
const dailyDataCount = readFile(`${dir}stats/dailyDataCount`)
printLastDataCount([
JSON.parse(head(tail(dailyDataCount, 1), 1)),
JSON.parse(head(tail(dailyDataCount, 2), 1)),
JSON.parse(head(tail(dailyDataCount, 3), 1)),
])
function printLastDataCount(data) {
const res = [['Today'], ['Yesterday'], ['Before yesterday']]
data.forEach((dataCount, i) => {
res[i].push(dataCount.userCount.toString())
res[i].push(dataCount.subjectCount.toString())
res[i].push(dataCount.questionCount.toString())
})
pCols(res, ['', 'Users', 'Subjects', 'Questions'], false, 'green', true)
}
// ------------------------------------------------------------------------------
printHeader('Daily script install / update check count')
const todaysLogs = readFile(`${dir}stats/vlogs/log`)
const yesterdaysLogs = readFile(`${dir}stats/vlogs/${getDayIndex(-1)}`) || ''
const beforeYesterdaysLogs = readFile(`${dir}stats/vlogs/${getDayIndex(-2)}`) || ''
const installs = [
[
'Today',
countLinesMatching(todaysLogs, '?install').toString(),
countLinesMatching(todaysLogs, '?up').toString(),
],
[
'Yesterday',
countLinesMatching(yesterdaysLogs, '?install').toString(),
countLinesMatching(yesterdaysLogs, '?up').toString(),
],
[
'Before yesterday',
countLinesMatching(beforeYesterdaysLogs, '?install').toString(),
countLinesMatching(beforeYesterdaysLogs, '?up').toString(),
],
]
pCols(installs, ['', 'Installs', 'Updates'], false, 'green')