mirror of
https://gitlab.com/MrFry/mrfrys-node-server
synced 2025-04-01 20:24:18 +02:00
server stats in javascript
This commit is contained in:
parent
6424a01758
commit
0336860a9d
1 changed files with 237 additions and 49 deletions
|
@ -2,15 +2,61 @@
|
||||||
// CONFIG
|
// CONFIG
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
const maxStatLength = 15
|
const cols = process.stdout.columns
|
||||||
|
// const rows = process.stdout.rows
|
||||||
|
const maxStatLength = Math.floor(cols / 4)
|
||||||
const statNameSpacing = 5
|
const statNameSpacing = 5
|
||||||
|
const beforeRowSpace = 13
|
||||||
const coloredWords = {
|
const coloredWords = {
|
||||||
red: ['lred'],
|
red: ['lred', 'thanks'],
|
||||||
|
cyan: [
|
||||||
|
'getveteranpw',
|
||||||
|
'pwrequest',
|
||||||
|
'getpw',
|
||||||
|
'availablepws',
|
||||||
|
'login',
|
||||||
|
'logout',
|
||||||
|
],
|
||||||
|
green: [
|
||||||
|
'manual',
|
||||||
|
'todos',
|
||||||
|
'allquestions',
|
||||||
|
'subjectbrowser',
|
||||||
|
'contribute',
|
||||||
|
'feedback',
|
||||||
|
'ranklist',
|
||||||
|
'allqr',
|
||||||
|
'possibleAnswers',
|
||||||
|
],
|
||||||
|
blue: ['isadding', 'ask'],
|
||||||
|
magenta: [
|
||||||
|
'donate',
|
||||||
|
'tiszai',
|
||||||
|
'install',
|
||||||
|
'irc',
|
||||||
|
'discord',
|
||||||
|
'postfeedback',
|
||||||
|
'votetodo',
|
||||||
|
'registerscript',
|
||||||
|
'quickvote',
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
const filterFromDailyStats = [
|
||||||
|
'savedQuestions',
|
||||||
|
'sio/f',
|
||||||
|
'sound/',
|
||||||
|
'/img/',
|
||||||
|
'.php',
|
||||||
|
'favicon',
|
||||||
|
'robots.txt',
|
||||||
|
'ads.txt',
|
||||||
|
'/f/',
|
||||||
|
'.git',
|
||||||
|
]
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
const fs = require('fs')
|
const fs = require('fs') // eslint-disable-line
|
||||||
|
|
||||||
const dir = process.argv[2]
|
const dir = process.argv[2]
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
|
@ -23,19 +69,29 @@ function getDayIndex(offset) {
|
||||||
offset = 0
|
offset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
let date = new Date()
|
const date = new Date()
|
||||||
if (offset) {
|
if (offset) {
|
||||||
date.setDate(date.getDate() + offset)
|
date.setDate(date.getDate() + offset)
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
date.getFullYear() +
|
date.getFullYear() +
|
||||||
'/' +
|
'-' +
|
||||||
('0' + (date.getMonth() + 1)).slice(-2) +
|
('0' + (date.getMonth() + 1)).slice(-2) +
|
||||||
'/' +
|
'-' +
|
||||||
('0' + date.getDate()).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) {
|
function C(color) {
|
||||||
if (color !== undefined) {
|
if (color !== undefined) {
|
||||||
color = color.toLowerCase()
|
color = color.toLowerCase()
|
||||||
|
@ -73,7 +129,7 @@ function readJSON(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function tail(text, number) {
|
function tail(text, number) {
|
||||||
let splitedText = text.split('\n')
|
const splitedText = text.split('\n')
|
||||||
return splitedText.slice(Math.max(splitedText.length - number, 1)).join('\n')
|
return splitedText.slice(Math.max(splitedText.length - number, 1)).join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +140,16 @@ function head(text, number) {
|
||||||
.join('\n')
|
.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) {
|
function readFile(name) {
|
||||||
return fs.readFileSync(name, 'utf8')
|
return fs.readFileSync(name, 'utf8')
|
||||||
}
|
}
|
||||||
|
@ -96,32 +162,37 @@ function getLetterNTimes(letter, number) {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
function pCols() {
|
function pCols(cols, rowTitles, colorNames, firstRowColor, showDiff) {
|
||||||
// console.log(arguments)
|
// console.log(cols)
|
||||||
let maxLength = 0
|
let maxLength = 0
|
||||||
Object.keys(arguments).forEach((key) => {
|
Object.keys(cols).forEach((key) => {
|
||||||
if (arguments[key].length > maxLength) {
|
if (cols[key].length > maxLength) {
|
||||||
maxLength = arguments[key].length
|
maxLength = cols[key].length
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
for (let i = 0; i < maxLength; i++) {
|
for (let i = 0; i < maxLength; i++) {
|
||||||
let row = []
|
const row = []
|
||||||
Object.keys(arguments)
|
const lastItems = []
|
||||||
|
Object.keys(cols)
|
||||||
.reverse()
|
.reverse()
|
||||||
.forEach((key) => {
|
.forEach((key) => {
|
||||||
const val = arguments[key]
|
const val = cols[key]
|
||||||
if (!val[i]) {
|
if (!val[i]) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyName = val[i].name || ''
|
lastItems.push(val[i])
|
||||||
|
const keyName = val[i].name || val[i]
|
||||||
|
|
||||||
let slicedName = keyName.slice(0, maxStatLength)
|
let slicedName = keyName.slice(0, maxStatLength)
|
||||||
let toColor = Object.keys(coloredWords).reduce((acc, key) => {
|
const toColor = colorNames
|
||||||
|
? Object.keys(coloredWords).reduce((acc, key) => {
|
||||||
const colorArray = coloredWords[key]
|
const colorArray = coloredWords[key]
|
||||||
|
|
||||||
const includes = colorArray.some((colorableIdName) => {
|
const includes = colorArray.some((colorableIdName) => {
|
||||||
return keyName.includes(colorableIdName)
|
return keyName
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(colorableIdName.toLowerCase())
|
||||||
})
|
})
|
||||||
|
|
||||||
if (includes) {
|
if (includes) {
|
||||||
|
@ -130,65 +201,157 @@ function pCols() {
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
}, '')
|
}, '')
|
||||||
|
: false
|
||||||
|
|
||||||
|
const sep = (i + 1) % 5 === 0 ? '.' : ' '
|
||||||
|
|
||||||
while (slicedName.length < maxStatLength) {
|
while (slicedName.length < maxStatLength) {
|
||||||
slicedName = ' ' + slicedName
|
slicedName = slicedName + sep
|
||||||
}
|
}
|
||||||
|
|
||||||
let ammount = val[i].val ? val[i].val.toString() : 0
|
let ammount = val[i].val ? val[i].val.toString() : ''
|
||||||
while (ammount.length < 4) {
|
while (ammount.length < 4) {
|
||||||
ammount = ammount + ' '
|
ammount = ammount + ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toColor) {
|
if (toColor) {
|
||||||
row.push(C(toColor) + slicedName + ': ' + ammount + C())
|
row.push(C(toColor) + slicedName + ' ' + ammount + C())
|
||||||
} else {
|
} else {
|
||||||
row.push(slicedName + ' ' + ammount)
|
row.push(slicedName + ' ' + ammount)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(row.join(getLetterNTimes(' ', statNameSpacing)))
|
|
||||||
|
// 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`)
|
const dailyStats = readJSON(`${dir}stats/vstats`)
|
||||||
function preProcessDailyStats(obj) {
|
function preProcessDailyStats(obj) {
|
||||||
return Object.keys(obj).map((key) => {
|
const formatted = Object.keys(obj).reduce((acc, key) => {
|
||||||
return { name: key, val: obj[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(
|
pCols(
|
||||||
|
[
|
||||||
preProcessDailyStats(dailyStats[getDayIndex()]),
|
preProcessDailyStats(dailyStats[getDayIndex()]),
|
||||||
preProcessDailyStats(dailyStats[getDayIndex(-1)]),
|
preProcessDailyStats(dailyStats[getDayIndex(-1)]),
|
||||||
preProcessDailyStats(dailyStats[getDayIndex(-2)])
|
preProcessDailyStats(dailyStats[getDayIndex(-2)]),
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
printHeader('User id test solving')
|
||||||
const userIdTestSolving = readJSON(`${dir}stats/idvstats`)
|
const userIdTestSolving = readJSON(`${dir}stats/idvstats`)
|
||||||
function preProcessUIdTestSolving(obj) {
|
function preProcessUIdTestSolving(obj, minLength) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return [{ val: 0 }]
|
return '0'
|
||||||
|
}
|
||||||
|
if (minLength) {
|
||||||
|
return Object.keys(obj)
|
||||||
|
.filter((key) => {
|
||||||
|
return obj[key] > minLength
|
||||||
|
})
|
||||||
|
.length.toString()
|
||||||
|
} else {
|
||||||
|
return Object.keys(obj).length.toString()
|
||||||
}
|
}
|
||||||
return [{ val: Object.keys(obj).length }]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pCols(
|
pCols(
|
||||||
preProcessUIdTestSolving(userIdTestSolving[getDayIndex()]),
|
[
|
||||||
preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-1)]),
|
['Today', preProcessUIdTestSolving(userIdTestSolving[getDayIndex()])],
|
||||||
preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-2)])
|
['Yesterday', preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-1)])],
|
||||||
|
[
|
||||||
|
'Before yesterday',
|
||||||
|
preProcessUIdTestSolving(userIdTestSolving[getDayIndex(-2)]),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
'green'
|
||||||
)
|
)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
printHeader('User id requests')
|
||||||
const clientIdTestSolving = readJSON(`${dir}stats/uvstats`)
|
const clientIdTestSolving = readJSON(`${dir}stats/uvstats`)
|
||||||
|
|
||||||
pCols(
|
pCols(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'Today',
|
||||||
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex()]),
|
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex()]),
|
||||||
|
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex()], 2),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'Yesterday',
|
||||||
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-1)]),
|
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-1)]),
|
||||||
preProcessUIdTestSolving(clientIdTestSolving[getDayIndex(-2)])
|
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`)
|
const dailyDataCount = readFile(`${dir}stats/dailyDataCount`)
|
||||||
|
|
||||||
printLastDataCount([
|
printLastDataCount([
|
||||||
|
@ -198,12 +361,37 @@ printLastDataCount([
|
||||||
])
|
])
|
||||||
|
|
||||||
function printLastDataCount(data) {
|
function printLastDataCount(data) {
|
||||||
const res = [[], [], []]
|
const res = [['Today'], ['Yesterday'], ['Before yesterday']]
|
||||||
data.forEach((dataCount, i) => {
|
data.forEach((dataCount, i) => {
|
||||||
res[i].push({ val: dataCount.userCount })
|
res[i].push(dataCount.userCount.toString())
|
||||||
res[i].push({ val: dataCount.subjectCount })
|
res[i].push(dataCount.subjectCount.toString())
|
||||||
res[i].push({ val: dataCount.questionCount })
|
res[i].push(dataCount.questionCount.toString())
|
||||||
})
|
})
|
||||||
|
|
||||||
pCols(...res)
|
pCols(res, ['', 'Users', 'Subjects', 'Questions'], false, 'green', true)
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
printHeader('Daily script install / update check count')
|
||||||
|
const todaysLogs = readFile(`${dir}stats/vlogs/${getDayIndex()}`)
|
||||||
|
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')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue