|
@@ -1,3 +1,4 @@
|
|
|
+<script src="script/chart.js"></script>
|
|
|
<div class="ui stackable grid">
|
|
|
<div class="ten wide column serverstatusWrapper">
|
|
|
<div id="serverstatus" class="ui statustab inverted segment">
|
|
@@ -51,6 +52,10 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+<div class="standardContainer" style="position: relative; margin-top: 1em;">
|
|
|
+ <canvas id="networkActivity"></canvas>
|
|
|
+</div>
|
|
|
<br>
|
|
|
<div class="standardContainer">
|
|
|
<h4>Basic Settings</h4>
|
|
@@ -371,4 +376,177 @@
|
|
|
}
|
|
|
initTlsSetting();
|
|
|
|
|
|
-</script>
|
|
|
+</script>
|
|
|
+
|
|
|
+<script>
|
|
|
+ /*
|
|
|
+ Render Network Activity Graph
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ Setup Graph
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+ let rxValues = [];
|
|
|
+ let txValues = [];
|
|
|
+ let lastRx = 0;
|
|
|
+ let lastTx = 0;
|
|
|
+ let timestamps = [];
|
|
|
+ let netstatRecordTokeep = 60;
|
|
|
+
|
|
|
+ function fetchData() {
|
|
|
+ fetch('/api/stats/netstat')
|
|
|
+ .then(response => response.json())
|
|
|
+ .then(data => {
|
|
|
+ let rx = data.RX;
|
|
|
+ let tx = data.TX;
|
|
|
+
|
|
|
+ // Calculate change from previous values
|
|
|
+ if (lastRx == 0 && lastTx == 0){
|
|
|
+ //inital value
|
|
|
+ lastRx = rx;
|
|
|
+ lastTx = tx;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let deltaRx = rx - lastRx;
|
|
|
+ let deltaTx = tx - lastTx;
|
|
|
+
|
|
|
+ if (rxValues.length < netstatRecordTokeep){
|
|
|
+ //pad init into the array
|
|
|
+ for(var i = 0;i<netstatRecordTokeep;i++){
|
|
|
+ rxValues.push(deltaRx);
|
|
|
+ txValues.push(deltaTx);
|
|
|
+ timestamps.push(Date.now() - 1000 * (netstatRecordTokeep - i))
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add change to accumulated values
|
|
|
+ rxValues.push(deltaRx);
|
|
|
+ txValues.push(deltaTx);
|
|
|
+ timestamps.push(Date.now());
|
|
|
+
|
|
|
+ // Only keep last netstatRecordTokeep data points
|
|
|
+ if (rxValues.length > netstatRecordTokeep) {
|
|
|
+ rxValues.shift();
|
|
|
+ txValues.shift();
|
|
|
+ timestamps.shift();
|
|
|
+ }
|
|
|
+
|
|
|
+ lastRx = rx;
|
|
|
+ lastTx = tx;
|
|
|
+
|
|
|
+ updateChart();
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ console.error('Failed to fetch data', error);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatBandwidth(bps) {
|
|
|
+ const KBPS = 1000;
|
|
|
+ const MBPS = 1000 * KBPS;
|
|
|
+ const GBPS = 1000 * MBPS;
|
|
|
+
|
|
|
+ if (bps >= GBPS) {
|
|
|
+ return (bps / GBPS).toFixed(2) + " Gbps";
|
|
|
+ } else if (bps >= MBPS) {
|
|
|
+ return (bps / MBPS).toFixed(2) + " Mbps";
|
|
|
+ } else if (bps >= KBPS) {
|
|
|
+ return (bps / KBPS).toFixed(2) + " Kbps";
|
|
|
+ } else {
|
|
|
+ return bps.toFixed(2) + " bps";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var networkStatisticChart;
|
|
|
+ function initChart(){
|
|
|
+ $.get("/api/stats/netstat", function(data){
|
|
|
+ networkStatisticChart = new Chart(
|
|
|
+ document.getElementById('networkActivity'),
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ responsive: true,
|
|
|
+ options: {
|
|
|
+ animation: false,
|
|
|
+ maintainAspectRatio: false,
|
|
|
+ tooltips: {enabled: false},
|
|
|
+ hover: {mode: null},
|
|
|
+ plugins: {
|
|
|
+ legend: {
|
|
|
+ display: true,
|
|
|
+ position: "right",
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ display: false,
|
|
|
+ text: 'Network Statistic'
|
|
|
+ },
|
|
|
+ },
|
|
|
+ scales: {
|
|
|
+ x: {
|
|
|
+ display: false,
|
|
|
+ },
|
|
|
+ y: {
|
|
|
+ display: true,
|
|
|
+ scaleLabel: {
|
|
|
+ display: true,
|
|
|
+ labelString: 'Value'
|
|
|
+ },
|
|
|
+ ticks: {
|
|
|
+ stepSize: 10000000,
|
|
|
+ callback: function(label, index, labels) {
|
|
|
+ return formatBandwidth(parseInt(label));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ gridLines: {
|
|
|
+ display: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ labels: timestamps,
|
|
|
+ datasets: [
|
|
|
+ {
|
|
|
+ label: 'Inbound',
|
|
|
+ data: rxValues,
|
|
|
+ borderColor: "#4d9dd9",
|
|
|
+ backgroundColor: 'rgba(77, 157, 217, 0.2)',
|
|
|
+ fill: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'Outbound',
|
|
|
+ data: txValues,
|
|
|
+ borderColor: '#3a9460',
|
|
|
+ backgroundColor: 'rgba(58, 148, 96, 0.2)',
|
|
|
+ fill: true,
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function updateChart() {
|
|
|
+ //networkStatisticChart.data.datasets[0].data = rxValues;
|
|
|
+ //networkStatisticChart.data.datasets[1].data = txValues;
|
|
|
+ networkStatisticChart.update();
|
|
|
+ }
|
|
|
+
|
|
|
+ window.addEventListener('resize', () => {
|
|
|
+ networkStatisticChart.resize($(".contentWindow").width() - 500, 200);
|
|
|
+ });
|
|
|
+
|
|
|
+ //Bind event to tab switch
|
|
|
+ tabSwitchEventBind["status"] = function(){
|
|
|
+ //On switch over to this page, resize the chart
|
|
|
+ networkStatisticChart.resize($(".contentWindow").width() - 500, 200);
|
|
|
+ }
|
|
|
+
|
|
|
+ //Initialize chart data
|
|
|
+ initChart();
|
|
|
+ fetchData();
|
|
|
+ setInterval(fetchData, 1000);
|
|
|
+</script>
|