diff --git a/DnsServerCore/www/js/logs.js b/DnsServerCore/www/js/logs.js new file mode 100644 index 00000000..de8b366e --- /dev/null +++ b/DnsServerCore/www/js/logs.js @@ -0,0 +1,392 @@ +/* +Technitium DNS Server +Copyright (C) 2021 Shreyas Zare (shreyas@technitium.com) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +*/ + +$(function () { + $('#dtpQueryLogStart').datetimepicker({ format: "YYYY-MM-DD HH:mm:ss" }); + $('#dtpQueryLogEnd').datetimepicker({ format: "YYYY-MM-DD HH:mm:ss" }); + + $("#optQueryLogsAppName").change(function () { + if (appsList == null) + return; + + var appName = $("#optQueryLogsAppName").val(); + var optClassPaths = ""; + + for (var i = 0; i < appsList.length; i++) { + if (appsList[i].name == appName) { + for (var j = 0; j < appsList[i].loggers.length; j++) { + optClassPaths += ""; + } + } + } + + $("#optQueryLogsClassPath").html(optClassPaths); + $("#txtAddEditRecordDataData").val(""); + }); +}); + +function refreshLogsTab() { + if ($("#logsTabListLogViewer").hasClass("active")) + refreshLogFilesList(); + else if ($("#logsTabListQueryLogs").hasClass("active")) + refreshQueryLogsTab(); +} + +function refreshLogFilesList() { + var lstLogFiles = $("#lstLogFiles"); + + HTTPRequest({ + url: "/api/listLogs?token=" + token, + success: function (responseJSON) { + var logFiles = responseJSON.response.logFiles; + + var list = "
[delete all stats]
"; + + if (logFiles.length == 0) { + list += "
No Log Was Found
"; + } + else { + list += "
[delete all logs]
"; + + for (var i = 0; i < logFiles.length; i++) { + var logFile = logFiles[i]; + + list += "
" + logFile.fileName + " [" + logFile.size + "]
" + } + } + + lstLogFiles.html(list); + }, + invalidToken: function () { + showPageLogin(); + }, + objLoaderPlaceholder: lstLogFiles + }); + + return false; +} + +function viewLog(logFile) { + var divLogViewer = $("#divLogViewer"); + var txtLogViewerTitle = $("#txtLogViewerTitle"); + var divLogViewerLoader = $("#divLogViewerLoader"); + var preLogViewerBody = $("#preLogViewerBody"); + + txtLogViewerTitle.text(logFile); + + preLogViewerBody.hide(); + divLogViewerLoader.show(); + divLogViewer.show(); + + HTTPGetFileRequest({ + url: "/log/" + logFile + "?limit=2&token=" + token, + success: function (response) { + + divLogViewerLoader.hide(); + + preLogViewerBody.text(response); + preLogViewerBody.show(); + }, + objLoaderPlaceholder: divLogViewerLoader + }); + + return false; +} + +function downloadLog() { + var logFile = $("#txtLogViewerTitle").text(); + + window.open("/log/" + logFile + "?token=" + token + "&ts=" + (new Date().getTime()), "_blank"); + + return false; +} + +function deleteLog() { + var logFile = $("#txtLogViewerTitle").text(); + + if (!confirm("Are you sure you want to permanently delete the log file '" + logFile + "'?")) + return false; + + var btn = $("#btnDeleteLog").button('loading'); + + HTTPRequest({ + url: "/api/deleteLog?token=" + token + "&log=" + logFile, + success: function (responseJSON) { + refreshLogFilesList(); + + $("#divLogViewer").hide(); + btn.button('reset'); + + showAlert("success", "Log Deleted!", "Log file was deleted successfully."); + }, + error: function () { + btn.button('reset'); + }, + invalidToken: function () { + btn.button('reset'); + showPageLogin(); + } + }); + + return false; +} + +function deleteAllLogs() { + if (!confirm("Are you sure you want to permanently delete all log files?")) + return false; + + HTTPRequest({ + url: "/api/deleteAllLogs?token=" + token, + success: function (responseJSON) { + refreshLogFilesList(); + + $("#divLogViewer").hide(); + + showAlert("success", "Logs Deleted!", "All log files were deleted successfully."); + }, + invalidToken: function () { + showPageLogin(); + } + }); + + return false; +} + +function deleteAllStats() { + if (!confirm("Are you sure you want to permanently delete all stats files?")) + return false; + + HTTPRequest({ + url: "/api/deleteAllStats?token=" + token, + success: function (responseJSON) { + showAlert("success", "Stats Deleted!", "All stats files were deleted successfully."); + }, + invalidToken: function () { + showPageLogin(); + } + }); + + return false; +} + +var appsList; + +function refreshQueryLogsTab() { + var frmQueryLogs = $("#frmQueryLogs"); + var divQueryLogsLoader = $("#divQueryLogsLoader"); + var tableQueryLogs = $("#tableQueryLogs"); + + var optQueryLogsAppName = $("#optQueryLogsAppName"); + var optQueryLogsClassPath = $("#optQueryLogsClassPath"); + + var currentAppName = optQueryLogsAppName.val(); + var currentClassPath = optQueryLogsClassPath.val(); + var loader; + + if (appsList == null) { + frmQueryLogs.hide(); + tableQueryLogs.hide(); + loader = divQueryLogsLoader; + } + else { + optQueryLogsAppName.prop('disabled', true); + optQueryLogsClassPath.prop('disabled', true); + } + + HTTPRequest({ + url: "/api/apps/list?token=" + token, + success: function (responseJSON) { + var apps = responseJSON.response.apps; + + var optApps = ""; + var optClassPaths = ""; + + for (var i = 0; i < apps.length; i++) { + if (apps[i].loggers.length > 0) { + optApps += ""; + + if (currentAppName == null) + currentAppName = apps[i].name; + } + } + + for (var i = 0; i < apps.length; i++) { + if (apps[i].name == currentAppName) { + for (var j = 0; j < apps[i].loggers.length; j++) { + optClassPaths += ""; + } + } + } + + optQueryLogsAppName.html(optApps); + optQueryLogsClassPath.html(optClassPaths); + + if (currentAppName != null) + optQueryLogsAppName.val(currentAppName); + + if (currentClassPath != null) + optQueryLogsClassPath.val(currentClassPath); + + if (appsList == null) { + frmQueryLogs.show(); + loader.hide(); + } + else { + optQueryLogsAppName.prop('disabled', false); + optQueryLogsClassPath.prop('disabled', false); + } + + appsList = apps; + }, + error: function () { + if (appsList == null) { + frmQueryLogs.show(); + tableQueryLogs.show(); + } + else { + optQueryLogsAppName.prop('disabled', false); + optQueryLogsClassPath.prop('disabled', false); + } + }, + invalidToken: function () { + showPageLogin(); + }, + objLoaderPlaceholder: loader + }); +} + +function queryLogs(pageNumber) { + var btn = $("#btnQueryLogs"); + var divQueryLogsLoader = $("#divQueryLogsLoader"); + var tableQueryLogs = $("#tableQueryLogs"); + + var name = $("#optQueryLogsAppName").val(); + if (name == null) { + showAlert("warning", "Missing!", "Please install a DNS App that does query logging to view its logged data here."); + $("#optQueryLogsAppName").focus(); + return false; + } + + var classPath = $("#optQueryLogsClassPath").val(); + if (classPath == null) { + showAlert("warning", "Missing!", "Please select a Class Path to query logs."); + $("#optQueryLogsClassPath").focus(); + return false; + } + + var entriesPerPage = $("#optQueryLogsEntriesPerPage").val(); + + var start = $("#txtQueryLogStart").val(); + if (start != "") + start = moment(start).format("YYYY-MM-DD HH:mm:ss"); + + var end = $("#txtQueryLogEnd").val(); + if (end != "") + end = moment(end).format("YYYY-MM-DD HH:mm:ss"); + + var clientIpAddress = $("#txtQueryLogClientIpAddress").val(); + var protocol = $("#optQueryLogsProtocol").val(); + var responseType = $("#optQueryLogsResponseType").val(); + var rcode = $("#optQueryLogsResponseCode").val(); + var qname = $("#txtQueryLogQName").val(); + var qtype = $("#optQueryLogQType").val(); + var qclass = $("#optQueryLogQClass").val(); + + tableQueryLogs.hide(); + divQueryLogsLoader.show(); + + btn.button('loading'); + + HTTPRequest({ + url: "/api/queryLogs?token=" + token + "&name=" + encodeURIComponent(name) + "&classPath=" + encodeURIComponent(classPath) + "&pageNumber=" + pageNumber + "&entriesPerPage=" + entriesPerPage + + "&start=" + encodeURIComponent(start) + "&end=" + encodeURIComponent(end) + "&clientIpAddress=" + encodeURIComponent(clientIpAddress) + "&protocol=" + protocol + "&responseType=" + responseType + "&rcode=" + rcode + + "&qname=" + encodeURIComponent(qname) + "&qtype=" + qtype + "&qclass=" + qclass, + success: function (responseJSON) { + var tableHtml = ""; + + for (var i = 0; i < responseJSON.response.entries.length; i++) { + tableHtml += "" + responseJSON.response.entries[i].rowNumber + "" + + moment(responseJSON.response.entries[i].timestamp).local().format("YYYY-MM-DD HH:mm:ss") + "" + + responseJSON.response.entries[i].clientIpAddress + "" + + responseJSON.response.entries[i].protocol + "" + + responseJSON.response.entries[i].responseType + "" + + responseJSON.response.entries[i].rcode + "" + + htmlEncode(responseJSON.response.entries[i].qname) + "" + + responseJSON.response.entries[i].qtype + "" + + responseJSON.response.entries[i].qclass + "" + + htmlEncode(responseJSON.response.entries[i].answer) + "" + } + + var paginationHtml = ""; + + if (responseJSON.response.pageNumber > 1) { + paginationHtml += "
  • «
  • "; + paginationHtml += "
  • "; + } + + var pageStart = responseJSON.response.pageNumber - 5; + if (pageStart < 1) + pageStart = 1; + + var pageEnd = pageStart + 9; + if (pageEnd > responseJSON.response.totalPages) { + var endDiff = pageEnd - responseJSON.response.totalPages; + pageEnd = responseJSON.response.totalPages; + + pageStart -= endDiff; + if (pageStart < 1) + pageStart = 1; + } + + for (var i = pageStart; i <= pageEnd; i++) { + if (i == responseJSON.response.pageNumber) + paginationHtml += "
  • " + i + "
  • "; + else + paginationHtml += "
  • " + i + "
  • "; + } + + if (responseJSON.response.pageNumber < responseJSON.response.totalPages) { + paginationHtml += "
  • "; + paginationHtml += "
  • »
  • "; + } + + $("#tableQueryLogsBody").html(tableHtml); + + if (responseJSON.response.entries.length > 0) + $("#tableQueryLogsFooterStatus").html(responseJSON.response.entries[0].rowNumber + "-" + responseJSON.response.entries[responseJSON.response.entries.length - 1].rowNumber + " (" + responseJSON.response.entries.length + ") of " + responseJSON.response.totalEntries + " logs"); + else + $("#tableQueryLogsFooterStatus").html("0 logs"); + + $("#tableQueryLogsFooterPagination").html(paginationHtml); + + btn.button('reset'); + divQueryLogsLoader.hide(); + tableQueryLogs.show(); + }, + error: function () { + btn.button('reset'); + }, + invalidToken: function () { + showPageLogin(); + }, + objLoaderPlaceholder: divQueryLogsLoader + }); + + return false; +} \ No newline at end of file