-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
122 lines (98 loc) · 2.54 KB
/
server.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const os = require('os')
const monitor = require('os-monitor')
const exec = require('child_process').exec
const monitorConfig = {
delay: monitor.seconds(1),
immediate: true
}
const TOTAL_CPU = os.cpus().length
const MAX_LOAD = TOTAL_CPU / 4
const history = []
const recentEvents = []
const alerts = [{
average: 0,
highUsage: false,
timestamp: new Date().getTime()
}]
app.use(express.static('public'))
app.set('views', './app/views')
app.set('view engine', 'pug')
app.get('/stress', (req, res) => {
stress()
res.sendStatus(200)
})
app.get('/unstress', (req, res) => {
unstress()
res.sendStatus(200)
})
app.get('/', (req, res) => {
res.render('index', {
totalCPUs: TOTAL_CPU,
maxLoad: MAX_LOAD
})
})
monitor.start(monitorConfig)
monitor.on('monitor', handleMonitorEvent)
io.on('connection', emitInitialState)
listen()
function listen() {
server.listen(3000, () => {
console.log('Hank is listening on port 3000')
})
}
function kill() {
server.close(() => {
console.log('Hank is no longer listening on port 3000')
})
}
function stress() {
exec('cat /dev/zero > /dev/null')
}
function unstress() {
exec('killall cat')
}
function emitInitialState() {
io.emit('initialState', {
history,
cpus: TOTAL_CPU,
alerts: alerts.filter((a, i) => i !== 0)
})
}
function handleMonitorEvent(event) {
const data = {
loadavg: event.loadavg[0],
timestamp: new Date().getTime(),
usedmemory: Math.floor((event.totalmem - event.freemem) * 100 / event.totalmem)
}
history.push(data)
recentEvents.push(data)
if (isCollectionFull(recentEvents, monitor.minutes(2))) {
const totalLoadAvg = recentEvents.reduce((a, b) => (a.loadavg || a) + b.loadavg)
const average = totalLoadAvg / recentEvents.length
checkForAlert(average, data.timestamp)
recentEvents.length = 0
}
if (isCollectionFull(history, monitor.minutes(10))) {
history.shift()
data.historyFull = true
}
io.emit('monitor', data)
}
function isCollectionFull(col, max){
return col[0].timestamp + max <= col[col.length - 1].timestamp
}
function checkForAlert(average, timestamp) {
const highUsage = average > MAX_LOAD
const lastAlert = alerts[alerts.length - 1]
const alertInfo = { average, highUsage, timestamp }
if (lastAlert.highUsage !== highUsage) {
alerts.push(alertInfo)
io.emit('alert', alertInfo)
}
return alertInfo
}
module.exports = { listen, kill, checkForAlert }