Server IP : 85.214.239.14 / Your IP : 18.188.195.90 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /sbin/ |
Upload File : |
#!/usr/bin/perl -T # SPDX-License-Identifier: BSD-2-Clause #------------------------------------------------------------------------------ # This is amavisd-agent, a demo program to display # SNMP-like counters updated by amavis. # # Author: Mark Martinec <Mark.Martinec@ijs.si> # # Copyright (c) 2004-2014, Mark Martinec # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # The views and conclusions contained in the software and documentation are # those of the authors and should not be interpreted as representing official # policies, either expressed or implied, of the Jozef Stefan Institute. # (the above license is the 2-clause BSD license, also known as # a "Simplified BSD License", and pertains to this program only) # # Patches and problem reports are welcome. # The latest version of this program is available at: # http://www.ijs.si/software/amavisd/ #------------------------------------------------------------------------------ use strict; use re 'taint'; use warnings; no warnings 'uninitialized'; use Errno qw(ENOENT); use Time::HiRes (); use BerkeleyDB; my($dbfile) = 'snmp.db'; my($db_home) = # DB databases directory defined $ENV{'AMAVISD_DB_HOME'} ? $ENV{'AMAVISD_DB_HOME'} : '/var/lib/amavis/db'; my($wakeuptime) = 10; # -w, sleep time in seconds, may be fractional my($repeatcount); # -c, repeat count (when defined) use vars qw($VERSION); $VERSION = 2.701; use vars qw(%values %virus_by_name); use vars qw(%virus_by_os %spam_by_os %ham_by_os); use vars qw(%history $avg_int $uptime); $avg_int = 5*60; # 5 minute interval sub p1($$@) { my($k,$avg,@tot_k) = @_; printf("%-35s %6d %6.0f/h", $k, $values{$k}, $avg*3600); for my $tot_k (@tot_k) { if ($values{$tot_k} <= 0) { printf(" --- %%") } else { printf(" %7.1f %%", 100*$values{$k}/$values{$tot_k}) } print " ($tot_k)"; } print "\n"; } sub p1_size($$@) { my($k,$avg,@tot_k) = @_; my($scale) = 1024*1024; printf("%-35s %6.0fMB %4.0fMB/h", $k, $values{$k}/$scale, $avg*3600/$scale); for my $tot_k (@tot_k) { if ($values{$tot_k} <= 0) { printf(" --- %%") } else { printf(" %5.1f %%", 100*$values{$k}/$values{$tot_k}) } print " ($tot_k)"; } print "\n"; } sub p1_time($$$$) { my($k,$dv,$dcnt,$tot_k) = @_; printf("%-35s %6.0f s %8s s/msg (%s)\n", $k, $values{$k}/1000, $dcnt < 1 ? "---" : sprintf("%7.3f",$dv/1000/$dcnt), $tot_k); } sub p2($$$$) { my($k,$avg,$tot_k,$href) = @_; if ($values{$tot_k} > 0) { printf("%-35s %6d %6.0f/h %6.1f %% (%s)\n", $k, $href->{$k}, $avg*3600, 100*$href->{$k}/$values{$tot_k}, $tot_k); } } sub enqueue($$$$$) { my($name,$now,$val,$msgcnt,$hold_time) = @_; if (ref $history{$name} ne 'ARRAY') { $history{$name} = [] } my($oldest_useful); for my $j (0..$#{$history{$name}}) { if ($history{$name}->[$j][0] + $hold_time >= $now) { $oldest_useful = $j; last } } if (defined $oldest_useful) { @{$history{$name}} = @{$history{$name}}[$oldest_useful..$#{$history{$name}}]; } push(@{$history{$name}}, [$now,$val,$msgcnt]); my($average,$dv,$dt,$dcnt); my($n) = scalar(@{$history{$name}}); my($oldest) = $history{$name}->[0]; my($latest) = $history{$name}->[$n-1]; $dt = $latest->[0] - $oldest->[0]; $dv = $latest->[1] - $oldest->[1]; $dcnt = $latest->[2] - $oldest->[2]; if ($n < 2 || $dt < $hold_time/2) { $dt = $uptime; $dv = $val; $dcnt = $msgcnt; # average since the start time } if ($dt > 0) { $average = $dv/$dt } ($average, $dv, $dt, $dcnt, $n); } sub fmt_ticks($) { my($t) = @_; my($hh)= $t % 100; $t = int($t/100); my($s) = $t % 60; $t = int($t/60); my($m) = $t % 60; $t = int($t/60); my($h) = $t % 24; $t = int($t/24); my($d) = $t; sprintf("%d days, %d:%02d:%02d.%02d", $d,$h,$m,$s,$hh); }; # main program starts here my($normal_termination) = 0; $SIG{INT} = sub { die "\n" }; # do the END code block while (@ARGV) { my($opt) = shift @ARGV; my($val) = shift @ARGV; if ($opt eq '-w' && $val =~ /^\+?\d+(?:\.\d*)?\z/) { $wakeuptime = $val } elsif ($opt eq '-c' && $val =~ /^[+-]?\d+\z/) { $repeatcount = $val } else { die "Usage: $0 [-c <count>] [-w <wait-interval>]\n" } } my($stat,$key,$val); my($env,$db,$old_db_inode,@dbstat,$cursor); for (;;) { last if defined $repeatcount && $repeatcount <= 0; @dbstat = stat("$db_home/$dbfile"); my($errn) = @dbstat ? 0 : 0+$!; $errn==0 || $errn==ENOENT or die "stat $db_home/$dbfile: $!"; if (defined $db && $old_db_inode != $dbstat[1]) { $db->db_close==0 or die "BDB db_close error: $BerkeleyDB::Error $!"; undef $db; printf STDERR ("Reopening snmp database %s/%s\n", $db_home,$dbfile); } if (!defined $db && $errn==0) { $old_db_inode = $dbstat[1]; $env = BerkeleyDB::Env->new( -Home => $db_home, -Flags => DB_INIT_CDB | DB_INIT_MPOOL, -ErrFile => \*STDOUT, -Verbose => 1); defined $env or die "BDB no env: $BerkeleyDB::Error $!"; $db = BerkeleyDB::Hash->new(-Filename => $dbfile, -Env => $env); defined $db or die "BDB no dbS 1: $BerkeleyDB::Error $!"; } $| = 0; %values = (); %virus_by_name = (); %virus_by_os = (); %spam_by_os = (); %ham_by_os = (); my($now); my($eval_stat,$interrupt); $interrupt = ''; if (!defined $db) { printf STDERR ("No snmp database %s/%s; waiting...\n", $db_home,$dbfile); } else { $repeatcount-- if defined $repeatcount && $repeatcount > 0; print "\n\n"; my($h1) = sub { $interrupt = $_[0] }; local(@SIG{qw(INT HUP TERM TSTP QUIT ALRM USR1 USR2)}) = ($h1) x 8; eval { $cursor = $db->db_cursor; # obtain read lock defined $cursor or die "db_cursor error: $BerkeleyDB::Error"; $now = Time::HiRes::time; while ( ($stat=$cursor->c_get($key,$val,DB_NEXT)) == 0 ) { if ($key =~ /^(virus\.byname\..*)\z/s) { $virus_by_name{$1} = $val } elsif ($key =~ /^(virus\.byOS\..*)\z/s) { $virus_by_os{$1} = $val } elsif ($key =~ /^(ham\.byOS\..*)\z/s) { $ham_by_os{$1} = $val } elsif ($key =~ /^(?:spam|spammy)\.byOS\.(.*)\z/s) { $spam_by_os{"spam.byOS.$1"} = $val } else { $values{$key} = $val } } $stat==DB_NOTFOUND or die "c_get: $BerkeleyDB::Error $!"; $cursor->c_close==0 or die "c_close error: $BerkeleyDB::Error"; $cursor = undef; }; $eval_stat = $@; if (defined $db) { $cursor->c_close if defined $cursor; # unlock, ignoring status $cursor = undef; } } if ($interrupt ne '') { kill($interrupt,$$) } # resignal elsif ($eval_stat ne '') { chomp($eval_stat); die "BDB $eval_stat\n" } for my $k (sort keys %values) { if ($values{$k} =~ /^(?:C32|C64) (.*)\z/) { $values{$k} = $1; } elsif ($k eq 'sysUpTime' && $values{$k} =~ /^INT (.*)\z/) { $uptime = $now - $1; my($ticks) = int($uptime*100); printf("%-15s %s %s (%s)\n", $k,'TimeTicks', $ticks, fmt_ticks($ticks)); delete($values{$k}); } elsif ($values{$k} =~ /^(?:INT|TIM) (.*)\z/) { $values{$k} = $1; } else { printf("%-15s %s\n", $k,$values{$k}); delete($values{$k}); } } my($msgcnt) = $values{'InMsgs'}; for (sort keys %values) { my($avg,$dv,$dt,$dcnt,$n) = enqueue($_, $now, $values{$_}, $msgcnt, $avg_int); if (/^OpsDecTyp/) {} # later elsif (/^CacheHitsVirusMsgs$/) { p1($_,$avg,'ContentVirusMsgs') } elsif (/^CacheHitsBannedMsgs$/) { p1($_,$avg,'ContentBannedMsgs') } elsif (/^CacheHitsSpamMsgs$/) { p1($_,$avg,'ContentSpamMsgs') } elsif (/^Cache/) { p1($_,$avg,'CacheAttempts') } # elsif (/^Content(.*?)Msgs/) { p1($_,$avg,'Content'.$1.'Msgs') } elsif (/^Content(.*?)Msgs(.*)\z/) { p1($_,$avg,'InMsgs'.$2) } elsif (/^Content/) { p1($_,$avg,'InMsgs') } elsif (/^OpsSql/) { p1($_,$avg,'InMsgsRecips') } elsif (/^InMsgsSize/) { p1_size($_,$avg,'InMsgsSize') } elsif (/^InMsgsRecipsLocal\z/) { p1($_,$avg,'InMsgsRecips') } elsif (/^InMsgsRecips(.*)\z/) { p1($_,$avg,'InMsgs'.$1) } elsif (/^InMsgsBounce./) { p1($_,$avg,'InMsgsBounce') } elsif (/^(InMsgs|Ops)/) { p1($_,$avg,'InMsgs') } elsif (/^OutMsgsSize\z/) { p1_size($_,$avg,'InMsgsSize') } elsif (/^OutMsgsSize/) { p1_size($_,$avg,'OutMsgsSize') } elsif (/^OutMsgs\z/) { p1($_,$avg,'InMsgs') } elsif (/^Out/) { p1($_,$avg,'OutMsgs') } elsif (/^QuarMsgsSize\z/) { p1_size($_,$avg,'InMsgsSize') } elsif (/^QuarMsgsSize/) { p1_size($_,$avg,'QuarMsgsSize') } elsif (/^Quar/) { p1($_,$avg,'QuarMsgs') } elsif (/^LogEntries\z/) { p1($_,$avg,'InMsgs') } elsif (/^Log/) { p1($_,$avg,'LogEntries') } elsif (/^GenMailIdRetries/) { p1($_,$avg,'InMsgs') } elsif (/^PenPalsAttempts\z/) { p1($_,$avg,'InMsgsRecipsLocal') } elsif (/^PenPalsHits\z/) { p1($_,$avg,'PenPalsAttempts')} elsif (/^PenPalsHits./) { p1($_,$avg,'PenPalsHits') } elsif (/^PenPals/) { p1($_,$avg,'PenPalsAttempts') } elsif (/^SqlAddrSenderAttempts\z/) { p1($_,$avg,'InMsgs') } elsif (/^SqlAddrSender/) { p1($_,$avg,'SqlAddrSenderAttempts') } elsif (/^SqlAddrRecipAttempts\z/) { p1($_,$avg,'InMsgsRecips') } elsif (/^SqlAddrRecip/) { p1($_,$avg,'SqlAddrRecipAttempts') } elsif (/^banned\.byOS/) { p1($_,$avg,'InMsgs') } elsif (/^TimeElapsed/i) { p1_time($_,$dv,$dcnt,'InMsgs') } else { p1($_,$avg,undef) } } for (sort { $values{$b}<=>$values{$a} } grep {/^OpsDecTyp/} keys %values) { my($avg,$dv,$dt,$dcnt,$n) = enqueue($_, $now, $values{$_}, $msgcnt, $avg_int); p1($_,$avg,'InMsgs'); } for my $href (\%virus_by_name,\%virus_by_os,\%spam_by_os,\%ham_by_os) { for (keys %$href) { $href->{$_} = $1 if $href->{$_} =~ /^(?:C32|C64) (.*)\z/ } } for my $href (\%virus_by_os,\%spam_by_os,\%ham_by_os) { for (keys %$href) { /^[a-zA-Z]+\.byOS\.(.*)\z/; my($os) = $1; $values{"all.byOS.$os"} += $href->{$_}; } } my($separated) = 0; for my $pair ([\%virus_by_name, 'ContentVirusMsgs',], [\%virus_by_os, 'ContentVirusMsgs',], [\%spam_by_os, 'ContentSpamMsgs', ], [\%ham_by_os, 'ContentCleanMsgs' ] ) { my($href,$tot_k) = @$pair; for (sort {$href->{$b} <=> $href->{$a}} keys %$href) { if (!$separated) { print "\n"; $separated = 1 } my($avg,$dv,$dt,$dcnt,$n) = enqueue($_, $now, $href->{$_}, $msgcnt, $avg_int); p2($_,$avg,$tot_k,$href); } } if (0) { # disabled $separated = 0; for my $href (\%virus_by_os, \%spam_by_os, \%ham_by_os) { for (sort {$href->{$b} <=> $href->{$a}} keys %$href) { if (!$separated) { print "\n"; $separated = 1 } my($avg,$dv,$dt,$dcnt,$n) = enqueue($_, $now, $href->{$_}, $msgcnt, $avg_int); /^[a-zA-Z]+\.byOS\.(.*)\z/; my($os) = $1; p2($_,$avg,"all.byOS.$os",$href); } } $separated = 0; for (sort { $values{$b}<=>$values{$a} } grep {/^all\.byOS\./} keys %values) { if (!$separated) { print "\n"; $separated = 1 } my($avg,$dv,$dt,$dcnt,$n) = enqueue($_, $now, $values{$_}, $msgcnt, $avg_int); p1($_,$avg,'InMsgs'); } } $| = 1; last if defined $repeatcount && $repeatcount <= 0; Time::HiRes::sleep($wakeuptime) if $wakeuptime > 0; } # forever $normal_termination = 1; END { if (defined $db) { $cursor->c_close if defined $cursor; # ignoring status $db->db_close==0 or die "BDB db_close error: $BerkeleyDB::Error $!"; } print STDERR "exited\n" if !$normal_termination; }