Merge pull request #108 from richard-underwood/issue-107

Ability to rotate and search logs
This commit is contained in:
Tuxis Internet Engineering V.O.F 2016-09-13 11:10:22 +02:00 committed by GitHub
commit b16af25052
5 changed files with 215 additions and 55 deletions

View file

@ -7,7 +7,12 @@ $apiproto = 'http'; # http | https
$apisslverify = FALSE; # Verify SSL Certificate if using https for apiproto
$allowzoneadd = FALSE; # Allow normal users to add zones
$logging = TRUE;
$allowclearlogs = TRUE; # Allow clearing of log entries
$allowrotatelogs = FALSE;# Allow rotation to text file on server
# Log directory - if allowrotatelogs is set, this is where the logs will
# be written. It must be writeable by the web server user.
$logsdirectory = "../etc";
# If you configure this, nsedit will try to authenticate via WeFact too.
# Debtors will be added to the sqlitedatabase with their crypted password.

View file

@ -276,6 +276,58 @@ function clearlogs() {
writelog("Logtable truncated.");
}
function rotatelogs() {
global $logging, $logsdirectory;
if ($logging !== TRUE)
return FALSE;
if(!is_dir($logsdirectory) || !is_writable($logsdirectory)) {
writelog("Logs directory cannot be written to.");
return FALSE;
}
date_default_timezone_set('UTC');
$filename = date("Y-m-d-His") . ".json";
$file = fopen($logsdirectory . "/" . $filename, "x");
if($file === FALSE) {
writelog("Can't create file for log rotation.");
return FALSE;
}
if(fwrite($file,json_encode(getlogs())) === FALSE) {
writelog("Can't write to file for log rotation.");
fclose($file);
return FALSE;
} else {
fclose($file);
clearlogs();
return $filename;
}
}
function listrotatedlogs() {
global $logging, $logsdirectory;
if ($logging !== TRUE)
return FALSE;
$list = scandir($logsdirectory,SCANDIR_SORT_DESCENDING);
if($list === FALSE) {
writelog("Logs directory cannot read.");
return FALSE;
}
$list=array_filter($list,
function ($val) {
return(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$val) == 1);
}
);
return $list;
}
function writelog($line, $user=False) {
global $logging;
if ($logging !== TRUE)

View file

@ -114,7 +114,12 @@ if ($blocklogin === TRUE) {
<div id="dnssecinfo">
</div>
<div id="clearlogs" style="display: none;">
Are you sure you want to clear all the logs? Maybe save them first?
Are you sure you want to clear the current logs? Maybe download them
first<?php if($allowrotatelogs) { ?>, or use "Rotate logs" to save
them on the server<?php } ?>?
</div>
<div id="rotatelogs" style="display: none;">
Are you sure you want to rotate the current logs?
</div>
<div id="searchlogs" style="display: none; text-align: right;">
<table border="0">
@ -184,6 +189,21 @@ if ($blocklogin === TRUE) {
</div>
<div id="logs">
<div class="tables" id="Logs"></div>
<?php if($allowrotatelogs) { ?>
<br>Log entries being viewed:
<select id="logfile">
<option value="">(Current logs)</option>
<?php
$logfiles=listrotatedlogs();
if($logfiles !== FALSE) {
foreach ($logfiles as $filename) {
echo '<option value="' . $filename . '">' . str_replace(".json","",$filename) . "</option>\n";
}
}
?></select>
<?php } else { ?>
<input type="hidden" id="logfile" value="">
<?php } ?>
</div>
<?php } ?>
@ -920,18 +940,18 @@ $(document).ready(function () {
});
<?php if (is_adminuser()) { ?>
$('#Logs').hide();
$('#logs').hide();
$('#Users').hide();
$('#AboutMe').hide();
$('#aboutme').click(function () {
$('#Logs').hide();
$('#logs').hide();
$('#Users').hide();
$('#MasterZones').hide();
$('#SlaveZones').hide();
$('#AboutMe').show();
});
$('#useradmin').click(function () {
$('#Logs').hide();
$('#logs').hide();
$('#MasterZones').hide();
$('#SlaveZones').hide();
$('#AboutMe').hide();
@ -939,7 +959,7 @@ $(document).ready(function () {
$('#Users').show();
});
$('#zoneadmin').click(function () {
$('#Logs').hide();
$('#logs').hide();
$('#Users').hide();
$('#AboutMe').hide();
$('#MasterZones').show();
@ -950,8 +970,10 @@ $(document).ready(function () {
$('#AboutMe').hide();
$('#MasterZones').hide();
$('#SlaveZones').hide();
$('#Logs').jtable('load');
$('#Logs').show();
$('#Logs').jtable('load', {
logfile: $('#logfile').val()
});
$('#logs').show();
});
$('#Users').jtable({
title: 'Users',
@ -1004,8 +1026,7 @@ $(document).ready(function () {
pageSize: 20,
sorting: false,
actions: {
listAction: 'logs.php?action=list',
deleteAction: 'logs.php?action=delete',
listAction: 'logs.php?action=list'
},
messages: {
deleteConfirmation: 'This entry will be deleted. Are you sure?'
@ -1027,6 +1048,7 @@ $(document).ready(function () {
$( this ).dialog( 'close' );
$('#Logs').find('.jtable-title-text').text('Logs (filtered)');
$('#Logs').jtable('load', {
logfile: $('#logfile').val(),
user: $('#searchlogs-user').val(),
entry: $('#searchlogs-entry').val()
});
@ -1036,13 +1058,40 @@ $(document).ready(function () {
$('#searchlogs-entry').val('');
$( this ).dialog( 'close' );
$('#Logs').find('.jtable-title-text').text('Logs');
$('#Logs').jtable('load');
$('#Logs').jtable('load', {
logfile: $('#logfile').val()
});
return false;
}
}
});
}
},
<?php if($allowrotatelogs === TRUE) { ?>
{
text: 'Rotate logs',
click: function() {
$("#rotatelogs").dialog({
modal: true,
title: "Rotate logs",
width: 'auto',
buttons: {
Ok: function() {
$.get("logs.php?action=rotate");
$( this ).dialog( "close" );
$('#logfile').val('');
$('#Logs').jtable('load');
},
Cancel: function() {
$( this ).dialog( "close" );
return false;
}
}
});
}
},
<?php } ?>
<?php if($allowclearlogs === TRUE) { ?>
{
icon: 'img/delete_inverted.png',
text: 'Clear logs',
@ -1055,6 +1104,7 @@ $(document).ready(function () {
Ok: function() {
$.get("logs.php?action=clear");
$( this ).dialog( "close" );
$('#logfile').val('');
$('#Logs').jtable('load');
},
Cancel: function() {
@ -1065,17 +1115,18 @@ $(document).ready(function () {
});
}
},
<?php } ?>
{
icon: 'img/export.png',
text: 'Save logs',
text: 'Download logs',
click: function () {
var $zexport = $.get("logs.php?action=export", function(data) {
var $zexport = $.get("logs.php?action=export&logfile=" + $('#logfile').val(), function(data) {
console.log(data);
blob = new Blob([data], { type: 'text/plain' });
var dl = document.createElement('a');
dl.addEventListener('click', function(ev) {
dl.href = URL.createObjectURL(blob);
dl.download = 'nseditlogs.txt';
dl.download = $('#logfile').val() == "" ? 'nseditlogs.txt':$('#logfile').val() + ".txt";
}, false);
if (document.createEvent) {
@ -1111,6 +1162,15 @@ $(document).ready(function () {
}
}
});
$('#logfile').change(function () {
$('#Logs').jtable('load', {
logfile: $('#logfile').val(),
user: $('#searchlogs-user').val(),
entry: $('#searchlogs-entry').val()
});
});
<?php } ?>
$('#MasterZones').jtable('load');
$('#SlaveZones').jtable('load');

View file

@ -20,14 +20,22 @@ if (!isset($_GET['action'])) {
jtable_respond(null, 'error', 'No action given');
}
if ($logging !== TRUE) {
jtable_respond(null, 'error', 'Logging is disabled');
} else {
switch ($_GET['action']) {
case "list":
global $logging;
if ($logging !== TRUE)
jtable_respond(null, 'error', 'Logging is disabled');
if(!empty($_POST['logfile'])) {
if(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$_POST['logfile']) == 1) {
$entries=json_decode(file_get_contents($logsdirectory . "/" . $_POST['logfile']),true);
} else {
jtable_respond(null, 'error', "Can't find log file");
break;
}
} else {
$entries=getlogs();
}
if(!empty($_POST['user'])) {
$entries=array_filter($entries,
@ -48,22 +56,41 @@ case "list":
jtable_respond($entries);
break;
case "delete":
if ($emailaddress != '' and delete_user($emailaddress) !== FALSE) {
jtable_respond(null, 'delete');
case "export":
if(!empty($_GET['logfile'])) {
if(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$_GET['logfile']) == 1) {
$entries=json_decode(file_get_contents($logsdirectory . "/" . $_GET['logfile']),true);
} else {
jtable_respond(null, 'error', 'Could not delete user');
jtable_respond(null, 'error', "Can't find log file");
break;
}
} else {
$entries=getlogs();
}
if(defined('JSON_PRETTY_PRINT')) {
print json_encode($entries,JSON_PRETTY_PRINT);
} else {
print json_encode($entries);
}
break;
case "export":
print json_encode(getlogs());
break;
case "clear":
if($allowclearlogs === TRUE) {
clearlogs();
} else {
jtable_respond(null, 'error', 'Invalid action');
}
break;
case "rotate":
if($allowrotatelogs === TRUE) {
rotatelogs();
} else {
jtable_respond(null, 'error', 'Invalid action');
}
break;
default:
jtable_respond(null, 'error', 'Invalid action');
break;
}
}

16
rotate-logs.php Normal file
View file

@ -0,0 +1,16 @@
<?php
include_once('includes/config.inc.php');
include_once('includes/session.inc.php');
include_once('includes/misc.inc.php');
if(php_sapi_name() !== 'cli') {
echo "This script is intended to be run from the command line";
} else {
if($allowrotatelogs === TRUE) {
$current_user['username']='<system>';
rotatelogs();
} else {
echo "Rotating logs has been disabled."
}
}