208 lines
5.7 KiB
JavaScript
208 lines
5.7 KiB
JavaScript
(function () {
|
|
let app = document.getElementById('app')
|
|
|
|
function httpGet (url) {
|
|
let request = new XMLHttpRequest()
|
|
return new Promise(function (resolve, reject) {
|
|
request.onreadystatechange = function () {
|
|
if (this.readyState === 4) {
|
|
if (this.status === 200) {
|
|
resolve(this.responseText)
|
|
} else if (this.response == null && this.status === 0) {
|
|
reject(new Error('The status server appears to be offile.'))
|
|
}
|
|
}
|
|
}
|
|
|
|
request.open("GET", url, true)
|
|
request.send(null)
|
|
})
|
|
}
|
|
|
|
function bytesToSize (bytes) {
|
|
let sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
|
|
if (bytes == 0) return '0 Byte'
|
|
let i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)))
|
|
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]
|
|
}
|
|
|
|
// Add a zero in front of single-digit numbers
|
|
function zf (v) {
|
|
if (v > 9) {
|
|
return '' + v
|
|
} else {
|
|
return '0' + v
|
|
}
|
|
}
|
|
|
|
// Convert seconds into years days hours minutes seconds(.milliseconds)
|
|
function readableTime (timems, ignoreMs) {
|
|
var time = timems | 0
|
|
var ms = ignoreMs ? '' : '.' + zf((timems * 100) % 100 | 0)
|
|
if (time < 60) return zf(time) + ms + 's'
|
|
else if (time < 3600) return zf(time / 60 | 0) + 'm ' + zf(time % 60) + ms + 's'
|
|
else if (time < 86400) return zf(time / 3600 | 0) + 'h ' + zf((time % 3600) / 60 | 0) + 'm ' + zf((time % 3600) % 60) + ms + 's'
|
|
else if (time < 31536000) return (time / 86400 | 0) + 'd ' + zf((time % 86400) / 3600 | 0) + 'h ' + zf((time % 3600) / 60 | 0) + 'm ' + zf((time % 3600) % 60) + 's'
|
|
else return (time / 31536000 | 0) + 'y ' + zf((time % 31536000) / 86400 | 0) + 'd ' + zf((time % 86400) / 3600 | 0) + 'h ' + zf((time % 3600) / 60 | 0) + 'm ' + zf((time % 3600) % 60) + 's'
|
|
}
|
|
|
|
function e (element, content, cl) {
|
|
let el = document.createElement(element)
|
|
if (cl) el.className = cl
|
|
el.innerHTML = content
|
|
return el.outerHTML
|
|
}
|
|
|
|
function box (type, content) {
|
|
return e('div', content, type)
|
|
}
|
|
|
|
function bar (metric, value, percentage, low, high) {
|
|
return box('bar-outer',
|
|
e('span', metric, 'bar-name') +
|
|
box('bar-inner',
|
|
'<div class="bar-progress" style="width: ' + percentage + '%;"></div>'
|
|
) +
|
|
box('bar-stats',
|
|
e('span', low, 'stat-low') +
|
|
e('span', value, 'stat-now') +
|
|
e('span', high, 'stat-high')
|
|
)
|
|
)
|
|
}
|
|
|
|
function renderPage (data) {
|
|
let title = 'Welcome to ' + data.hostname + ' on ' + data.kernel
|
|
document.title = title
|
|
|
|
app.innerHTML = ''
|
|
app.innerHTML += box('infobox-row',
|
|
box('general infobox',
|
|
box('header',
|
|
e('h2', 'General')
|
|
) +
|
|
box('content',
|
|
box('row',
|
|
e('label', 'Hostname') +
|
|
e('span', data.hostname)
|
|
) + box('row',
|
|
e('label', 'Uptime') +
|
|
e('span', readableTime(data.uptime))
|
|
) + box('row',
|
|
e('label', 'Kernel version') +
|
|
e('span', data.kernel)
|
|
) + box('row',
|
|
e('label', 'Processes') +
|
|
e('span', data.cpu.processes)
|
|
)
|
|
)
|
|
) +
|
|
|
|
// CPU usage
|
|
box('cpu infobox',
|
|
box('header',
|
|
e('h2', 'CPU')
|
|
) +
|
|
box('content',
|
|
box('row',
|
|
e('label', 'Model') +
|
|
e('span', data.cpu.model)
|
|
) +
|
|
box('row',
|
|
e('label', 'Num. cores') +
|
|
e('span', data.cpu.count)
|
|
) +
|
|
box('row',
|
|
e('label', 'Usage') +
|
|
e('span', Math.floor(data.cpu.usage) + ' %')
|
|
) + box('row',
|
|
e('label', 'Load averages') +
|
|
e('span', data.cpu.loadAverage[0].toFixed(2) + ', ' + data.cpu.loadAverage[1].toFixed(2) + ', ' + data.cpu.loadAverage[2].toFixed(2))
|
|
)
|
|
)
|
|
))
|
|
|
|
// Memory usage
|
|
let memuse = (data.memory.total - data.memory.free)
|
|
app.innerHTML += box('memory infobox',
|
|
box('header',
|
|
e('h2', 'Memory')
|
|
) +
|
|
box('content',
|
|
bar('Memory usage', bytesToSize(memuse), memuse * 100 / data.memory.total, '0 Bytes', bytesToSize(data.memory.total))
|
|
)
|
|
)
|
|
|
|
// Network interfaces
|
|
let interfaces = ''
|
|
for (let int in data.network) {
|
|
if (int === 'lo') continue
|
|
let iface = data.network[int]
|
|
let ips = []
|
|
for (let ip in iface.addresses) {
|
|
ips.push(e('span', iface.addresses[ip], 'ip-addr'))
|
|
}
|
|
interfaces += box('interface',
|
|
e('h3', int) +
|
|
ips.join('') +
|
|
e('h4', 'Bandwidth', 'sec-info') +
|
|
box('row',
|
|
e('label', 'Download') +
|
|
e('span', bytesToSize(iface.download))
|
|
) + box('row',
|
|
e('label', 'Upload') +
|
|
e('span', bytesToSize(iface.upload))
|
|
)
|
|
)
|
|
}
|
|
|
|
// Disks
|
|
let disks = ''
|
|
for (let mount in data.disk) {
|
|
let disk = data.disk[mount]
|
|
disks += box('disk',
|
|
e('h3', 'Mounted on ' + mount) +
|
|
box('row',
|
|
e('label', 'Free space') +
|
|
e('span', disk.freeGb + ' GB')
|
|
) +
|
|
bar('Disk usage', disk.usedGb + ' GB', disk.usedPercentage, '0 GB', disk.totalGb + ' GB')
|
|
)
|
|
}
|
|
|
|
app.innerHTML += box('infobox-row',
|
|
box('network infobox',
|
|
box('header',
|
|
e('h2', 'Network Interfaces')
|
|
) +
|
|
box('content',
|
|
box('interfaces', interfaces)
|
|
)
|
|
)+
|
|
|
|
box('disk infobox',
|
|
box('header',
|
|
e('h2', 'Disk Drives')
|
|
) +
|
|
box('content',
|
|
box('disks', disks)
|
|
)
|
|
)
|
|
)
|
|
}
|
|
|
|
function update () {
|
|
httpGet('/status').then(function (data) {
|
|
try {
|
|
renderPage(JSON.parse(data))
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
}, function (e) {
|
|
console.error(e)
|
|
})
|
|
}
|
|
|
|
update()
|
|
})()
|