Initial work on traffic graph.

Ylian Saint-Hilaire committed May 5, 2021 at 17:08 UTC b349b83ef1cbbac55f3477efb613836f3fdcb162
2 files changed +49 -2
meshcentral.js
+7 -1
@@ -1665,6 +1665,7 @@ function CreateMeshCentralServer(config, args) {
1665 }
1666
1667 // Start collecting server stats every 5 minutes
1668 + obj.trafficStats = obj.webserver.getTrafficStats();
1669 setInterval(function () {
1670 obj.serverStatsCounter++;
1671 var hours = 720; // Start with all events lasting 30 days.
@@ -1676,6 +1677,10 @@ function CreateMeshCentralServer(config, args) {
1677 var expire = new Date();
1678 expire.setTime(expire.getTime() + (60 * 60 * 1000 * hours));
1679
1680 + // Get traffic data
1681 + var trafficStats = obj.webserver.getTrafficDelta(obj.trafficStats);
1682 + obj.trafficStats = trafficStats.current;
1683 +
1684 var data = {
1685 time: new Date(),
1686 expire: expire,
@@ -1686,7 +1691,8 @@ function CreateMeshCentralServer(config, args) {
1691 cu: Object.keys(obj.webserver.wssessions).length,
1692 us: Object.keys(obj.webserver.wssessions2).length,
1693 rs: obj.webserver.relaySessionCount
1689 - }
1694 + },
1695 + traffic: trafficStats.delta
1696 };
1697 if (obj.mpsserver != null) {
1698 data.conn.am = 0;
views/default.handlebars
+42 -1
@@ -1023,6 +1023,8 @@
1023 <select id=p40type onchange=updateServerTimelineStats()>
1024 <option value=0>Connections</option>
1025 <option value=1>Memory</option>
1026 + <option value=3>Inbound Traffic</option>
1027 + <option value=4>Outbound Traffic</option>
1028 </select>&nbsp;
1029 <select id=p40time onchange=updateServerTimelineHours()>
1030 <option value=3>Last 3 hours</option>
@@ -14381,6 +14383,7 @@
14383 maintainAspectRatio: false,
14384 elements: { line: { cubicInterpolationMode: 'monotone' } },
14385 scales: {
14386 + y: { stacked: true },
14387 xAxes: [{ type: 'time', time: { tooltipFormat: 'll HH:mm' }, display: true, scaleLabel: { display: false, labelString: '' } }],
14388 yAxes: [{ type: 'linear', display: true, scaleLabel: { display: true, labelString: '' } }]
14389 }
@@ -14497,7 +14500,45 @@
14500 data.datasets[2].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].mem.heapTotal / (1024 * 1024) });
14501 data.datasets[3].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].mem.rss / (1024 * 1024) });
14502 }
14500 - } /*else if (chartType == 2) { // Database
14503 + } else if ((chartType == 3) || (chartType == 4)) { // Inbound/Outbound traffic
14504 + serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = "Megabytes";
14505 + data = {
14506 + labels: [pastDate(0), timeAfter],
14507 + datasets: [
14508 + { label: "Agent", data: [], backgroundColor: 'rgba(158, 151, 16, .1)', borderColor: 'rgb(158, 151, 16)', fill: true, steppedLine: true },
14509 + { label: "CIRA", data: [], backgroundColor: 'rgba(16, 84, 158, .1)', borderColor: 'rgb(16, 84, 158)', fill: true, steppedLine: true },
14510 + { label: "LMS", data: [], backgroundColor: 'rgba(255, 99, 132, .1)', borderColor: 'rgb(255, 99, 132)', fill: true, steppedLine: true },
14511 + { label: "HTTP", data: [], backgroundColor: 'rgba(39, 158, 16, .1)', borderColor: 'rgb(39, 158, 16)', fill: true, steppedLine: true }
14512 + ]
14513 + };
14514 + for (var i = 0; i < serverTimelineStats.length; i++) {
14515 + if (serverTimelineStats[i].traffic == null) continue;
14516 + if ((serverTimelineStats[i].s != null) && (servers.indexOf(serverTimelineStats[i].s) == -1)) {
14517 + servers.push(serverTimelineStats[i].s);
14518 + if (serverAutoSelect) { selectedServer = serverTimelineStats[i].s; serverAutoSelect = false; }
14519 + }
14520 + if (serverTimelineStats[i].s == null) { serverEmptyExists = true; }
14521 + if (serverTimelineStats[i].s != selectedServer) { continue; }
14522 + if (serverTimelineStats[i].first == true) {
14523 + data.datasets[0].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
14524 + data.datasets[1].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
14525 + data.datasets[2].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
14526 + data.datasets[3].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
14527 + }
14528 + if (chartType == 3) {
14529 + data.datasets[0].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.AgentCtrlIn ? (serverTimelineStats[i].traffic.AgentCtrlIn / (1024 * 1024)) : 0 });
14530 + data.datasets[1].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.CIRAIn ? (serverTimelineStats[i].traffic.CIRAIn / (1024 * 1024)) : 0 });
14531 + data.datasets[2].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.LMSIn ? (serverTimelineStats[i].traffic.LMSIn / (1024 * 1024)) : 0 });
14532 + data.datasets[3].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.httpIn ? (serverTimelineStats[i].traffic.httpIn / (1024 * 1024)) : 0 });
14533 + } else if (chartType == 4) {
14534 + data.datasets[0].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.AgentCtrlOut ? (serverTimelineStats[i].traffic.AgentCtrlOut / (1024 * 1024)) : 0 });
14535 + data.datasets[1].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.CIRAOut ? (serverTimelineStats[i].traffic.CIRAOut / (1024 * 1024)) : 0 });
14536 + data.datasets[2].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.LMSOut ? (serverTimelineStats[i].traffic.LMSOut / (1024 * 1024)) : 0 });
14537 + data.datasets[3].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].traffic.httpOut ? (serverTimelineStats[i].traffic.httpOut / (1024 * 1024)) : 0 });
14538 + }
14539 + }
14540 + }
14541 + /*else if (chartType == 2) { // Database
14542 serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = 'Records';
14543 data = {
14544 labels: [pastDate(0), timeAfter],