index.html 9.56 KB
<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
    <style>
        * {
            font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
        }

        h1 {
            font-size: 3em;
            color: #222222;
            margin: 0;
        }

        h5 {
            margin: 0;
            color: #888888;
        }

        p {
            font-size: 0.7em;
            color: #888888;
        }

        .stats-column {
            flex: 0 0 200px;
        }

        .container {
            display: flex;
            flex-direction: row;
            margin-top: 20px;
            height: 100px;
        }

        .footer {
            position: fixed;
            margin: auto;
            text-align: center;
            left: 0;
            right: 0;
            bottom: 0;
        }

        .span-controls {
            float: right;
        }

        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
<div style="width: 400px; margin: auto">
    <div class="header">
        <span><b>Express Status</b></span>
        <div class="span-controls">
            <span>1M</span>
            <span>15M</span>
            <span>1H</span>
            <span>24H</span>
        </div>
    </div>
    <div class="container">
        <div class="stats-column">
            <h5>CPU Usage</h5>
            <h1 id="cpuStat">- %</h1>
        </div>
        <canvas id="cpuChart" width="400" height="100"></canvas>
    </div>
    <div class="container">
        <div class="stats-column">
            <h5>Memory Usage</h5>
            <h1 id="memStat">- %</h1>
        </div>
        <canvas id="memChart" width="400" height="100"></canvas>
    </div>
    <div class="container">
        <div class="stats-column">
            <h5>One Minute Load Avg</h5>
            <h1 id="loadStat">-</h1>
        </div>
        <canvas id="loadChart" width="400" height="100"></canvas>
    </div>
    <div class="container">
        <div class="stats-column">
            <h5>Response Time</h5>
            <h1 id="responseTimeStat">-</h1>
        </div>
        <canvas id="responseTimeChart" width="400" height="100"></canvas>
    </div>
    <div class="container">
        <div class="stats-column">
            <h5>Requests per Second</h5>
            <h1 id="rpsStat">-</h1>
        </div>
        <canvas id="rpsChart" width="400" height="100"></canvas>
    </div>
    <div class="footer">
        <p>Made with &#9829; with Socket.io & Chart.js</p>
    </div>
