######################################################## # Please file all bug reports, patches, and feature # requests under: # https://sourceforge.net/p/logwatch/_list/tickets # Help requests and discusion can be filed under: # https://sourceforge.net/p/logwatch/discussion/ ######################################################## ##################################################### ## Copyright (c) 2008 Kirk Bauer ## Covered under the included MIT/X-Consortium License: ## http://www.opensource.org/licenses/mit-license.php ## All modifications and contributions by other persons to ## this script are assumed to have been donated to the ## Logwatch project and thus assume the above copyright ## and licensing terms. If you want to make contributions ## under your own copyright or a different license this ## must be explicitly stated in the contribution an the ## Logwatch project reserves the right to not accept such ## contributions. If you have made significant ## contributions to this script and want to claim ## copyright please contact logwatch-devel@lists.sourceforge.net. ######################################################### use strict; use Logwatch ':ip'; my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; my $Ignore_cpu_throttled = $ENV{'ignore_cpu_throttled'} || 0; my $Ignore_faults = $ENV{'ignore_faults'}; my $Ignore_rpcsec_expired = $ENV{'ignore_rpcsec_expired'} || 0; my $Ignore_messages = $ENV{'kernel_ignore_messages'} || '^$'; my $CPUThrottled = 0; my %SYNflood = (); my %RAIDErrors = (); my %DRBDErrors = (); my %SegFaults = (); my %GPFaults = (); my %TrapInt3s = (); my %UnalignedErrors = (); my %FPAssists = (); my %OOM = (); my %Errors = (); my %Kernel = (); my %EDACs = (); my %NFS = (); my %EXT4Volume = (); my %EXT4 = (); #Init String Containers my ( $Volume, $errormsg, $from, $host, $on ); while (defined(my $ThisLine = )) { chomp($ThisLine); next if ($ThisLine eq ''); # Remove timestamp if present $ThisLine =~ s/^\[\s*\d+\.\d+\]\s*//; if ( # filter out audit messages - these should be parsed by the audit # service ($ThisLine =~ /(type=\d+\s+)?audit\(/) # following now in iptables service or ($ThisLine =~ /^Packet log: .*PROTO=/) or ($ThisLine =~ /IN=.*OUT=.*SRC=.*DST=.*PROTO=/) or ($ThisLine =~ /RAS: Correctable Errors collector initialized/) # user specified ignore messages, lower cased or ($ThisLine =~ /$Ignore_messages/i) ) { # ignore the above strings } elsif ( ($from,$on) = ( $ThisLine =~ /^Warning: possible SYN flood from ([^ ]+) on ([^ ]+):.+ Sending cookies/ ) ) { my $Fullfrom = LookupIP($from); my $Fullon = LookupIP($on); $SYNflood{$Fullon}{$Fullfrom}++; } elsif ($ThisLine =~ /temperature above threshold, cpu clock throttled/) { $CPUThrottled++ if not $Ignore_cpu_throttled; } elsif ($ThisLine =~ /continuing in degraded mode/) { $RAIDErrors{$ThisLine}++; } elsif ($ThisLine =~ /([^(]*)\[\d+\]: segfault at/) { $SegFaults{$1}++; } elsif ($ThisLine =~ /([^(]*)\[\d+\] general protection/) { $GPFaults{$1}++; } elsif ($ThisLine =~ /([^(]*)\[\d+\] trap int3 /) { $TrapInt3s{$1}++; } elsif ($ThisLine =~ /([^(]*)\(\d+\): unaligned access to/) { $UnalignedErrors{$1}++; } elsif ($ThisLine =~ /([^(]*)\(\d+\): floating-point assist fault at ip/) { $FPAssists{$1}++; } elsif ($ThisLine =~ /(?:[Kk]illed|[Kk]ill) process \d+ \((.*)\)/) { $OOM{$1}++; } elsif ($ThisLine =~ /(EDAC (?:igen6 )?(?:MC|PCI)\d:.*)/) { # Standard boot messages next if $ThisLine =~ /(?:Giving out device to |HANDLING IBECC MEMEORY )/; $EDACs{$1}++; } elsif ($ThisLine =~ /(block drbd\d+): Online verify found (\d+) \d+k block out of sync/) { $DRBDErrors{$1}{"$2 block(s) out of sync"} = 1; } elsif ($ThisLine =~ /(block drbd\d+): \[.*\] sock_sendmsg time expired/) { $DRBDErrors{$1}{"sock_sendmsg time expired"}++; } elsif ($ThisLine =~ /(block drbd\d+): Began resync as (SyncSource|SyncTarget)/) { $DRBDErrors{$1}{"Began resync as $2"}++; } elsif ( $ThisLine =~ /raid.*CRIT/) { # kernel: megaraid_sas 0000:88:00.0: 781934 (727946738s/0x0004/CRIT) - Enclosure PD 08(c Port 0 - 3/p1) phy bad for slot 19 # de-dupe $ThisLine =~ s/: \d+ /: /; $ThisLine =~ s/\(\d+s\//(Xs\//; $Errors{$ThisLine}++; } elsif ( ( $errormsg ) = ( $ThisLine =~ /(.*?error.{0,17})/i ) ) { # filter out smb open/read errors cased by insufficient permissions my $SkipError = 0; $SkipError = 1 if $ThisLine =~ /smb_readpage_sync: .*open failed, error=-13/; $SkipError = 1 if $ThisLine =~ /smb_open: .* open failed, result=-13/; $SkipError = 1 if $ThisLine =~ /smb_open: .* open failed, error=-13/; # filter out error_exit in stack traces caused by OOM conditions $SkipError = 1 if $ThisLine =~ /\[<[\da-f]+>\] error_exit\+0x/; # These are informative, not errors $SkipError = 1 if $ThisLine =~ /ACPI _OSC request failed \(AE_ERROR\), returned control mask: 0x1d/; $SkipError = 1 if $ThisLine =~ /ERST: Error Record Serialization Table \(ERST\) support is initialized/; $SkipError = 1 if $ThisLine =~ /GHES: Generic hardware error source: \d+ notified via .* is not supported/; $SkipError = 1 if $ThisLine =~ /HEST: Enabling Firmware First mode for corrected errors/; $SkipError = 1 if $ThisLine =~ /PCIe errors handled by (?:BIOS|OS)/; # These happen when kerberos tickets expire, which can be normal $SkipError = 1 if $ThisLine =~ /Error: state manager encountered RPCSEC_GSS session expired against NFSv4 server/ && $Ignore_rpcsec_expired; $SkipError = 1 if $ThisLine =~ /RAS: Correctable Errors collector initialized/; # filter out mount options $SkipError = 1 if $ThisLine =~ /errors=(?:continue|remount-ro|panic)/; $Errors{$errormsg}++ if ( (! $SkipError) || ($Detail > 8)); } elsif ( ( ($Volume, $errormsg) ) = ( $ThisLine =~ /^EXT4-fs \(([^)]+)\): (.*)/ ) ) { if ($errormsg =~ /INFO: recovery required on readonly filesystem/) { $EXT4Volume{$Volume} = 1; push @{$EXT4{$Volume}}, $errormsg; } elsif ($EXT4Volume{$Volume}) { push @{$EXT4{$Volume}}, $errormsg if $EXT4{$Volume}; delete $EXT4Volume{$Volume} if ($errormsg =~ /recovery complete/); } } elsif ( ( $errormsg ) = ( $ThisLine =~ /((BUG|WARNING|INFO):.{0,40})/ ) ) { $Errors{$errormsg}++; } elsif ( ( $host ) = ( $ThisLine =~ /^nfs: server (.*) not responding/ ) ) { $NFS{$host}++; # OTHER } else { # XXX For now, going to ignore all other kernel messages as there # XXX are practically an infinite number and most of them are obviously # XXX not parsed here at this time. # filter out smb open/read errors cased by insufficient permissions my $SkipError = 0; $SkipError = 1 if $ThisLine =~ /smb_readpage_sync: .*open failed, error=-13/; $SkipError = 1 if $ThisLine =~ /smb_open: .* open failed, result=-13/; $SkipError = 1 if $ThisLine =~ /smb_open: .* open failed, error=-13/; $SkipError = 1 if $ThisLine =~ /block drbd\d+: Out of sync: start=\d+/; $SkipError = 1 if $ThisLine =~ /block drbd\d+: updated( sync)? UUIDs?/i; $SkipError = 1 if $ThisLine =~ /block drbd\d+: Resync done/; $SkipError = 1 if $ThisLine =~ /block drbd\d+: cs:(?:Ahead|Behind) rs_left/; $SkipError = 1 if $ThisLine =~ /block drbd\d+: \d+ % had equal checksums, eliminated:/; $Kernel{$ThisLine}++ if ( (! $SkipError) || ($Detail > 8)) ; } } if (keys %SYNflood) { print "\nWarning: SYN flood on:\n"; foreach my $Thisone (sort {$a cmp $b} keys %SYNflood) { print " " . $Thisone . " from:\n"; foreach my $Next (sort {$a cmp $b} keys %{$SYNflood{$Thisone}}) { print " " . $Next . ": $SYNflood{$Thisone}{$Next} Time(s)\n"; } } } if (keys %RAIDErrors) { print "\nWARNING: RAID Errors Present\n"; foreach my $Thisone ( sort {$a cmp $b} keys %RAIDErrors ) { print " $Thisone ...: $RAIDErrors{$Thisone} Time(s)\n"; } } if (keys %DRBDErrors) { print "\nWARNING: DRBD Errors Present\n"; foreach my $Thisone ( sort {$a cmp $b} keys %DRBDErrors ) { foreach my $Msg (sort {$a cmp $b} keys %{$DRBDErrors{$Thisone}}) { print " $Thisone: $Msg"; print " : $DRBDErrors{$Thisone}{$Msg} Time(s)" if $DRBDErrors{$Thisone}{$Msg} > 1; print "\n"; } } } if (keys %SegFaults) { my $header_printed=0; foreach my $Thisone ( sort {$a cmp $b} keys %SegFaults ) { if ($Thisone =~ /^$Ignore_faults$/) { next; } if (!$header_printed) { print "\nWARNING: Segmentation Faults in these executables\n"; $header_printed=1; } print " $Thisone : $SegFaults{$Thisone} Time(s)\n"; } } if (keys %GPFaults) { my $header_printed=0; foreach my $Thisone ( sort {$a cmp $b} keys %GPFaults ) { if ($Thisone =~ /^$Ignore_faults$/) { next; } if (!$header_printed) { print "\nWARNING: General Protection Faults in these executables\n"; $header_printed=1; } print " $Thisone : $GPFaults{$Thisone} Time(s)\n"; } } if (keys %TrapInt3s) { my $header_printed=0; foreach my $Thisone ( sort {$a cmp $b} keys %TrapInt3s ) { if ($Ignore_faults =~ /\b\Q$Thisone\E\b/i) { next; } if (!$header_printed) { print "\nWARNING: Trap int3 in these executables\n"; $header_printed=1; } print " $Thisone : $TrapInt3s{$Thisone} Time(s)\n"; } } if (keys %UnalignedErrors) { print "\nWARNING: Unaligned Errors in these executables\n"; foreach my $Thisone ( sort {$a cmp $b} keys %UnalignedErrors ) { print " $Thisone : $UnalignedErrors{$Thisone} Time(s)\n"; } } if (keys %FPAssists) { print "\nWARNING: Floating-Point Assists in these executables\n"; foreach my $Thisone ( sort {$a cmp $b} keys %FPAssists ) { print " $Thisone : $FPAssists{$Thisone} Time(s)\n"; } } if (keys %OOM) { print "\nWARNING: Out of memory killer killed these executables\n"; foreach my $Thisone ( sort {$a cmp $b} keys %OOM ) { print " $Thisone : $OOM{$Thisone} Time(s)\n"; } } if (keys %Errors) { print "\nWARNING: Kernel Errors Present\n"; foreach my $Thisone ( sort {$a cmp $b} keys %Errors ) { print " $Thisone ...: $Errors{$Thisone} Time(s)\n"; } } if (keys %EDACs) { print "\nWARNING: Kernel EDAC Messages\n"; foreach my $Thisone ( sort {$a cmp $b} keys %EDACs ) { print " $Thisone ...: $EDACs{$Thisone} Time(s)\n"; } } if (keys %NFS) { print "\nWARNING: NFS Server Not Responding Messages\n"; foreach my $Thisone ( sort {$a cmp $b} keys %NFS ) { print " $Thisone ...: $NFS{$Thisone} Time(s)\n"; } } if (keys %EXT4) { print "\nWARNING: Ext4 Errors Present\n"; foreach my $Volume ( sort {$a cmp $b} keys %EXT4 ) { print " $Volume:\n"; foreach my $Msg (@{$EXT4{$Volume}}) { print " $Msg\n"; } } } if ($CPUThrottled) { print "\nWARNING: CPU Package temperature above threshold, cpu clock throttled $CPUThrottled Time(s)\n"; } # OTHER if ( ($Detail >= 5) and (keys %Kernel) ) { print "\n"; foreach my $Thisone (sort {$a cmp $b} keys %Kernel) { print $Kernel{$Thisone} . " Time(s): " . $Thisone . "\n"; } } exit(0); # vi: shiftwidth=3 tabstop=3 syntax=perl et # Local Variables: # mode: perl # perl-indent-level: 3 # indent-tabs-mode: nil # End: