From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robin Roevens To: development@lists.ipfire.org Subject: [PATCH 3/3] Add Zabbix Agent Logs viewer in WebGUI Date: Sun, 02 Apr 2023 13:07:11 +0200 Message-ID: <20230402110711.19593-4-robin.roevens@disroot.org> In-Reply-To: <20230402110711.19593-1-robin.roevens@disroot.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============4415836720766185888==" List-Id: --===============4415836720766185888== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable - Adds a simple logs viewer page logs.cgi/zabbix_agentd.dat, based on logs.cgi/logs.dat, to the Logs menu in GUI. - Changes permission of zabbix_agentd logfiles in logrotate config for GUI to be able to access the log files (640 to 644) - Changes file permissions of existing zabbix_agentd logfiles upon update of the package - Rootfile changes: added gui page, menu item-file, and addon language files - configroot rootfile changes: added logs menu item-file as comment - web-user-interface rootfile changes: added log viewer .dat as comment - Update language cache during install/uninstall Signed-off-by: Robin Roevens --- config/menu/EX-zabbix_agentd.menu | 5 + config/rootfiles/common/configroot | 1 + config/rootfiles/common/web-user-interface | 1 + config/rootfiles/packages/zabbix_agentd | 6 + config/zabbix_agentd/logrotate | 2 +- config/zabbix_agentd/zabbix_agentd.de.pl | 8 + config/zabbix_agentd/zabbix_agentd.en.pl | 8 + config/zabbix_agentd/zabbix_agentd.fr.pl | 8 + config/zabbix_agentd/zabbix_agentd.nl.pl | 8 + html/cgi-bin/logs.cgi/zabbix_agentd.dat | 341 +++++++++++++++++++++ lfs/zabbix_agentd | 4 + src/paks/zabbix_agentd/install.sh | 1 + src/paks/zabbix_agentd/uninstall.sh | 1 + src/paks/zabbix_agentd/update.sh | 3 + 14 files changed, 396 insertions(+), 1 deletion(-) create mode 100644 config/menu/EX-zabbix_agentd.menu create mode 100644 config/zabbix_agentd/zabbix_agentd.de.pl create mode 100644 config/zabbix_agentd/zabbix_agentd.en.pl create mode 100644 config/zabbix_agentd/zabbix_agentd.fr.pl create mode 100644 config/zabbix_agentd/zabbix_agentd.nl.pl create mode 100644 html/cgi-bin/logs.cgi/zabbix_agentd.dat diff --git a/config/menu/EX-zabbix_agentd.menu b/config/menu/EX-zabbix_agentd= .menu new file mode 100644 index 000000000..dddd7f05e --- /dev/null +++ b/config/menu/EX-zabbix_agentd.menu @@ -0,0 +1,5 @@ + $sublogs->{'95.zabbixagent'} =3D {'caption' =3D> $Lang::tr{'zabbix agent lo= gs'}, + 'uri' =3D> '/cgi-bin/logs.cgi/zabbix_agentd.dat', + 'title' =3D> "$Lang::tr{'zabbix agent logs'}", + 'enabled' =3D> 1 + }; diff --git a/config/rootfiles/common/configroot b/config/rootfiles/common/con= figroot index bc979cf2c..f12e2e0f0 100644 --- a/config/rootfiles/common/configroot +++ b/config/rootfiles/common/configroot @@ -126,6 +126,7 @@ var/ipfire/menu.d/70-log.menu #var/ipfire/menu.d/EX-samba.menu #var/ipfire/menu.d/EX-tor.menu #var/ipfire/menu.d/EX-wlanap.menu +#var/ipfire/menu.d/EX-zabbix_agentd.menu var/ipfire/modem var/ipfire/modem-lib.pl #var/ipfire/modem/defaults diff --git a/config/rootfiles/common/web-user-interface b/config/rootfiles/co= mmon/web-user-interface index 33f0d30a7..bc17b4ce4 100644 --- a/config/rootfiles/common/web-user-interface +++ b/config/rootfiles/common/web-user-interface @@ -49,6 +49,7 @@ srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromip.dat srv/web/ipfire/cgi-bin/logs.cgi/showrequestfromport.dat srv/web/ipfire/cgi-bin/logs.cgi/summary.dat srv/web/ipfire/cgi-bin/logs.cgi/urlfilter.dat +#srv/web/ipfire/cgi-bin/logs.cgi/zabbix_agentd.dat srv/web/ipfire/cgi-bin/mac.cgi srv/web/ipfire/cgi-bin/mail.cgi srv/web/ipfire/cgi-bin/mdstat.cgi diff --git a/config/rootfiles/packages/zabbix_agentd b/config/rootfiles/packa= ges/zabbix_agentd index 6f2c831d7..5b57026f5 100644 --- a/config/rootfiles/packages/zabbix_agentd +++ b/config/rootfiles/packages/zabbix_agentd @@ -7,6 +7,7 @@ etc/zabbix_agentd/scripts etc/zabbix_agentd/zabbix_agentd.conf etc/zabbix_agentd/zabbix_agentd.conf.example etc/zabbix_agentd/zabbix_agentd.d +srv/web/ipfire/cgi-bin/logs.cgi/zabbix_agentd.dat usr/bin/zabbix_get usr/bin/zabbix_sender #usr/lib/modules @@ -16,6 +17,11 @@ usr/sbin/zabbix_agentd #usr/share/man/man1/zabbix_sender.1 #usr/share/man/man8/zabbix_agentd.8 var/ipfire/backup/addons/includes/zabbix_agentd +var/ipfire/addon-lang/zabbix_agentd.de.pl +var/ipfire/addon-lang/zabbix_agentd.en.pl +var/ipfire/addon-lang/zabbix_agentd.fr.pl +var/ipfire/addon-lang/zabbix_agentd.nl.pl +var/ipfire/menu.d/EX-zabbix_agentd.menu var/ipfire/zabbix_agentd var/ipfire/zabbix_agentd/zabbix_agentd_ipfire_mandatory.conf var/ipfire/zabbix_agentd/userparameters diff --git a/config/zabbix_agentd/logrotate b/config/zabbix_agentd/logrotate index 83bbca9fb..46fee44f2 100644 --- a/config/zabbix_agentd/logrotate +++ b/config/zabbix_agentd/logrotate @@ -5,5 +5,5 @@ delaycompress missingok notifempty - create 0640 zabbix zabbix + create 0644 zabbix zabbix } diff --git a/config/zabbix_agentd/zabbix_agentd.de.pl b/config/zabbix_agentd/= zabbix_agentd.de.pl new file mode 100644 index 000000000..910225242 --- /dev/null +++ b/config/zabbix_agentd/zabbix_agentd.de.pl @@ -0,0 +1,8 @@ +%tr =3D (=20 +%tr, + +'zabbix agent logs' =3D> "Zabbix Agent-Protokolldateien", + +); + +#EOF diff --git a/config/zabbix_agentd/zabbix_agentd.en.pl b/config/zabbix_agentd/= zabbix_agentd.en.pl new file mode 100644 index 000000000..1f523f926 --- /dev/null +++ b/config/zabbix_agentd/zabbix_agentd.en.pl @@ -0,0 +1,8 @@ +%tr =3D (=20 +%tr, + +'zabbix agent logs' =3D> "Zabbix Agent Logs", + +); + +#EOF diff --git a/config/zabbix_agentd/zabbix_agentd.fr.pl b/config/zabbix_agentd/= zabbix_agentd.fr.pl new file mode 100644 index 000000000..f7576ad2f --- /dev/null +++ b/config/zabbix_agentd/zabbix_agentd.fr.pl @@ -0,0 +1,8 @@ +%tr =3D (=20 +%tr, + +'zabbix agent logs' =3D> "Rapports de Zabbix Agent", + +); + +#EOF diff --git a/config/zabbix_agentd/zabbix_agentd.nl.pl b/config/zabbix_agentd/= zabbix_agentd.nl.pl new file mode 100644 index 000000000..1f523f926 --- /dev/null +++ b/config/zabbix_agentd/zabbix_agentd.nl.pl @@ -0,0 +1,8 @@ +%tr =3D (=20 +%tr, + +'zabbix agent logs' =3D> "Zabbix Agent Logs", + +); + +#EOF diff --git a/html/cgi-bin/logs.cgi/zabbix_agentd.dat b/html/cgi-bin/logs.cgi/= zabbix_agentd.dat new file mode 100644 index 000000000..047ca2e98 --- /dev/null +++ b/html/cgi-bin/logs.cgi/zabbix_agentd.dat @@ -0,0 +1,341 @@ +#!/usr/bin/perl +############################################################################= ### +# = # +# IPFire.org - A linux based firewall = # +# Copyright (C) 2020 IPFire Team = # +# = # +# 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 . = # +# = # +############################################################################= ### + +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 =3D (); +my %mainsettings =3D (); +&General::readhash("${General::swroot}/main/settings", \%mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", = \%color); + +use POSIX(); + +my %cgiparams=3D(); +my %logsettings=3D(); +my $errormessage =3D ''; + +my @shortmonths =3D ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', + 'Sep', 'Oct', 'Nov', 'Dec' ); +my @longmonths =3D ( $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 =3D localtime(); +my $dow =3D $now[6]; +my $doy =3D $now[7]; +my $tdoy =3D $now[7]; +my $year =3D $now[5]+1900; + +$cgiparams{'DAY'} =3D $now[3]; +$cgiparams{'MONTH'} =3D $now[4]; +$cgiparams{'ACTION'} =3D ''; + +&Header::getcgihash(\%cgiparams); +$logsettings{'LOGVIEW_REVERSE'} =3D 'off'; +&General::readhash("${General::swroot}/logging/settings", \%logsettings); +${Header::viewsize} =3D defined ($logsettings{'LOGVIEW_VIEWSIZE'}) ? $logset= tings{'LOGVIEW_VIEWSIZE'} : 150; + +my $start =3D ($logsettings{'LOGVIEW_REVERSE'} eq 'on') ? 0x7FFFF000 : 0; #i= ndex of first line number to display + +if ($ENV{'QUERY_STRING'} && $cgiparams{'ACTION'} ne $Lang::tr{'update'}) { + my @temp =3D split(',',$ENV{'QUERY_STRING'}); + $start =3D $temp[0]; + $cgiparams{'MONTH'} =3D $temp[1]; + $cgiparams{'DAY'} =3D $temp[2]; +} + +if (!($cgiparams{'MONTH'} =3D~ /^(0|1|2|3|4|5|6|7|8|9|10|11)$/) || + !($cgiparams{'DAY'} =3D~ /^(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'} =3D $now[3]; + $cgiparams{'MONTH'} =3D $now[4]; +} elsif($cgiparams{'ACTION'} eq '>>') { + my @temp_then=3D(); + my @temp_now =3D localtime(time); + $temp_now[4] =3D $cgiparams{'MONTH'}; + $temp_now[3] =3D $cgiparams{'DAY'}; + @temp_then =3D localtime(POSIX::mktime(@temp_now) + 86400); + ## Retrieve the same time on the next day + + ## 86400 seconds in a day + $cgiparams{'MONTH'} =3D $temp_then[4]; + $cgiparams{'DAY'} =3D $temp_then[3]; +} elsif($cgiparams{'ACTION'} eq '<<') { + my @temp_then=3D(); + my @temp_now =3D localtime(time); + $temp_now[4] =3D $cgiparams{'MONTH'}; + $temp_now[3] =3D $cgiparams{'DAY'}; + @temp_then =3D localtime(POSIX::mktime(@temp_now) - 86400); + ## Retrieve the same time on the next day - + ## 86400 seconds in a day + $cgiparams{'MONTH'} =3D $temp_then[4]; + $cgiparams{'DAY'} =3D $temp_then[3]; +} + +# Find in which file.gz is the log. Can be calculated because MONTHLY ROTATI= NG of zabbix_agentd.log +my $gzindex; +my $date =3D $cgiparams{'DAY'} =3D=3D 0 ? '' : $cgiparams{'DAY'} <=3D 9 ? "= 0$cgiparams{'DAY'}" : "$cgiparams{'DAY'}"; + +my @then =3D (); + +my $monthstr =3D ($cgiparams{'MONTH'} + 1) <=3D 9 ? "0" . ($cgiparams{'MONTH= '} + 1) : ($cgiparams{'MONTH'} + 1); +my $daystr =3D $cgiparams{'DAY'} =3D=3D 0 ? '..' : $cgiparams{'DAY'} <=3D = 9 ? "0$cgiparams{'DAY'}" : "$cgiparams{'DAY'}"; +my $yearstr =3D $year; + +# Calculate time. If future date, calculate for past year !!! +if (( $cgiparams{'MONTH'} eq $now[4]) && ($cgiparams{'DAY'} > $now[3]) || + ( $cgiparams{'MONTH'} > $now[4] ) ) { + @then =3D localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'= MONTH'}, $year - 1901 )); + $date =3D "$longmonths[$cgiparams{'MONTH'}] $date, ". int($year-1); + $yearstr--; +} else { + @then =3D localtime(POSIX::mktime( 0, 0, 0, $cgiparams{'DAY'}, $cgiparams{'= MONTH'}, $year - 1900 )); + $date =3D "$longmonths[$cgiparams{'MONTH'}] $date, $year"; +} + +$gzindex =3D $now[4] - $then[4]; +$gzindex +=3D 12 if $gzindex < 0; + +my $lines =3D 0; +my @log=3D(); + +my $loop =3D 1; +my $filestr =3D 0; +my $search_for_end =3D 0; + +while ($gzindex >=3D0 && $loop) { + # calculate file name + if ($gzindex =3D=3D 0) { + $filestr =3D "/var/log/zabbix/zabbix_agentd.log"; + } else { + $filestr =3D "/var/log/zabbix/zabbix_agentd.log.$gzindex"; + $filestr =3D "$filestr.gz" if -f "$filestr.gz"; + } + # now read file if existing + if (open (FILE,($filestr =3D~ /.gz$/ ? "gzip -dc $filestr |" : $filestr))) { + READ:while () { + my $line =3D $_; + if ($line =3D~ /^ *[0-9]+:${yearstr}${monthstr}${daystr}:[0-9]{6}\.[0-9]{= 3} (.*)/) { + # when standard viewing, just keep in memory the correct slice + # it starts at '$start' and size is $viewport + # If export, then keep all lines... + if ($cgiparams{'ACTION'} eq $Lang::tr{'export'}){ + $log[$lines++] =3D "$line"; + } else { + if ($lines++ < ($start + $Header::viewsize)) { + push(@log,"$line"); + if (@log > $Header::viewsize) { + shift (@log); + } + } + } + $search_for_end =3D 1; # we find the start of slice, can look for end now + } else { + if ($search_for_end =3D=3D 1) { + #finish read files when date is over (test month equality only) + $line =3D~ /^ *[0-9]+:[0-9]{4}([0-9]{2})([0-9]{2}):[0-9]{6}\.[0-9]{3} .= *$/; + $loop =3D 0 if ( ($1 ne $monthstr) || ( ($daystr ne '..') && ($daystr n= e $2) ) ); + } + } + } + close (FILE); + } + $gzindex--; # will try next gz file eg 40,39,38,.... because it may hav= e holes +} + +if ($cgiparams{'ACTION'} eq $Lang::tr{'export'}) { + print "Content-type: text/plain\n\n"; + print "IPFire $Lang::tr{'zabbix agent logs'}\r\n"; + print "$Lang::tr{'date'}: $date\r\n\r\n"; + + if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log =3D reverse @log; } + + foreach $_ (@log) { + /^ *([0-9]+):[0-9]{6}([0-9]{2}):([0-9]{2})([0-9]{2})([0-9]{2}\.[0-9]{3}) (= .*)$/; + my $pid =3D $1; + my $day =3D $2; + $day =3D~ tr / /0/; + my $time =3D $cgiparams{'DAY'} ? "$3:$4:$5" : "$day/$3:$4:$5" ; + print "$time ($pid) $6\r\n"; + } + exit 0; +} + +&Header::showhttpheaders(); + +&Header::openpage($Lang::tr{'zabbix agent logs'}, 1, ''); + +&Header::openbigbox('100%', 'left', '', $errormessage); + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage \n"; + &Header::closebox(); +} + +&Header::openbox('100%', 'left', "$Lang::tr{'settings'}:"); + +print < + + + + + + + + + + + +
$Lang::tr{'month'}: + $Lang::tr{'day'}: +
+ +END +; + +&Header::closebox(); + +&Header::openbox('100%', 'left', $Lang::tr{'log'}); +print "

$Lang::tr{'total hits for log section'} $date: $lines

"; + +$start =3D $lines - ${Header::viewsize} if ($start >=3D $lines - ${Header::v= iewsize}); +$start =3D 0 if ($start < 0); + +my $prev; +if ($start =3D=3D 0) { + $prev =3D -1; +} else { + $prev =3D $start - ${Header::viewsize}; + $prev =3D 0 if ( $prev < 0); +} + +my $next; +if ($start =3D=3D $lines - ${Header::viewsize}) { + $next =3D -1; +} else { + $next =3D $start + ${Header::viewsize}; + $next =3D $lines - ${Header::viewsize} if ($next >=3D $lines - ${Header::vi= ewsize}); +} + +if ($logsettings{'LOGVIEW_REVERSE'} eq 'on') { @log =3D reverse @log; } +if ($lines !=3D 0) { &oldernewer(); } + +print < + + $Lang::tr{'time'}<= /b> + PID +   + +END +; + +$lines =3D 0; +foreach $_ (@log) { + /^ *([0-9]+):[0-9]{6}([0-9]{2}):([0-9]{2})([0-9]{2})([0-9]{2}\.[0-9]{3}) (.= *)$/; + my $pid =3D $1; + my $day =3D $2; + $day =3D~ tr / /0/; + my $time =3D $cgiparams{'DAY'} ? "$3:$4:$5" : "$day/$3:$4:$5" ; + my $data =3D $6; + my $col=3D""; + + if ($lines % 2) { + print ""; + $col=3D"bgcolor=3D'$color{'color20'}'";=20 + } else { + print ""; + $col=3D"bgcolor=3D'$color{'color22'}'";=20 + } + print "$time$pid" .&Header::cleanhtml ("$data", = 'y') . "\n"; + $lines++; +} +print ""; + +&oldernewer(); + +&Header::closebox(); + +&Header::closebigbox(); + +&Header::closepage(); + +sub oldernewer { + print < + +END + ; + + print ""; + if ($prev !=3D -1) { + print "$Lang::tr{'older'}";=20 + } else { + print "$Lang::tr{'older'}";=20 + } + print "\n"; + + print ""; + if ($next >=3D 0) { + print "$Lang::tr{'newer'}";=20 + } else { + print "$Lang::tr{'newer'}";=20 + } + print "\n"; + + print < + +END + ; +} diff --git a/lfs/zabbix_agentd b/lfs/zabbix_agentd index 281bd9fa3..49b8440f8 100644 --- a/lfs/zabbix_agentd +++ b/lfs/zabbix_agentd @@ -139,6 +139,10 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) -mkdir -pv /etc/logrotate.d install -v -m 644 $(DIR_SRC)/config/zabbix_agentd/logrotate \ /etc/logrotate.d/zabbix_agentd +=09 + # Install addon-specific language-files. + install -v -m 004 $(DIR_SRC)/config/zabbix_agentd/zabbix_agentd.*.pl \ + /var/ipfire/addon-lang/ =20 @rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/src/paks/zabbix_agentd/install.sh b/src/paks/zabbix_agentd/insta= ll.sh index 80632d1ec..465ea7e8a 100644 --- a/src/paks/zabbix_agentd/install.sh +++ b/src/paks/zabbix_agentd/install.sh @@ -32,6 +32,7 @@ if ! getent passwd zabbix; then fi =20 extract_files +/usr/local/bin/update-lang-cache =20 # Create symlinks for runlevel interaction. ln -sf ../init.d/zabbix_agentd /etc/rc.d/rc3.d/S65zabbix_agentd diff --git a/src/paks/zabbix_agentd/uninstall.sh b/src/paks/zabbix_agentd/uni= nstall.sh index edff3b818..4342384de 100644 --- a/src/paks/zabbix_agentd/uninstall.sh +++ b/src/paks/zabbix_agentd/uninstall.sh @@ -25,6 +25,7 @@ stop_service ${NAME} make_backup ${NAME} remove_files +/usr/local/bin/update-lang-cache =20 # Remove init-scripts and symlinks rm -rfv /etc/rc.d/rc*.d/*zabbix_agentd diff --git a/src/paks/zabbix_agentd/update.sh b/src/paks/zabbix_agentd/update= .sh index a41e72ab4..f01e32810 100644 --- a/src/paks/zabbix_agentd/update.sh +++ b/src/paks/zabbix_agentd/update.sh @@ -40,6 +40,9 @@ if [ -f /etc/sudoers.d/zabbix ]; then fi fi =20 +# Fix permissions on /var/log/zabbix/* to allow GUI to read the logfiles. +find /var/log/zabbix -perm 640 -exec chmod 644 \{\} \; + extract_backup_includes ./uninstall.sh ./install.sh --=20 2.40.0 --=20 Dit bericht is gescanned op virussen en andere gevaarlijke inhoud door MailScanner en lijkt schoon te zijn. --===============4415836720766185888==--