</div>
<script>
    Chart.defaults.global.defaultFontSize = 8;
    Chart.defaults.global.animation.duration = 500;
    Chart.defaults.global.legend.display = false;
    Chart.defaults.global.elements.line.backgroundColor = "rgba(0,0,0,0)";
    Chart.defaults.global.elements.line.borderColor = "rgba(0,0,0,0.9)";
    Chart.defaults.global.elements.line.borderWidth = 2;

    var socket = io('http://localhost:41338');
    var labels = [];
    var cpuDataset = [{
        label: 'CPU Usage in %',
        data: [],
        lineTension: 0.3,
        pointRadius: 0,
    }];

    var memDataset = [{
        label: 'Memory Usage in MB',
        data: [],
        lineTension: 0.2,
        pointRadius: 0,
    }];

    var loadDataset = [{
        label: '1 Minute Load',
        data: [],
        lineTension: 0.2,
        pointRadius: 0,
    }];

    var responseTimeDataset = [{
        label: 'Response Time',
        data: [],
        lineTension: 0.2,
        pointRadius: 0,
    }];

    var rpsDataset = [{
        label: 'Requests per Second',
        data: [],
        lineTension: 0.2,
        pointRadius: 0,
    }];

    var defaultOptions = {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }],
            xAxes: [{
                type: 'time',
                time: {
                    unitStepSize: 30
                },
                gridLines: {
                    display: false
                }
            }]
        },
        tooltips: {
            enabled: false
        }
    };

    var cpuStat = document.getElementById('cpuStat');
    var memStat = document.getElementById('memStat');
    var loadStat = document.getElementById('loadStat');
    var responseTimeStat = document.getElementById('responseTimeStat');
    var rpsStat = document.getElementById('rpsStat');

    var cpuChartCtx = document.getElementById("cpuChart");
    var memChartCtx = document.getElementById("memChart");
    var loadChartCtx = document.getElementById("loadChart");
    var responseTimeChartCtx = document.getElementById("responseTimeChart");
    var rpsChartCtx = document.getElementById("rpsChart");

    var cpuChart = new Chart(cpuChartCtx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: cpuDataset,
        },
        options: defaultOptions
    });

    var memChart = new Chart(memChartCtx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: memDataset,
        },
        options: defaultOptions
    });

    var loadChart = new Chart(loadChartCtx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: loadDataset,
        },
        options: defaultOptions
    });

    var responseTimeChart = new Chart(responseTimeChartCtx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: responseTimeDataset,
        },
        options: defaultOptions
    });

    var rpsChart = new Chart(rpsChartCtx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: rpsDataset,
        },
        options: defaultOptions
    });

    socket.on('start', function(data) {
        // Remove last element of Array because it contains malformed responses data.
        // To keep consistency we also remove os data.
        data[0].responses.pop();
        data[0].os.pop();

        cpuStat.textContent = data[0].os[data[0].os.length - 1].cpu.toFixed(1) + '%';
        cpuChart.data.datasets[0].data = data[0].os.map(function(point) { return point.cpu; });
        cpuChart.data.labels = data[0].os.map(function(point) { return point.timestamp; });
        cpuChart.update();

        memStat.textContent = data[0].os[data[0].os.length - 1].memory.toFixed(1) + 'MB';
        memChart.data.datasets[0].data = data[0].os.map(function(point) { return point.memory; });
        memChart.data.labels = data[0].os.map(function(point) { return point.timestamp; });
        memChart.update();

        loadStat.textContent = data[0].os[data[0].os.length - 1].load[0].toFixed(2);
        loadChart.data.datasets[0].data = data[0].os.map(function(point) { return point.load[0]; });
        loadChart.data.labels = data[0].os.map(function(point) { return point.timestamp; });
        loadChart.update();

        responseTimeStat.textContent = data[0].responses[data[0].responses.length - 1].mean.toFixed(2) + 'ms';
        responseTimeChart.data.datasets[0].data = data[0].responses.map(function(point) { return point.mean; });
        responseTimeChart.data.labels = data[0].responses.map(function(point) { return point.timestamp; });
        responseTimeChart.update();

        if (data[0].responses.length >= 2) {
            var deltaTime = data[0].responses[data[0].responses.length - 1].timestamp - data[0].responses[data[0].responses.length - 2].timestamp;
            rpsStat.textContent = (data[0].responses[data[0].responses.length - 1].count / deltaTime * 1000).toFixed(2);
            rpsChart.data.datasets[0].data = data[0].responses.map(function(point) { return point.count / deltaTime * 1000; });
            rpsChart.data.labels = data[0].responses.map(function(point) { return point.timestamp; });
            rpsChart.update();
        }
    });

    socket.on('stats', function (data) {
        cpuStat.textContent = data.os.cpu.toFixed(1) + '%';
        cpuChart.data.datasets[0].data.push(data.os.cpu);
        cpuChart.data.labels.push(data.os.timestamp);
        cpuChart.data.datasets[0].data.shift();
        cpuChart.data.labels.shift();
        cpuChart.update();

        memStat.textContent = data.os.memory.toFixed(1) + 'MB';
        memChart.data.datasets[0].data.push(data.os.memory);
        memChart.data.labels.push(data.os.timestamp);
        memChart.data.datasets[0].data.shift();
        memChart.data.labels.shift();
        memChart.update();

        loadStat.textContent = data.os.load[0].toFixed(2);
        loadChart.data.datasets[0].data.push(data.os.load[0]);
        loadChart.data.labels.push(data.os.timestamp);
        loadChart.data.datasets[0].data.shift();
        loadChart.data.labels.shift();
        loadChart.update();

        responseTimeStat.textContent = data.responses.mean.toFixed(2) + 'ms';
        responseTimeChart.data.datasets[0].data.push(data.responses.mean);
        responseTimeChart.data.labels.push(data.responses.timestamp);
        responseTimeChart.data.datasets[0].data.shift();
        responseTimeChart.data.labels.shift();
        responseTimeChart.update();

        var deltaTime = data.responses.timestamp - rpsChart.data.labels[rpsChart.data.labels.length - 1];
        rpsStat.textContent = (data.responses.count / deltaTime * 1000).toFixed(2);
        rpsChart.data.datasets[0].data.push(data.responses.count / deltaTime * 1000);
        rpsChart.data.labels.push(data.responses.timestamp);
        rpsChart.data.datasets[0].data.shift();
        rpsChart.data.labels.shift();
        rpsChart.update();
    });
</script>
</body>
</html>