-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
136 lines (117 loc) · 3.5 KB
/
index.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const os = require('os')
const p = require('prettier-bytes')
const eld = require('event-loop-delay')
const hrtime = require('./hrtime')
const isBare = !!global.Bare
const resourceUsage = isBare ? os.resourceUsage : global.process.resourceUsage
const memoryUsage = isBare ? os.memoryUsage : global.process.memoryUsage
const pid = isBare ? global.Bare.pid : global.process.pid
const argv = isBare ? global.Bare.argv : global.process.argv
module.exports = top
function top (opts) {
if (!opts) opts = {}
const tick = opts.interval || 1000
const started = Date.now()
const interval = setInterval(perSecond, tick)
const win = [{ time: hrtime(), cpu: cpuUsage(null), delay: 0 }, null, null, null]
const loopSampler = eld()
let sec = 1
interval.unref()
return {
pid,
command: argv.join(' '),
started,
runtime () {
return Date.now() - started
},
delay () {
const btm = oldest()
const timeDelta = hrtime(win[btm].time)
const ms = Math.max(1, timeDelta[0] * 1e3 + Math.floor(timeDelta[1] / 1e6))
return Math.floor((loopSampler.delay - win[btm].delay) / (ms / tick))
},
cpu () {
const btm = oldest()
const cpuDelta = cpuUsage(win[btm].cpu)
const timeDelta = hrtime(win[btm].time)
const us = timeDelta[0] * 1e6 + timeDelta[1] / 1e3
return {
time: us,
percent: (cpuDelta.system + cpuDelta.user) / us,
system: cpuDelta.system,
user: cpuDelta.user
}
},
memory () {
const mem = memoryUsage()
const total = os.totalmem()
return {
percent: (mem.rss || 0) / total,
rss: mem.rss || 0,
total,
heapPercent: mem.heapUsed / mem.heapTotal,
heapUsed: mem.heapUsed,
heapTotal: mem.heapTotal,
external: mem.external
}
},
loadavg () {
return os.loadavg()
},
destroy () {
clearInterval(interval)
},
toString () {
const mem = this.memory()
return `cpu: ${pct(this.cpu().percent)} | rss: ${p(mem.rss)} (${pct(mem.percent)}) | heap: ${p(mem.heapUsed)} / ${p(mem.heapTotal)} (${pct(mem.heapPercent)}) | ext: ${p(mem.external)} | delay: ${this.delay()} ms | ${time(this.runtime())} | loadavg: ${os.loadavg().map(fixed2).join(', ')}`
},
toJSON () {
const memory = this.memory()
return {
timestamp: new Date(),
cpu: Number(this.cpu().percent.toFixed(4)),
memory: { ...memory, percent: Number(memory.percent.toFixed(4)), heapPercent: Number(memory.heapPercent.toFixed(4)) },
delay: this.delay(),
runtime: this.runtime()
}
}
}
function oldest () {
let btm = (sec - 4) & 3
while (!win[btm]) btm = (btm + 1) & 3
return btm
}
function perSecond () {
const ptr = sec++ & 3
win[ptr] = { time: hrtime(), cpu: cpuUsage(null), delay: loopSampler.delay }
}
}
function pct (n) {
return (100 * n).toFixed(1) + '%'
}
function fixed2 (n) {
return n.toFixed(2)
}
function time (n) {
let secs = Math.floor(n / 1000)
const hours = Math.floor(secs / 3600)
secs -= hours * 3600
const mins = Math.floor(secs / 60)
secs -= mins * 60
return pad(hours) + ':' + pad(mins) + ':' + pad(secs)
}
function pad (n) {
return n < 10 ? '0' + n : '' + n
}
function cpuUsage (previous) {
const current = resourceUsage()
const result = {
user: current.userCPUTime,
system: current.systemCPUTime
}
if (!previous) return result
return {
user: result.user - previous.user,
system: result.system - previous.system
}
}