2020-09-29 01:28:43 +02:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
<link
|
|
|
|
href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap"
|
|
|
|
rel="stylesheet">
|
|
|
|
<script
|
|
|
|
src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0/dist/Chart.bundle.min.js"></script>
|
|
|
|
<title>Fiber Monitor</title>
|
|
|
|
<style>
|
2020-09-29 01:28:43 +02:00
|
|
|
body {
|
|
|
|
margin: 0;
|
|
|
|
font: 16px / 1.6 'Roboto', sans-serif;
|
|
|
|
}
|
|
|
|
|
|
|
|
.wrapper {
|
|
|
|
max-width: 900px;
|
|
|
|
margin: 0 auto;
|
|
|
|
padding: 30px 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.title {
|
|
|
|
text-align: center;
|
|
|
|
margin-bottom: 2em;
|
|
|
|
}
|
|
|
|
|
|
|
|
.title h1 {
|
|
|
|
font-size: 1.8em;
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row {
|
|
|
|
display: flex;
|
|
|
|
margin-bottom: 20px;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row .column:first-child {
|
|
|
|
width: 35%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.row .column:last-child {
|
|
|
|
width: 65%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.metric {
|
|
|
|
color: #777;
|
|
|
|
font-weight: 900;
|
|
|
|
}
|
|
|
|
|
|
|
|
h2 {
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
font-size: 2.2em;
|
|
|
|
}
|
|
|
|
|
2020-09-29 03:11:39 +02:00
|
|
|
h2 span {
|
|
|
|
font-size: 12px;
|
|
|
|
color: #777;
|
|
|
|
}
|
|
|
|
|
2020-09-29 01:28:43 +02:00
|
|
|
canvas {
|
|
|
|
width: 200px;
|
|
|
|
height: 180px;
|
|
|
|
}
|
|
|
|
</style>
|
2020-09-29 04:03:13 +02:00
|
|
|
</head>
|
2020-09-29 01:28:43 +02:00
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
<body>
|
|
|
|
<section class="wrapper">
|
|
|
|
<div class="title">
|
|
|
|
<h1>Fiber Monitor</h1>
|
2020-09-29 01:28:43 +02:00
|
|
|
</div>
|
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
<section class="charts">
|
|
|
|
<div class="row">
|
|
|
|
<div class="column">
|
|
|
|
<div class="metric">CPU Usage</div>
|
|
|
|
<h2 id="cpuMetric">0.00%</h2>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<canvas id="cpuChart"></canvas>
|
|
|
|
</div>
|
2020-09-29 01:28:43 +02:00
|
|
|
</div>
|
2020-09-29 04:03:13 +02:00
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
<div class="column">
|
|
|
|
<div class="metric">Memory Usage</div>
|
|
|
|
<h2 id="ramMetric">0.00 MB</h2>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<canvas id="ramChart"></canvas>
|
|
|
|
</div>
|
2020-09-29 01:28:43 +02:00
|
|
|
</div>
|
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
<div class="row">
|
|
|
|
<div class="column">
|
|
|
|
<div class="metric">Response Time</div>
|
|
|
|
<h2 id="rtimeMetric">0ms</h2>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<canvas id="rtimeChart"></canvas>
|
|
|
|
</div>
|
2020-09-29 01:28:43 +02:00
|
|
|
</div>
|
2020-09-29 04:03:13 +02:00
|
|
|
|
|
|
|
<div class="row">
|
|
|
|
<div class="column">
|
|
|
|
<div class="metric">Open Connections</div>
|
|
|
|
<h2 id="connsMetric">0</h2>
|
|
|
|
</div>
|
|
|
|
<div class="column">
|
|
|
|
<canvas id="connsChart"></canvas>
|
|
|
|
</div>
|
2020-09-29 01:28:43 +02:00
|
|
|
</div>
|
2020-09-29 04:03:13 +02:00
|
|
|
</section>
|
2020-09-29 01:28:43 +02:00
|
|
|
</section>
|
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
<script>
|
2020-09-29 03:11:39 +02:00
|
|
|
function formatBytes(bytes, decimals = 1) {
|
|
|
|
if (bytes === 0) return '0 Bytes';
|
|
|
|
|
|
|
|
const k = 1024;
|
|
|
|
const dm = decimals < 0 ? 0 : decimals;
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
|
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
|
|
|
}
|
2020-09-29 01:28:43 +02:00
|
|
|
Chart.defaults.global.legend.display = false;
|
|
|
|
Chart.defaults.global.defaultFontSize = 8;
|
|
|
|
Chart.defaults.global.animation.duration = 1000;
|
|
|
|
Chart.defaults.global.animation.easing = 'easeOutQuart';
|
|
|
|
Chart.defaults.global.elements.line.backgroundColor = 'rgba(0, 172, 215, 0.25)';
|
|
|
|
Chart.defaults.global.elements.line.borderColor = 'rgba(0, 172, 215, 1)';
|
|
|
|
Chart.defaults.global.elements.line.borderWidth = 2;
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
scales: {
|
|
|
|
yAxes: [{
|
|
|
|
ticks: {
|
2020-09-29 02:31:32 +02:00
|
|
|
beginAtZero: true
|
2020-09-29 01:28:43 +02:00
|
|
|
}
|
|
|
|
}],
|
|
|
|
xAxes: [{
|
|
|
|
type: 'time',
|
|
|
|
time: {
|
|
|
|
unitStepSize: 30,
|
|
|
|
unit: 'second'
|
|
|
|
},
|
|
|
|
gridlines: {
|
|
|
|
display: false
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
tooltips: {
|
|
|
|
enabled: false
|
|
|
|
},
|
|
|
|
responsive: true,
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
animation: false
|
|
|
|
};
|
|
|
|
|
|
|
|
const cpuMetric = document.querySelector('#cpuMetric');
|
|
|
|
const ramMetric = document.querySelector('#ramMetric');
|
2020-09-29 02:31:32 +02:00
|
|
|
const rtimeMetric = document.querySelector('#rtimeMetric');
|
|
|
|
const connsMetric = document.querySelector('#connsMetric');
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
const cpuChartCtx = document.querySelector('#cpuChart').getContext('2d');
|
|
|
|
const ramChartCtx = document.querySelector('#ramChart').getContext('2d');
|
2020-09-29 02:31:32 +02:00
|
|
|
const rtimeChartCtx = document.querySelector('#rtimeChart').getContext('2d');
|
|
|
|
const connsChartCtx = document.querySelector('#connsChart').getContext('2d');
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
const cpuChart = createChart(cpuChartCtx);
|
|
|
|
const ramChart = createChart(ramChartCtx);
|
2020-09-29 02:31:32 +02:00
|
|
|
const rtimeChart = createChart(rtimeChartCtx);
|
|
|
|
const connsChart = createChart(connsChartCtx);
|
2020-09-29 01:28:43 +02:00
|
|
|
|
2020-09-29 02:31:32 +02:00
|
|
|
const charts = [cpuChart, ramChart, rtimeChart, connsChart];
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
function createChart(ctx) {
|
|
|
|
return new Chart(ctx, {
|
|
|
|
type: 'line',
|
|
|
|
data: {
|
|
|
|
labels: [],
|
|
|
|
datasets: [{
|
|
|
|
label: '',
|
|
|
|
data: [],
|
|
|
|
lineTension: 0.2,
|
|
|
|
pointRadius: 0,
|
|
|
|
}]
|
|
|
|
},
|
|
|
|
options
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// function init() {
|
|
|
|
// charts.forEach(chart => {
|
|
|
|
// chart.data.datasets[0].data = JSON.parse(localStorage.getItem(chart.canvas.id)) || []
|
|
|
|
// chart.update();
|
|
|
|
// })
|
|
|
|
// }
|
|
|
|
|
2020-09-29 04:03:13 +02:00
|
|
|
function update(json, rtime) {
|
2020-09-29 03:11:39 +02:00
|
|
|
cpu = json.pid.cpu.toFixed(1);
|
|
|
|
cpuOS = json.os.cpu.toFixed(1);
|
2020-09-29 01:28:43 +02:00
|
|
|
|
2020-09-29 03:11:39 +02:00
|
|
|
cpuMetric.innerHTML = cpu + '% <span>' + cpuOS + '%</span>';
|
2020-09-29 03:18:58 +02:00
|
|
|
ramMetric.innerHTML = formatBytes(json.pid.ram) + ' <span>' + formatBytes(json.os.ram) + '</span>';
|
2020-09-29 04:36:38 +02:00
|
|
|
rtimeMetric.innerHTML = rtime + 'ms <span>client</span>';
|
2020-09-29 03:11:39 +02:00
|
|
|
connsMetric.innerHTML = json.conns;
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
cpuChart.data.datasets[0].data.push(cpu);
|
2020-09-29 03:18:58 +02:00
|
|
|
ramChart.data.datasets[0].data.push((json.pid.ram / 1e6).toFixed(2));
|
2020-09-29 04:03:13 +02:00
|
|
|
rtimeChart.data.datasets[0].data.push(rtime);
|
2020-09-29 03:11:39 +02:00
|
|
|
connsChart.data.datasets[0].data.push(json.conns);
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
const timestamp = new Date().getTime();
|
|
|
|
|
|
|
|
charts.forEach(chart => {
|
|
|
|
if (chart.data.labels.length > 50) {
|
|
|
|
chart.data.datasets.forEach(function (dataset) {
|
|
|
|
dataset.data.shift();
|
|
|
|
});
|
|
|
|
chart.data.labels.shift();
|
|
|
|
}
|
|
|
|
|
|
|
|
chart.data.labels.push(timestamp);
|
|
|
|
chart.update();
|
|
|
|
// localStorage.setItem(chart.canvas.id, JSON.stringify(chart.data.datasets[0].data));
|
|
|
|
});
|
2020-09-29 04:31:11 +02:00
|
|
|
setTimeout(fetchJSON, 750)
|
2020-09-29 04:36:38 +02:00
|
|
|
|
2020-09-29 01:28:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function fetchJSON() {
|
2020-09-29 04:03:13 +02:00
|
|
|
var t1 = ''
|
|
|
|
var t0 = performance.now()
|
2020-09-29 01:28:43 +02:00
|
|
|
fetch(window.location.href, {
|
|
|
|
headers: {
|
|
|
|
'Accept': 'application/json'
|
|
|
|
},
|
|
|
|
credentials: 'same-origin'
|
|
|
|
})
|
2020-09-29 04:03:13 +02:00
|
|
|
.then(res => {
|
|
|
|
t1 = performance.now()
|
|
|
|
return res.json()
|
|
|
|
})
|
|
|
|
.then(res => {
|
2020-09-29 04:36:38 +02:00
|
|
|
update(res, Math.round(t1 - t0))
|
2020-09-29 04:03:13 +02:00
|
|
|
})
|
2020-09-29 04:36:38 +02:00
|
|
|
.catch(console.error);
|
2020-09-29 01:28:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fetchJSON()
|
|
|
|
</script>
|
2020-09-29 04:03:13 +02:00
|
|
|
</body>
|
2020-09-29 01:28:43 +02:00
|
|
|
|
|
|
|
</html>
|