/
stats.js
97 lines (84 loc) · 3.88 KB
/
stats.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
'use strict'
var _ = require('lodash')
const debug = require('debug')
function Stats () {
this.latestTimestamp = 0
this.sockets()
this.clearAPIStats(this)
}
Stats.prototype.sockets = function () {
if (_.isNil(global.panel)) return setTimeout(() => this.sockets(), 10)
global.panel.socketListening(this, 'getLatestStats', this.getLatestStats)
global.panel.socketListening(this, 'getApiStats', this.getApiStats)
}
Stats.prototype.clearAPIStats = async function (self) {
const d = debug('stats:clearAPIStats')
let stats = await global.db.engine.find('api.stats')
// remove data older than 24h
stats = _.filter(stats, (o) => _.now() - o.timestamp >= 1000 * 60 * 60 * 24)
d('Stats to delete: %j', stats)
for (let s of stats) await global.db.engine.remove('api.stats', { _id: s._id.toString() })
setTimeout(() => self.clearAPIStats(self), 1000 * 60 * 60)
}
Stats.prototype.save = async function (data) {
if (data.timestamp - this.latestTimestamp >= 30000) {
let stats = await global.db.engine.findOne('stats', {'whenOnline': data.whenOnline})
// pseudo avg value through stream
data.currentViewers = Math.round((data.currentViewers + _.get(stats, 'currentViewers', data.currentViewers)) / 2)
data.currentHosts = Math.round((data.currentHosts + _.get(stats, 'currentHosts', data.currentHosts)) / 2)
global.db.engine.update('stats', {'whenOnline': data.whenOnline}, data)
this.latestTimestamp = data.timestamp
}
}
Stats.prototype.getLatestStats = async function (self, socket) {
let statsFromDb = await global.db.engine.find('stats')
let stats = {
currentViewers: 0,
currentSubscribers: 0,
currentBits: 0,
currentTips: 0,
chatMessages: 0,
currentFollowers: 0,
currentViews: 0,
maxViewers: 0,
currentHosts: 0,
newChatters: 0
}
if (statsFromDb.length > 1) {
// get second stream (first is current stream)
statsFromDb = _.orderBy(statsFromDb, 'timestamp', 'desc')
statsFromDb.shift() // remove first element
let i = 0
for (let stat of statsFromDb) {
stats.currentViewers += parseFloat(_.isNil(stat.currentViewers) ? 0 : stat.currentViewers)
stats.currentBits += parseFloat(_.isNil(stat.currentBits) ? 0 : stat.currentBits)
stats.currentTips += parseFloat(_.isNil(stat.currentTips) ? 0 : stat.currentTips)
stats.chatMessages += parseFloat(_.isNil(stat.chatMessages) ? 0 : stat.chatMessages)
stats.maxViewers += parseFloat(_.isNil(stat.maxViewers) ? 0 : stat.maxViewers)
stats.newChatters += parseFloat(_.isNil(stat.newChatters) ? 0 : stat.newChatters)
stats.currentHosts += parseFloat(_.isNil(stat.currentHosts) ? 0 : stat.currentHosts)
if (i === 0) {
// get only latest
stats.currentFollowers = stat.currentFollowers
stats.currentViews = stat.currentViews
stats.currentSubscribers = stat.currentSubscribers
}
i++
}
stats.currentViewers = parseFloat(stats.currentViewers / statsFromDb.length).toFixed(0)
stats.currentBits = parseFloat(stats.currentBits / statsFromDb.length).toFixed(0)
stats.currentTips = parseFloat(stats.currentTips / statsFromDb.length).toFixed(0)
stats.chatMessages = parseFloat(stats.chatMessages / statsFromDb.length).toFixed(0)
stats.maxViewers = parseFloat(stats.maxViewers / statsFromDb.length).toFixed(0)
stats.newChatters = parseFloat(stats.newChatters / statsFromDb.length).toFixed(0)
stats.currentHosts = parseFloat(stats.currentHosts / statsFromDb.length).toFixed(0)
} else stats = {}
socket.emit('latestStats', stats)
}
Stats.prototype.getApiStats = async function (self, socket, options) {
const [from, to] = [_.get(options, 'from', _.now() - 1000 * 60 * 60), _.get(options, 'to', _.now())]
let stats = await global.db.engine.find('api.stats')
// return hour of data
socket.emit('api.stats', _.filter(stats, (o) => from < o.timestamp && to >= o.timestamp))
}
module.exports = Stats