mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2026-01-07 17:24:02 +00:00
webapp: implemented dashboard.
This commit is contained in:
@@ -202,3 +202,65 @@ label {
|
||||
width: 84%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.stats-panel {
|
||||
height: 100px;
|
||||
padding: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
.stats-panel .total-queries {
|
||||
background-color: rgba(102, 153, 255, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .no-error {
|
||||
background-color: rgba(92, 184, 92, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .server-failure {
|
||||
background-color: rgba(217, 83, 79, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .name-error {
|
||||
background-color: rgba(7, 7, 7, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .refused {
|
||||
background-color: rgba(91, 192, 222, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .blocked {
|
||||
background-color: rgba(255, 165, 0, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .clients {
|
||||
background-color: rgba(51, 122, 183, 0.7);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.stats-panel .stats-item {
|
||||
width: 150px;
|
||||
float: left;
|
||||
padding: 10px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.stats-panel .stats-item .number {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.stats-panel .stats-item .percentage {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.stats-panel .stats-item .title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!--<link href="/css/bootstrap-theme.min.css" rel="stylesheet">-->
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/Chart.min.js"></script>
|
||||
|
||||
<link href="/css/font-awesome.min.css" rel="stylesheet" />
|
||||
|
||||
@@ -87,17 +88,160 @@
|
||||
|
||||
<div>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li id="mainPanelTabListZones" role="presentation" class="active"><a href="#mainPanelTabPaneZones" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return refreshZonesList();">Zones</a></li>
|
||||
<li id="mainPanelTabListDashboard" role="presentation" class="active"><a href="#mainPanelTabPaneDashboard" aria-controls="mainPanelTabPaneDashboard" role="tab" data-toggle="tab" onclick="return refreshDashboard();">Dashboard</a></li>
|
||||
<li id="mainPanelTabListZones" role="presentation"><a href="#mainPanelTabPaneZones" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return refreshZonesList();">Zones</a></li>
|
||||
<li id="mainPanelTabListCachedZones" role="presentation"><a href="#mainPanelTabPaneCachedZones" aria-controls="mainPanelTabPaneCachedZones" role="tab" data-toggle="tab" onclick="return false;">Cached Zones</a></li>
|
||||
<li id="mainPanelTabListBlockedZones" role="presentation"><a href="#mainPanelTabPaneBlockedZones" aria-controls="mainPanelTabPaneBlockedZones" role="tab" data-toggle="tab" onclick="return false;">Blocked Zones</a></li>
|
||||
<li id="mainPanelTabListDnsClient" role="presentation"><a href="#mainPanelTabPaneDnsClient" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return false;">DNS Client</a></li>
|
||||
<li id="mainPanelTabListDnsClient" role="presentation"><a href="#mainPanelTabPaneDnsClient" aria-controls="mainPanelTabPaneDnsClient" role="tab" data-toggle="tab" onclick="return false;">DNS Client</a></li>
|
||||
<li id="mainPanelTabListSettings" role="presentation"><a href="#mainPanelTabPaneSettings" aria-controls="mainPanelTabPaneSettings" role="tab" data-toggle="tab" onclick="return loadDnsSettings();">Settings</a></li>
|
||||
<li id="mainPanelTabListLogs" role="presentation"><a href="#mainPanelTabPaneLogs" aria-controls="mainPanelTabPaneLogs" role="tab" data-toggle="tab" onclick="return refreshLogFilesList();">Logs</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="mainPanelTabPaneZones" role="tabpanel" class="tab-pane active" style="padding: 10px 0 0 0;">
|
||||
<div id="mainPanelTabPaneDashboard" role="tabpanel" class="tab-pane active" style="padding: 10px 0 0 0;">
|
||||
<div id="divDashboardLoader" style="margin-top: 10px; height: 400px;"></div>
|
||||
|
||||
<div id="divDashboard" style="display: none;">
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-default active">
|
||||
<input type="radio" name="optStatMode" id="optLastHour" autocomplete="off" checked> Last Hour
|
||||
</label>
|
||||
<label class="btn btn-default">
|
||||
<input type="radio" name="optStatMode" id="optLastDay" autocomplete="off"> Last Day
|
||||
</label>
|
||||
<label class="btn btn-default">
|
||||
<input type="radio" name="optStatMode" id="optLastWeek" autocomplete="off"> Last Week
|
||||
</label>
|
||||
<label class="btn btn-default">
|
||||
<input type="radio" name="optStatMode" id="optLastMonth" autocomplete="off"> Last Month
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="stats-panel">
|
||||
<div class="stats-item total-queries">
|
||||
<div class="number" id="divDashboardStatsTotalQueries">100</div>
|
||||
<div class="percentage">100%</div>
|
||||
<div class="title">Total Queries</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item no-error">
|
||||
<div class="number" id="divDashboardStatsTotalNoError">70</div>
|
||||
<div class="percentage" id="divDashboardStatsTotalNoErrorPercentage">0%</div>
|
||||
<div class="title">No Error</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item server-failure">
|
||||
<div class="number" id="divDashboardStatsTotalServerFailure">5</div>
|
||||
<div class="percentage" id="divDashboardStatsTotalServerFailurePercentage">0%</div>
|
||||
<div class="title">Server Failure</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item name-error">
|
||||
<div class="number" id="divDashboardStatsTotalNameError">5</div>
|
||||
<div class="percentage" id="divDashboardStatsTotalNameErrorPercentage">0%</div>
|
||||
<div class="title">Name Error</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item refused">
|
||||
<div class="number" id="divDashboardStatsTotalRefused">10</div>
|
||||
<div class="percentage" id="divDashboardStatsTotalRefusedPercentage">0%</div>
|
||||
<div class="title">Refused</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item blocked">
|
||||
<div class="number" id="divDashboardStatsTotalBlocked">10</div>
|
||||
<div class="percentage" id="divDashboardStatsTotalBlockedPercentage">0%</div>
|
||||
<div class="title">Blocked</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-item clients">
|
||||
<div class="number" id="divDashboardStatsTotalClients">10</div>
|
||||
<div class="percentage"> </div>
|
||||
<div class="title">Clients</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<canvas id="canvasDashboardMain" style="margin: 10px 0 10px 0;"></canvas>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<div class="panel panel-default" style="float: left; width: 547px; margin-bottom: 0px;">
|
||||
<div class="panel-heading">Top Query Type</div>
|
||||
<div class="panel-body">
|
||||
<canvas id="canvasDashboardPie"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default" style="float: right; width: 547px; margin-bottom: 0px;">
|
||||
<div class="panel-heading">Top Clients</div>
|
||||
<table class="table table-hover" id="tableTopClients">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Client</th>
|
||||
<th>Queries</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>127.0.0.1</td>
|
||||
<td>100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>::1</td>
|
||||
<td>10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<div class="panel panel-default" style="float: left; width: 547px; margin-bottom: 0px;">
|
||||
<div class="panel-heading">Top Domains</div>
|
||||
<table class="table table-hover" id="tableTopDomains">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th>Hits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>example.com</td>
|
||||
<td>10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default" style="float: right; width: 547px; margin-bottom: 0px;">
|
||||
<div class="panel-heading">Top Blocked Domains</div>
|
||||
<table class="table table-hover" id="tableTopBlockedDomains">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th>Hits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>blocked.example.com</td>
|
||||
<td>10</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mainPanelTabPaneZones" role="tabpanel" class="tab-pane" style="padding: 10px 0 0 0;">
|
||||
|
||||
<div class="well well-sm zone-list-pane">
|
||||
<form class="form-inline">
|
||||
@@ -763,9 +907,9 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin-bottom: 0px;">
|
||||
<button id="btnSaveDnsSettings" type="button" class="btn btn-primary" data-loading-text="Saving..." onclick="return saveDnsSettings();" style="margin-right: 6px;">Save Settings</button>
|
||||
<button id="btnFlushDnsCache" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushDnsCache();">Flush Cache</button>
|
||||
<button id="btnFlushBlockedZone" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushBlockedZone();">Flush Blocked Zone</button>
|
||||
<button id="btnSaveDnsSettings" type="button" class="btn btn-primary" data-loading-text="Saving..." onclick="return saveDnsSettings();">Save Settings</button>
|
||||
<button id="btnFlushDnsCache" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushDnsCache();" style="margin-left: 6px;">Flush Cache</button>
|
||||
<button id="btnFlushBlockedZone" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushBlockedZone();" style="margin-left: 6px;">Flush Blocked Zone</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
10
DnsServerCore/www/js/Chart.min.js
vendored
Normal file
10
DnsServerCore/www/js/Chart.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
|
||||
var token = null;
|
||||
var refreshZonesTimerHandle;
|
||||
var refreshTimerHandle;
|
||||
|
||||
function showPageLogin() {
|
||||
hideAlert();
|
||||
@@ -15,9 +15,9 @@ function showPageLogin() {
|
||||
|
||||
$("#txtUser").focus();
|
||||
|
||||
if (refreshZonesTimerHandle != null) {
|
||||
clearInterval(refreshZonesTimerHandle);
|
||||
refreshZonesTimerHandle = null;
|
||||
if (refreshTimerHandle != null) {
|
||||
clearInterval(refreshTimerHandle);
|
||||
refreshTimerHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ function showPageMain(username) {
|
||||
|
||||
$(".nav-tabs li").removeClass("active");
|
||||
$(".tab-pane").removeClass("active");
|
||||
$("#mainPanelTabListZones").addClass("active");
|
||||
$("#mainPanelTabPaneZones").addClass("active");
|
||||
$("#mainPanelTabListDashboard").addClass("active");
|
||||
$("#mainPanelTabPaneDashboard").addClass("active");
|
||||
|
||||
$("#divZoneViewer").hide();
|
||||
|
||||
@@ -50,12 +50,16 @@ function showPageMain(username) {
|
||||
$("#pageMain").show();
|
||||
|
||||
loadDnsSettings();
|
||||
refreshDashboard();
|
||||
refreshZonesList();
|
||||
refreshCachedZonesList();
|
||||
refreshBlockedZonesList();
|
||||
checkForUpdate();
|
||||
|
||||
refreshZonesTimerHandle = setInterval(function () { refreshZonesList(true); }, 60000);
|
||||
refreshTimerHandle = setInterval(function () {
|
||||
refreshDashboard(true);
|
||||
refreshZonesList(true);
|
||||
}, 60000);
|
||||
}
|
||||
|
||||
$(function () {
|
||||
@@ -571,6 +575,164 @@ function saveDnsSettings() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function refreshDashboard(hideLoader) {
|
||||
|
||||
if (!$("#mainPanelTabPaneDashboard").hasClass("active"))
|
||||
return;
|
||||
|
||||
if (hideLoader == null)
|
||||
hideLoader = false;
|
||||
|
||||
var divDashboardLoader = $("#divDashboardLoader");
|
||||
var divDashboard = $("#divDashboard");
|
||||
|
||||
if (!hideLoader) {
|
||||
divDashboard.hide();
|
||||
divDashboardLoader.show();
|
||||
}
|
||||
|
||||
HTTPRequest({
|
||||
url: "/api/getStats?token=" + token,
|
||||
success: function (responseJSON) {
|
||||
|
||||
//stats
|
||||
$("#divDashboardStatsTotalQueries").text(responseJSON.response.stats.totalQueries);
|
||||
$("#divDashboardStatsTotalNoError").text(responseJSON.response.stats.totalNoError);
|
||||
$("#divDashboardStatsTotalServerFailure").text(responseJSON.response.stats.totalServerFailure);
|
||||
$("#divDashboardStatsTotalNameError").text(responseJSON.response.stats.totalNameError);
|
||||
$("#divDashboardStatsTotalRefused").text(responseJSON.response.stats.totalRefused);
|
||||
$("#divDashboardStatsTotalBlocked").text(responseJSON.response.stats.totalBlocked);
|
||||
$("#divDashboardStatsTotalClients").text(responseJSON.response.stats.totalClients);
|
||||
|
||||
if (responseJSON.response.stats.totalQueries > 0) {
|
||||
$("#divDashboardStatsTotalNoErrorPercentage").text((responseJSON.response.stats.totalNoError * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
|
||||
$("#divDashboardStatsTotalServerFailurePercentage").text((responseJSON.response.stats.totalServerFailure * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
|
||||
$("#divDashboardStatsTotalNameErrorPercentage").text((responseJSON.response.stats.totalNameError * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
|
||||
$("#divDashboardStatsTotalRefusedPercentage").text((responseJSON.response.stats.totalRefused * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
|
||||
$("#divDashboardStatsTotalBlockedPercentage").text((responseJSON.response.stats.totalBlocked * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
|
||||
}
|
||||
else {
|
||||
$("#divDashboardStatsTotalNoErrorPercentage").text("0%");
|
||||
$("#divDashboardStatsTotalServerFailurePercentage").text("0%");
|
||||
$("#divDashboardStatsTotalNameErrorPercentage").text("0%");
|
||||
$("#divDashboardStatsTotalRefusedPercentage").text("0%");
|
||||
$("#divDashboardStatsTotalBlockedPercentage").text("0%");
|
||||
}
|
||||
|
||||
//main chart
|
||||
if (window.chartDashboardMain == null) {
|
||||
var contextDashboardMain = document.getElementById("canvasDashboardMain").getContext('2d');
|
||||
|
||||
window.chartDashboardMain = new Chart(contextDashboardMain, {
|
||||
type: 'line',
|
||||
data: responseJSON.response.mainChartData,
|
||||
options: {
|
||||
elements: {
|
||||
line: {
|
||||
tension: .5,
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
window.chartDashboardMain.data = responseJSON.response.mainChartData;
|
||||
window.chartDashboardMain.update();
|
||||
}
|
||||
|
||||
//query type chart
|
||||
if (window.chartDashboardPie == null) {
|
||||
var contextDashboardPie = document.getElementById("canvasDashboardPie").getContext('2d');
|
||||
|
||||
window.chartDashboardPie = new Chart(contextDashboardPie, {
|
||||
type: 'doughnut',
|
||||
data: responseJSON.response.queryTypeChartData
|
||||
});
|
||||
}
|
||||
else {
|
||||
window.chartDashboardPie.data = responseJSON.response.queryTypeChartData;
|
||||
window.chartDashboardPie.update();
|
||||
}
|
||||
|
||||
//top clients
|
||||
{
|
||||
var tableHtml = "<thead><tr><th>Client</th><th>Queries</th></tr></thead><tbody>";
|
||||
var topClients = responseJSON.response.topClients;
|
||||
|
||||
if (topClients.length < 1) {
|
||||
tableHtml += "<tr><td>No Data</td><td></td></tr>";
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < topClients.length; i++) {
|
||||
tableHtml += "<tr><td>" + topClients[i].name + "</td><td>" + topClients[i].hits + "</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
tableHtml += "</tbody>";
|
||||
|
||||
$("#tableTopClients").html(tableHtml);
|
||||
}
|
||||
|
||||
//top domains
|
||||
{
|
||||
var tableHtml = "<thead><tr><th>Domain</th><th>Hits</th></tr></thead><tbody>";
|
||||
var topDomains = responseJSON.response.topDomains;
|
||||
|
||||
if (topDomains.length < 1) {
|
||||
tableHtml += "<tr><td>No Data</td><td></td></tr>";
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < topDomains.length; i++) {
|
||||
tableHtml += "<tr><td>" + topDomains[i].name + "</td><td>" + topDomains[i].hits + "</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
tableHtml += "</tbody>";
|
||||
|
||||
$("#tableTopDomains").html(tableHtml);
|
||||
}
|
||||
|
||||
//top blocked domains
|
||||
{
|
||||
var tableHtml = "<thead><tr><th>Domain</th><th>Hits</th></tr></thead><tbody>";
|
||||
var topBlockedDomains = responseJSON.response.topBlockedDomains;
|
||||
|
||||
if (topBlockedDomains.length < 1) {
|
||||
tableHtml += "<tr><td>No Data</td><td></td></tr>";
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < topBlockedDomains.length; i++) {
|
||||
tableHtml += "<tr><td>" + topBlockedDomains[i].name + "</td><td>" + topBlockedDomains[i].hits + "</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
tableHtml += "</tbody>";
|
||||
|
||||
$("#tableTopBlockedDomains").html(tableHtml);
|
||||
}
|
||||
|
||||
if (!hideLoader) {
|
||||
divDashboardLoader.hide();
|
||||
divDashboard.show();
|
||||
}
|
||||
},
|
||||
invalidToken: function () {
|
||||
showPageLogin();
|
||||
},
|
||||
objLoaderPlaceholder: divDashboardLoader,
|
||||
dontHideAlert: hideLoader
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function flushDnsCache() {
|
||||
|
||||
if (!confirm("Are you sure to flush the DNS Server cache?"))
|
||||
|
||||
Reference in New Issue
Block a user