412 lines
12 KiB
HTML
412 lines
12 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<title>nytsoi.net system monitor</title>
|
|||
|
<meta charset="utf-8" />
|
|||
|
|
|||
|
<style type="text/css">
|
|||
|
html, body {
|
|||
|
background-color: #123456;
|
|||
|
margin: 0px;
|
|||
|
padding: 0px;
|
|||
|
}
|
|||
|
|
|||
|
#container {
|
|||
|
color: #abcdef;
|
|||
|
font-size: 14px;
|
|||
|
font-family: monospace;
|
|||
|
line-height: 1;
|
|||
|
padding: 0px 10px;
|
|||
|
margin: 0px auto;
|
|||
|
width: 1100px;
|
|||
|
}
|
|||
|
|
|||
|
#container h1, h2, h3, h4, h5, h6 {
|
|||
|
padding: 10px;
|
|||
|
margin: 0px;
|
|||
|
font-weight: normal;
|
|||
|
text-align: left;
|
|||
|
}
|
|||
|
|
|||
|
#container h1 {
|
|||
|
font-size: 16px;
|
|||
|
float: left;
|
|||
|
}
|
|||
|
|
|||
|
#container h2, h3, h4, h5, h6 {
|
|||
|
font-size: 14px;
|
|||
|
}
|
|||
|
|
|||
|
#container, #container>div {
|
|||
|
float: left;
|
|||
|
}
|
|||
|
|
|||
|
#cpu {
|
|||
|
/*width: 48%;*/
|
|||
|
clear: left;
|
|||
|
}
|
|||
|
|
|||
|
#mem {
|
|||
|
/*width: 48%;*/
|
|||
|
}
|
|||
|
|
|||
|
#virt, #swap {
|
|||
|
white-space: pre;
|
|||
|
}
|
|||
|
|
|||
|
#cpu_times, #io {
|
|||
|
/*width: 48%;*/
|
|||
|
}
|
|||
|
|
|||
|
.t {
|
|||
|
border-top: 1px solid #abcdef;
|
|||
|
}
|
|||
|
.r {
|
|||
|
border-right: 1px solid #abcdef;
|
|||
|
}
|
|||
|
.b {
|
|||
|
border-bottom: 1px solid #abcdef;
|
|||
|
}
|
|||
|
.l {
|
|||
|
border-left: 1px solid #abcdef;
|
|||
|
}
|
|||
|
|
|||
|
.p {
|
|||
|
padding: 10px;
|
|||
|
}
|
|||
|
|
|||
|
.np {
|
|||
|
padding: 0px;
|
|||
|
}
|
|||
|
|
|||
|
#cpu_time_legend, #cpu_time_values, #cpu_time_bars, #io_legend, #io_values {
|
|||
|
white-space: pre;
|
|||
|
float: left;
|
|||
|
}
|
|||
|
|
|||
|
.cpu {
|
|||
|
white-space: pre;
|
|||
|
border-top: 1px solid #abcdef;
|
|||
|
}
|
|||
|
|
|||
|
.cpu:first-of-type {
|
|||
|
border-top: none;
|
|||
|
}
|
|||
|
</style>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div id="container">
|
|||
|
<h1><span id="connecting"></span>nytsoi.net system monitor
|
|||
|
<span id="version"></span>
|
|||
|
| Uptime: <span id="uptime">?</span>
|
|||
|
| <span id="users">?</span> users, <span id="processes">?</span> processes
|
|||
|
</h1>
|
|||
|
|
|||
|
<div id="cpu" class="r t l b">
|
|||
|
<!--<h2 class="b">CPU</h2>-->
|
|||
|
</div>
|
|||
|
|
|||
|
<div id="mem" class="t r">
|
|||
|
<div id="virt" class="p b"></div>
|
|||
|
<div id="swap" class="p"></div>
|
|||
|
</div>
|
|||
|
<div id="cpu_times" class="r t b">
|
|||
|
<h2 class="b">CPU times </h2>
|
|||
|
<div id="cpu_time_legend" class="p">user
|
|||
|
system
|
|||
|
idle
|
|||
|
nice
|
|||
|
iowait
|
|||
|
irq
|
|||
|
softirq
|
|||
|
steal
|
|||
|
guest
|
|||
|
guest_nice</div>
|
|||
|
<div id="cpu_time_values" class="p"></div>
|
|||
|
<div id="cpu_time_bars" class="p"></div>
|
|||
|
</div>
|
|||
|
|
|||
|
<div id="io" class="r b">
|
|||
|
<h2 class="b">I/O </h2>
|
|||
|
<div id="io_legend" class="p">Network
|
|||
|
Bytes in
|
|||
|
Bytes out
|
|||
|
|
|||
|
Disk
|
|||
|
Reads
|
|||
|
Writes</div>
|
|||
|
<div id="io_values" class="p"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
|
|||
|
<script src="ws.js"></script>
|
|||
|
|
|||
|
<script type="text/javascript">
|
|||
|
var connect_chars = "·oOo· ";
|
|||
|
var connect_index = -1;
|
|||
|
var connecting = true;
|
|||
|
var im_hiding_behind_my_facebokk = false;
|
|||
|
var bar_char = "#";
|
|||
|
var cpu_bar_length = 55;
|
|||
|
var cpu_bar_height = 15;
|
|||
|
var cpu_bars = [];
|
|||
|
var cpu_amount = 0;
|
|||
|
var cpu_time_bar_length = 40;
|
|||
|
var mem_bar_length = 55;
|
|||
|
var swap_bar_length = mem_bar_length;
|
|||
|
var boot_time = 0;
|
|||
|
var version = "";
|
|||
|
var io_net_in = 0;
|
|||
|
var io_net_out = 0;
|
|||
|
var io_disk_in = 0;
|
|||
|
var io_disk_out = 0;
|
|||
|
|
|||
|
String.prototype.repeat = function(num)
|
|||
|
{
|
|||
|
num = Math.round(num);
|
|||
|
|
|||
|
if (num <= 0) {
|
|||
|
return "";
|
|||
|
}
|
|||
|
|
|||
|
return new Array(num + 1).join(this);
|
|||
|
};
|
|||
|
|
|||
|
function pad(str, length, filler) {
|
|||
|
if (typeof(filler) === "undefined") {
|
|||
|
filler = " ";
|
|||
|
}
|
|||
|
|
|||
|
str = String(str);
|
|||
|
|
|||
|
if (str.length >= length) {
|
|||
|
return str;
|
|||
|
}
|
|||
|
else {
|
|||
|
return str + filler.repeat(length - str.length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function draw_connecting() {
|
|||
|
if (connecting) {
|
|||
|
++connect_index;
|
|||
|
if (connect_index >= connect_chars.length) {
|
|||
|
connect_index = 0;
|
|||
|
}
|
|||
|
|
|||
|
$('#connecting').text(connect_chars[connect_index] + " ");
|
|||
|
im_hiding_behind_my_facebokk = false;
|
|||
|
}
|
|||
|
else if (!im_hiding_behind_my_facebokk) {
|
|||
|
$('#connecting').hide();
|
|||
|
im_hiding_behind_my_facebokk = true;
|
|||
|
}
|
|||
|
|
|||
|
current_time = (new Date).getTime() / 1000;
|
|||
|
interval = current_time - boot_time;
|
|||
|
|
|||
|
days = Math.floor(interval / 86400);
|
|||
|
hours = Math.floor((interval - (days * 86400)) / 3600);
|
|||
|
minutes = Math.floor((interval - (days * 86400) - (hours * 3600)) / 60);
|
|||
|
seconds = Math.floor(interval - (days * 86400) - (hours * 3600) - (minutes * 60));
|
|||
|
|
|||
|
$('#uptime').text("" + days + "d " + hours + "h " + minutes + "m " + seconds + "s");
|
|||
|
}
|
|||
|
|
|||
|
function bar(percent, max_length) {
|
|||
|
var bar_str = bar_char.repeat(max_length * (percent / 100));
|
|||
|
return pad(bar_str, max_length);
|
|||
|
}
|
|||
|
|
|||
|
function hb(bytes, round) {
|
|||
|
if (typeof(round) === "undefined") {
|
|||
|
round = 2;
|
|||
|
}
|
|||
|
|
|||
|
if (bytes <= 0) {
|
|||
|
return "0 B";
|
|||
|
}
|
|||
|
|
|||
|
var kilo = 1000;
|
|||
|
var prefixes = [
|
|||
|
[Math.pow(kilo, 4), 'T'],
|
|||
|
[Math.pow(kilo, 3), 'G'],
|
|||
|
[Math.pow(kilo, 2), 'M'],
|
|||
|
[kilo, 'k']
|
|||
|
];
|
|||
|
|
|||
|
for (var i = 0; i < prefixes.length; ++i) {
|
|||
|
if (bytes >= prefixes[i][0]) {
|
|||
|
return "" + (bytes / prefixes[i][0]).toFixed(2) + " " + prefixes[i][1] + "B";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return "" + bytes + " B";
|
|||
|
}
|
|||
|
|
|||
|
function connect() {
|
|||
|
return $.gracefulWebSocket("ws://sysmon-ws.nytsoi.net");
|
|||
|
}
|
|||
|
|
|||
|
setInterval(draw_connecting, 1000);
|
|||
|
var ws = connect();
|
|||
|
|
|||
|
ws.onopen = function() {
|
|||
|
connecting = false;
|
|||
|
};
|
|||
|
|
|||
|
ws.onclose = function() {
|
|||
|
connecting = true;
|
|||
|
|
|||
|
ws = connect();
|
|||
|
};
|
|||
|
|
|||
|
ws.onerror = ws.onclose;
|
|||
|
|
|||
|
ws.onmessage = function (event) {
|
|||
|
var json = $.parseJSON(event.data);
|
|||
|
|
|||
|
if (json.boot !== undefined) {
|
|||
|
boot_time = json.boot;
|
|||
|
cpu_amount = json.cpus;
|
|||
|
version = json.version;
|
|||
|
|
|||
|
$('#version').text(version);
|
|||
|
|
|||
|
for (var i = 0; i < cpu_amount; ++i) {
|
|||
|
cpu_bars.push([]);
|
|||
|
|
|||
|
new_div = $('<div />');
|
|||
|
new_div.addClass("cpu p");
|
|||
|
new_div.attr({id: "cpu" + i});
|
|||
|
$('#cpu').append(new_div);
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
// CPU BARS
|
|||
|
var cpu_bar_chars = [];
|
|||
|
for (var cpu = 0; cpu < cpu_amount; ++cpu) {
|
|||
|
new_val = json.cpu[cpu];
|
|||
|
var cbar = cpu_bars[cpu];
|
|||
|
var chars = [];
|
|||
|
|
|||
|
cbar.push(new_val);
|
|||
|
if (cbar.length > cpu_bar_length) {
|
|||
|
cbar.shift();
|
|||
|
}
|
|||
|
|
|||
|
for (var i = 0; i < cbar.length; ++i) {
|
|||
|
chars.push(bar(cbar[i], cpu_bar_height));
|
|||
|
}
|
|||
|
|
|||
|
var output = "";
|
|||
|
var legend = "CPU" + cpu + " " + Math.round(new_val) + "%";
|
|||
|
// Draw bar chart by transposing
|
|||
|
for (var y = 0; y < cpu_bar_height; ++y) {
|
|||
|
for (var x = 0; x < cpu_bar_length; ++x) {
|
|||
|
// Draw legend
|
|||
|
if (y == 0 && x < legend.length) {
|
|||
|
output += legend[x];
|
|||
|
}
|
|||
|
else {
|
|||
|
var cell = undefined;
|
|||
|
var column = chars[x];
|
|||
|
|
|||
|
if (column !== undefined) {
|
|||
|
cell = column[cpu_bar_height-y-1];
|
|||
|
}
|
|||
|
|
|||
|
if (cell === undefined) {
|
|||
|
output += " ";
|
|||
|
}
|
|||
|
else {
|
|||
|
output += cell;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
output += "\n";
|
|||
|
}
|
|||
|
|
|||
|
$('#cpu' + cpu).text(output);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// CPU TIMES
|
|||
|
var ct = json.cpu_times;
|
|||
|
$('#cpu_time_values').text("" +
|
|||
|
pad(Math.round(ct.user), 3) + "\n" +
|
|||
|
pad(Math.round(ct.system), 3) + "\n" +
|
|||
|
pad(Math.round(ct.idle), 3) + "\n" +
|
|||
|
pad(Math.round(ct.nice), 3) + "\n" +
|
|||
|
pad(Math.round(ct.iowait), 3) + "\n" +
|
|||
|
pad(Math.round(ct.irq), 3) + "\n" +
|
|||
|
pad(Math.round(ct.softirq), 3) + "\n" +
|
|||
|
pad(Math.round(ct.steal), 3) + "\n" +
|
|||
|
pad(Math.round(ct.guest), 3) + "\n" +
|
|||
|
pad(Math.round(ct.guest_nice), 3)
|
|||
|
);
|
|||
|
$('#cpu_time_bars').text("" +
|
|||
|
bar(ct.user, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.system, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.idle, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.nice, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.iowait, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.irq, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.softirq, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.steal, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.guest, cpu_time_bar_length) + "\n" +
|
|||
|
bar(ct.guest_nice, cpu_time_bar_length)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// I/O
|
|||
|
var net_in_diff = json.net.bytes_in - io_net_in;
|
|||
|
var net_out_diff = json.net.bytes_out - io_net_out;
|
|||
|
var disk_in_diff = json.disk.read_count - io_disk_in;
|
|||
|
var disk_out_diff = json.disk.write_count - io_disk_out;
|
|||
|
|
|||
|
io_net_in = json.net.bytes_in;
|
|||
|
io_net_out = json.net.bytes_out;
|
|||
|
io_disk_in = json.disk.read_count;
|
|||
|
io_disk_out = json.disk.write_count;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
$('#io_values').text(pad("", 20) + "\n" +
|
|||
|
hb(json.net.bytes_in) + " (" + hb(net_in_diff) + ")\n" +
|
|||
|
hb(json.net.bytes_out) + " (" + hb(net_out_diff) + ")\n" +
|
|||
|
"\n" +
|
|||
|
"\n" +
|
|||
|
json.disk.read_count + " (" + disk_in_diff + ")\n" +
|
|||
|
json.disk.write_count + " (" + disk_out_diff + ")"
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// MEMORY
|
|||
|
var mem_str = "Mem " + bar(json.mem, mem_bar_length);
|
|||
|
var swap_str = "Swap " + bar(json.swap, swap_bar_length);
|
|||
|
|
|||
|
var mem_end = "" + json.mem + " %";
|
|||
|
var swap_end = "" + json.swap + " %";
|
|||
|
mem_str = mem_str.substr(0, mem_str.length - mem_end.length) + mem_end;
|
|||
|
swap_str = swap_str.substr(0, swap_str.length - swap_end.length) + swap_end;
|
|||
|
|
|||
|
$('#virt').text(mem_str);
|
|||
|
$('#swap').text(swap_str);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// MISC
|
|||
|
$('#users').text(json.users);
|
|||
|
$('#processes').text(json.procs);
|
|||
|
}
|
|||
|
};
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|