240 lines
6.7 KiB
JavaScript
240 lines
6.7 KiB
JavaScript
var chartOptions = {
|
|
colors:['#008ffb', '#f08681'],
|
|
series: [
|
|
{
|
|
name: 'Ping',
|
|
data: [null]
|
|
},
|
|
{
|
|
name: 'Pakke Tap',
|
|
type: 'area',
|
|
data: [null]
|
|
}
|
|
],
|
|
chart: {
|
|
height: '100%',
|
|
id: 'realtime',
|
|
type: 'area',
|
|
animations: {
|
|
enabled: false,
|
|
},
|
|
toolbar: {
|
|
show: false
|
|
},
|
|
zoom: {
|
|
enabled: false
|
|
},
|
|
},
|
|
dataLabels: {
|
|
enabled: false,
|
|
},
|
|
stroke: {
|
|
curve: 'straight'
|
|
},
|
|
markers: {
|
|
size: 0
|
|
},
|
|
xaxis: {
|
|
type: 'datetime',
|
|
labels: {
|
|
datetimeUTC: false,
|
|
},
|
|
},
|
|
yaxis: [
|
|
{
|
|
seriesName: 'Ping',
|
|
labels: {
|
|
formatter: function (val) {
|
|
if (val == null) {
|
|
return 0;
|
|
}
|
|
return val.toFixed(1);
|
|
},
|
|
}
|
|
},
|
|
{
|
|
seriesName: 'Pakke Tap',
|
|
min:0,
|
|
max:100,
|
|
opposite: true,
|
|
|
|
labels: {
|
|
formatter: function (val) {
|
|
if (val == null) {
|
|
return 0 + '%';
|
|
}
|
|
return val.toFixed(0) + "%";
|
|
},
|
|
}
|
|
}
|
|
],
|
|
legend: {
|
|
show: false
|
|
},
|
|
};
|
|
var timeRangeInSeconds = 0;
|
|
var chartLatest;
|
|
var chartHasFetchedTimeRange = false;
|
|
var chartElement;
|
|
var chartPingSeries = [];
|
|
var chartPacketLossSeries = [];
|
|
var scanId;
|
|
|
|
const queryParam = new Proxy(new URLSearchParams(window.location.search), {
|
|
get: (searchParams, prop) => searchParams.get(prop),
|
|
});
|
|
|
|
document.body.onload = async function() {
|
|
chartElement = new ApexCharts(document.querySelector("#liveChart"), chartOptions);
|
|
chartElement.render();
|
|
|
|
timeRangeInSeconds = timeRangeSelector[timeRangeSelector.selectedIndex].attributes.value.nodeValue;
|
|
|
|
await update_summary();
|
|
update_chart();
|
|
window.setInterval(async function() {
|
|
update_summary();
|
|
update_chart();
|
|
}, 5000)
|
|
};
|
|
|
|
timeRangeSelector.onchange = function(event) {
|
|
timeRangeInSeconds = event.srcElement[event.srcElement.selectedIndex].attributes.value.nodeValue;
|
|
|
|
if (timeRangeInSeconds == 'Details') {
|
|
if (queryParam.ref_uuid !== null) {
|
|
window.location.href = './?p=scan_details&ref_uuid=' + queryParam.ref_uuid + '&scan_id=' + scanId;
|
|
} else {
|
|
window.location.href = './?p=scan_details&host=' + queryParam.host + '&scan_id=' + scanId;
|
|
}
|
|
}
|
|
|
|
// TODO: a very rare race condition may occur when switching too fast between time ranges can cause the chart to show wrong data
|
|
// cancel the update interval and start it again
|
|
|
|
// reset chart
|
|
chartHasFetchedTimeRange = false;
|
|
chartPingSeries = [];
|
|
chartPacketLossSeries = [];
|
|
chartElement.updateSeries([
|
|
{
|
|
data: chartPingSeries
|
|
},
|
|
{
|
|
data: chartPacketLossSeries
|
|
}
|
|
]);
|
|
|
|
update_chart();
|
|
update_summary();
|
|
};
|
|
|
|
async function update_summary() {
|
|
if (queryParam.ref_uuid !== null) {
|
|
var response = await fetch('./?p=api_stats&ref_uuid=' + queryParam.ref_uuid + '&since=' + (Math.floor(Date.now() / 1000) - timeRangeInSeconds));
|
|
} else {
|
|
var response = await fetch('./?p=api_stats&host=' + queryParam.host + '&since=' + (Math.floor(Date.now() / 1000) - timeRangeInSeconds));
|
|
}
|
|
|
|
if (response.status == 400) {
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
return;
|
|
}
|
|
|
|
if (response.status !== 200) {
|
|
return;
|
|
}
|
|
|
|
let jsonResponse = await response.json();
|
|
|
|
scanId = jsonResponse.scan_id;
|
|
|
|
let resp_ping = jsonResponse.ping_latest;
|
|
let resp_packet_loss = jsonResponse.packet_loss_percentage;
|
|
let resp_uptime = jsonResponse.uptime_percentage;
|
|
let resp_connection_status = jsonResponse.connection_status;
|
|
|
|
if (resp_ping == null) {
|
|
ping.innerHTML = 'Feilet';
|
|
} else {
|
|
ping.innerHTML = resp_ping + ' ms';
|
|
}
|
|
|
|
packet_loss.innerHTML = resp_packet_loss + ' %';
|
|
uptime.innerHTML = resp_uptime + ' %';
|
|
|
|
if (resp_connection_status == 'ONLINE') {
|
|
connection_status.className = 'sign-text alert-success'
|
|
connection_status.innerHTML = 'Online';
|
|
}
|
|
if (resp_connection_status == 'UNSTABLE') {
|
|
connection_status.className = 'sign-text alert-warning'
|
|
connection_status.innerHTML = 'Ustabilt';
|
|
}
|
|
if (resp_connection_status == 'OFFLINE') {
|
|
connection_status.className = 'sign-text alert-danger'
|
|
connection_status.innerHTML = 'Offline';
|
|
}
|
|
}
|
|
|
|
async function update_chart()
|
|
{
|
|
if (!chartHasFetchedTimeRange) {
|
|
var response = await fetch('./?p=api_chart&limit_length=1000&scan_id=' + scanId + '&since=' + (Math.floor(Date.now() / 1000) - timeRangeInSeconds));
|
|
chartHasFetchedTimeRange = true;
|
|
} else {
|
|
var response = await fetch('./?p=api_chart&scan_id=' + scanId + '&since=' + chartLatest);
|
|
}
|
|
|
|
if (response.status === 204) {
|
|
return;
|
|
}
|
|
|
|
let jsonResponse = await response.json();
|
|
|
|
chartLatest = jsonResponse.latest;
|
|
|
|
jsonResponse.pings.forEach(ping => {
|
|
let newDate = new Date(ping.date_added + ' UTC');
|
|
chartPingSeries.push({ x: newDate.toString(), y: ping.ping_avg});
|
|
});
|
|
|
|
// remove old pings
|
|
for (let i = 0; i < chartPingSeries.length; i++) {
|
|
let pingEpoch = Math.floor((new Date(chartPingSeries[i].x)).getTime() / 1000);
|
|
if (pingEpoch < chartLatest - timeRangeInSeconds) {
|
|
chartPingSeries.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
jsonResponse.pings.forEach(ping => {
|
|
let newDate = new Date(ping.date_added + ' UTC');
|
|
if (ping.pkt_transmitted != ping.pkt_received) {
|
|
let pktLossPercentage = ping.pkt_received / ping.pkt_transmitted * 100;
|
|
pktLossPercentage = 100 - pktLossPercentage;
|
|
chartPacketLossSeries.push({ x: newDate.toString(), y: pktLossPercentage});
|
|
} else {
|
|
chartPacketLossSeries.push({ x: newDate.toString(), y: 0});
|
|
}
|
|
});
|
|
|
|
for (let i = 0; i < chartPacketLossSeries.length; i++) {
|
|
let pingEpoch = Math.floor((new Date(chartPacketLossSeries[i].x)).getTime() / 1000);
|
|
if (pingEpoch < chartLatest - timeRangeInSeconds) {
|
|
chartPacketLossSeries.splice(i, 1);
|
|
}
|
|
}
|
|
|
|
chartElement.updateSeries([
|
|
{
|
|
name: 'Ping',
|
|
data: chartPingSeries
|
|
},
|
|
{
|
|
name: 'Pakke Tap',
|
|
data: chartPacketLossSeries
|
|
}
|
|
]);
|
|
} |