Files
bpfire/html/cgi-bin/logs.cgi/log.dat
Adolf Belka 284ebca057 log.dat: Fixes bug#12950 - adding apcupsd to system logs list
- Patch tested out on my production system that has apcupsd running on it. APCUPS was
   in the list of options in the system logs and entries from apcupsd were extracted
   correctly in the wui.

Fixes: Bug#12950
Tested-by: Adolf Belka <adolf.belka@ipfire.org>
Signed-off-by: Adolf Belka <adolf.belka@ipfire.org>
Reviewed-by: Michael Tremer <michael.tremer@ipfire.org>
2023-03-04 14:03:45 +00:00

466 lines
14 KiB
Perl

#!/usr/bin/perl
#
# SmoothWall CGIs
#
# This code is distributed under the terms of the GPL
#
# (c) The SmoothWall Team
#
# $Id: log.dat,v 1.6.2.22 2006/01/03 12:47:17 franck78 Exp $
#
use strict;
# enable only the following on debugging purpose
use warnings;
use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my %color = ();
my %mainsettings = ();
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
use POSIX();
my %cgiparams=();
my %logsettings=();
my $errormessage = '';
my @shortmonths = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
'Sep', 'Oct', 'Nov', 'Dec' );
my @longmonths = ( $Lang::tr{'january'}, $Lang::tr{'february'}, $Lang::tr{'march'},
$Lang::tr{'april'}, $Lang::tr{'may'}, $Lang::tr{'june'}, $Lang::tr{'july'}, $Lang::tr{'august'},
$Lang::tr{'september'}, $Lang::tr{'october'}, $Lang::tr{'november'},
$Lang::tr{'december'} );
my @now = localtime();
my $dow = $now[6];
my $doy = $now[7];
my $tdoy = $now[7];
my $year = $now[5]+1900;
$cgiparams{'DAY'} = $now[3];
$cgiparams{'MONTH'} = $now[4];
$cgiparams{'ACTION'} = '';
$cgiparams{'SECTION'} = 'ipfire';
my %sections = (
'apcupsd' => '(apcupsd\[.*?\]: )',
'auth' => '(\w+\(pam_unix\)\[.*\]: )',
'wio' => '(wio:|wio\[.*\])',
'captive' => '(Captive:)',
'clamav' => '(clamd\[.*\]: |freshclam\[.*\]: )',
'collectd' => '(collectd\[.*\]: )',
'cron' => '(fcron\[.*\]: )',
'ddns' => '(ddns\[\d+\]:)',
'dhcp' => '(dhcpd: )',
'dma' => '(dma: |dma\[.*\]: |postfix/\w*\[\d*\]: )',
'guardian' => '(guardian\[.*\]: )',
'ipblocklist' => '(ipblocklist: )',
'ipfire' => '(ipfire: )',
'ipsec' => '(ipsec_[\w_]+: |pluto\[.*\]: |charon: |vpnwatch: )',
'kernel' => '(kernel: (?!DROP_))',
'monit' => '(monit\[.*?\]: )',
'ntp' => '(ntpd(?:ate)?\[.*\]: )',
'nut' => '(upsmon\[.*?\]: )',
'oinkmaster' => '(oinkmaster\[.*\]: )',
'openvpn' => '(openvpnserver\[.*\]: |.*n2n\[.*\]: )',
'pakfire' => '(pakfire:)',
'red' => '(red:|pppd\[.*\]: |chat\[.*\]|pppoe\[.*\]|pptp\[.*\]|pppoa\[.*\]|pppoa3\[.*\]|pppoeci\[.*\]|ipppd|ipppd\[.*\]|kernel: ippp\d|kernel: isdn.*|ibod\[.*\]|dhcpcd\[.*\]|modem_run\[.*\])',
'samba' => '(nmbd|smbd|winbind)\[\d+\]:',
'suricata' => '(suricata: )',
'squid' => '(squid\[.*\]: |squid: )',
'ssh' => '(sshd(?:\(.*\))?\[.*\]: )',
'unbound' => '(unbound: \[.*:.*\])(.*:.*$)',
'urlfilter bl' => '(installpackage\[urlfilter\]: )',
'wireless' => '(hostapd:|kernel: ath.*:|kernel: wifi[0-9]:)'
);
# Translations for the %sections array.
my %trsections = (
'apcupsd' => 'APCUPS',
'auth' => "$Lang::tr{'loginlogout'}",
'wio' => 'Who Is Online?',
'captive' => $Lang::tr{'Captive'},
'clamav' => 'ClamAV',
'collectd' => 'Collectd',
'cron' => 'Cron',
'ddns' => "$Lang::tr{'dynamic dns'}",
'dhcp' => "$Lang::tr{'dhcp server'}",
'dma' => 'Mail',
'guardian' => "$Lang::tr{'guardian'}",
'ipblocklist' => "$Lang::tr{'ipblocklist'}",
'ipfire' => 'IPFire',
'ipsec' => 'IPSec',
'kernel' => "$Lang::tr{'kernel'}",
'monit' => 'Monit',
'ntp' => 'NTP',
'nut' => 'NUT',
'oinkmaster' => 'Oinkmaster',
'openvpn' => 'OpenVPN',
'pakfire' => 'Pakfire',
'red' => 'RED',
'samba' => $Lang::tr{'samba'},
'suricata' => "$Lang::tr{'intrusion detection'}",
'squid' => "$Lang::tr{'web proxy'}",
'ssh' => 'SSH',
'unbound' => 'DNS: Unbound',
'urlfilter bl' => 'URLFilter Blacklist',
'wireless' => 'Wireless'
);
&Header::getcgihash(\%cgiparams);
$logsettings{'LOGVIEW_REVERSE'} = 'off';
&General::readhash("${General::swroot}/logging/settings", \%logsettings);
${Header::viewsize} = defined ($logsettings{'LOGVIEW_VIEWSIZE'}) ? $logsettings{'LOGVIEW_VIEWSIZE'} : 150;
my $start = ($logsettings{'LOGVIEW_REVERSE'} eq 'on') ? 0x7FFFF000 : 0; #index of firts line number to display
if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'})
{
my @temp = split(',',$ENV{'QUERY_STRING'});
$start = $temp[0];
$cgiparams{'MONTH'} = $temp[1];
$cgiparams{'DAY'} = $temp[2];
$cgiparams{'SECTION'} = $temp[3];
}
if (!($cgiparams{'MONTH'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) ||
!($cgiparams{'DAY'} =~ /^(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)$/))
{
$cgiparams{'DAY'} = $now[3];
$cgiparams{'MONTH'} = $now[4];
}
elsif($cgiparams{'ACTION'} eq '>>')
{
my @temp_then=();
my @temp_now = localtime(time);
$temp_now[4] = $cgiparams{'MONTH'};
$temp_now[3] = $cgiparams{'DAY'};
if ($cgiparams{'DAY'}) {
@temp_then = localtime(POSIX::mktime(@temp_now) + 86400);
## Retrieve the same time on the next day +
## 86400 seconds in a day
} else {
$temp_now[3] = 1;
$temp_now[4] = ($temp_now[4]+1) %12;
@temp_then = localtime(POSIX::mktime(@temp_now) );
$temp_then[3] = 0;
}
$cgiparams{'MONTH'} = $temp_then[4];
$cgiparams{'DAY'} = $temp_then[3];
}
elsif($cgiparams{'ACTION'} eq '<<')
{
my @temp_then=();
my @temp_now = localtime(time);
$temp_now[4] = $cgiparams{'MONTH'};
$temp_now[3] = $cgiparams{'DAY'};
if ($cgiparams{'DAY'}) {
@temp_then = localtime(POSIX::mktime(@temp_now) - 86400);
## Retrieve the same time on the next day -
## 86400 seconds in a day
} else {
$temp_now[3] = 1;
$temp_now[4] = ($temp_now[4]-1) %12;
@temp_then = localtime(POSIX::mktime(@temp_now) );
$temp_then[3] = 0;
}
$cgiparams{'MONTH'} = $temp_then[4];
$cgiparams{'DAY'} = $temp_then[3];
}
# Find in which file.gz is the log. Can be calculated because WEEKLY ROTATING of access.log
my $gzindex;
my $date = $cgiparams{'DAY'} == 0 ? '' : $cgiparams{'DAY'} <= 9 ? "0$cgiparams{'DAY'}" : "$cgiparams{'DAY'}";
{
my $xday;
# Calculate time. If future date, calculate for past year !!!
if (( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) ||
( $cgiparams{'MONTH'} > $now[4] ) ) {
$xday = POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1901 );
$date = "$longmonths[$cgiparams{'MONTH'}] $date, ". int($year-1);
} else {
$xday = POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'MONTH'}, $year - 1900 );
$date = "$longmonths[$cgiparams{'MONTH'}] $date, $year";
}
# calculate end of active week (saturday 23H59)
my @then = ();
@then = localtime(time());
my $sunday = POSIX::mktime( 0, 0, 0, $then[3], $then[4], $then[5]);
$sunday += (6-$then[6]) * 86400;
# Convert delta in second to full weeks
$gzindex = int (($sunday-$xday)/604800 );
}
my $monthstr = $shortmonths[$cgiparams{'MONTH'}];
my $daystr = $cgiparams{'DAY'} == 0 ? '..' : $cgiparams{'DAY'} <= 9 ? " $cgiparams{'DAY'}" : "$cgiparams{'DAY'}";
my $section = $sections{$cgiparams{'SECTION'}};
my $lines = 0;
my @log=();
my $loop = 1;
my $filestr = 0;
my $lastdatetime; # for debug
my $search_for_end = 0;
while ($gzindex >=0 && $loop) {
# calculate file name
if ($gzindex == 0) {
$filestr = "/var/log/messages";
$filestr = "/var/log/mail" if (${section} =~ 'dma');
} else {
$filestr = "/var/log/messages.$gzindex";
$filestr = "/var/log/mail.$gzindex" if (${section} =~ 'dma');
$filestr = "$filestr.gz" if -f "$filestr.gz";
}
# now read file if existing
if (open (FILE,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr))) {
#&General::log("reading $filestr");
READ:while (<FILE>) {
my $line = $_;
if ($line =~ /^${monthstr} ${daystr} ..:..:.. [\w\-]+ ${section}(.*)/) {
# when standard viewing, just keep in memory the correct slice
# it starts a '$start' and size is $viewport
# If export, then keep all lines...
if ($cgiparams{'ACTION'} eq $Lang::tr{'export'}){
$log[$lines++] = "$line";
} else {
if ($lines++ < ($start + $Header::viewsize)) {
push(@log,"$line");
if (@log > $Header::viewsize) {
shift (@log);
}
#} else { don't do this optimisation, need to count lines !
# $datetime = $maxtime; # we have read viewsize lines, stop main loop
# last READ; # exit read file
}
}
$search_for_end = 1; # we find the start of slice, can look for end now
} else {
if ($search_for_end == 1) {
#finish read files when date is over (test month equality only)
$line =~ /^(...) (..) ..:..:..*$/;
$loop = 0 if ( ($1 ne $monthstr) || ( ($daystr ne '..') && ($daystr ne $2) ) );
}
}
}
close (FILE);
}
$gzindex--; # will try next gz file eg 40,39,38,.... because it may have holes when ipcop stopped
# for a long time
}# while
# $errormessage = "$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}";
if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
{
print "Content-type: text/plain\n\n";
print "IPFire diagnostics\r\n";
print "$Lang::tr{'section'}: $cgiparams{'SECTION'}\n";
print "$Lang::tr{'date'}: $date\r\n\r\n";
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }
foreach $_ (@log)
{
/^... (..) (..:..:..) [\w\-]+ ${section}(.*)$/;
my $day = $1;
$day =~ tr / /0/;
my $time = $cgiparams{'DAY'} ? "$2" : "$day/$2" ;
print "$time $3 $4\r\n";
}
exit 0;
}
&Header::showhttpheaders();
&Header::openpage($Lang::tr{'system logs'}, 1, '');
&Header::openbigbox('100%', 'left', '', $errormessage);
if ($errormessage) {
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
print "<font class='base'>$errormessage&nbsp;</font>\n";
&Header::closebox();
}
&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:");
print <<END
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
<table width='100%'>
<tr>
<td width='10%' class='base'>$Lang::tr{'section'}:&nbsp;</td>
<td width='20%'>
<select name='SECTION'>
END
;
foreach $section (sort {$trsections{$a} cmp $trsections{$b}} keys %sections) {
print "\t<option ";
if ($section eq $cgiparams{'SECTION'}) {
print "selected='selected' "; }
print "value='$section'>$trsections{$section}</option>\n";
}
print <<END
</select>
</td>
<td width='10%' class='base' align='right'>$Lang::tr{'month'}:&nbsp;</td>
<td width='10%'>
<select name='MONTH'>
END
;
for (my $month = 0; $month < 12; $month++)
{
print "\t<option ";
if ($month == $cgiparams{'MONTH'}) {
print "selected='selected' "; }
print "value='$month'>$longmonths[$month]</option>\n";
}
print <<END
</select>
</td>
<td width='10%' class='base' align='right'>&nbsp;$Lang::tr{'day'}:&nbsp;</td>
<td width='40%'>
<select name='DAY'>
END
;
print "<option value='0'>$Lang::tr{'all'}</option>\n";
for (my $day = 1; $day <= 31; $day++)
{
print "\t<option ";
if ($day == $cgiparams{'DAY'}) {
print "selected='selected' "; }
print "value='$day'>$day</option>\n";
}
print <<END
</select>
</td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day before'}' value='&lt;&lt;' /></td>
<td width='5%' align='center'><input type='submit' name='ACTION' title='$Lang::tr{'day after'}' value='&gt;&gt;' /></td>
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
<td width='10%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'export'}' /></td>
</tr>
</table>
</form>
END
;
&Header::closebox();
&Header::openbox('100%', 'left', $Lang::tr{'log'});
print "<p><b>$Lang::tr{'total hits for log section'} $cgiparams{'SECTION'} $date: $lines</b></p>";
$start = $lines - ${Header::viewsize} if ($start >= $lines - ${Header::viewsize});
$start = 0 if ($start < 0);
my $prev;
if ($start == 0) {
$prev = -1;
} else {
$prev = $start - ${Header::viewsize};
$prev = 0 if ( $prev < 0);
}
my $next;
if ($start == $lines - ${Header::viewsize}) {
$next = -1;
} else {
$next = $start + ${Header::viewsize};
$next = $lines - ${Header::viewsize} if ($next >= $lines - ${Header::viewsize});
}
if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log = reverse @log; }
if ($lines != 0) { &oldernewer(); }
print <<END
<table width='100%' class='tbl'>
<tr>
<th width='10%' align='center' class='boldbase'><b>$Lang::tr{'time'}</b></th>
<th width='15%' align='center' class='boldbase'><b>$Lang::tr{'section'}</b></th>
<th width='75%'>&nbsp;</th>
</tr>
END
;
$lines = 0;
#print '<tt>';
foreach $_ (@log)
{
/^... (..) (..:..:..) [\w\-]+ ${section}(.*)$/;
my $day = $1;
$day =~ tr / /0/;
my $time = $cgiparams{'DAY'} ? "$2" : "$day/$2" ;
my $sec = $3;
my $data = $4;
# correct the cut position, just when section=RED
if (($cgiparams{'SECTION'} eq 'red' ) && ($sec =~ /(kernel:)(.*)/)) {
$sec = 'kernel';
$data = $2.': '.$data;
}
my $d = substr ($data,0,80);
while (length($data)>80){ #very basic breaking of lines...
$data = substr ($data,80); #permit correct display in table cell
$d .= ' ' . substr ($data,0,80);
}
my $col="";
if ($lines % 2) {
print "<tr>";
$col="bgcolor='$color{'color20'}'"; }
else {
print "<tr>";
$col="bgcolor='$color{'color22'}'"; }
print "<td $col>$time<td $col>$sec<td $col>" .&Header::cleanhtml ("$d", 'y') . "</td></tr>\n";
$lines++;
}
#print '</tt>';
print "</table>";
&oldernewer();
&Header::closebox();
&Header::closebigbox();
&Header::closepage();
sub oldernewer
{
print <<END
<table width='100%'>
<tr>
END
;
print "<td align='center' width='50%'>";
if ($prev != -1) {
print "<a href='/cgi-bin/logs.cgi/log.dat?$prev,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{'SECTION'}'>$Lang::tr{'older'}</a>"; }
else {
print "$Lang::tr{'older'}"; }
print "</td>\n";
print "<td align='center' width='50%'>";
if ($next >= 0) {
print "<a href='/cgi-bin/logs.cgi/log.dat?$next,$cgiparams{'MONTH'},$cgiparams{'DAY'},$cgiparams{'SECTION'}'>$Lang::tr{'newer'}</a>"; }
else {
print "$Lang::tr{'newer'}"; }
print "</td>\n";
print <<END
</tr>
</table>
END
;
}