Sophie

Sophie

distrib > Mandriva > 2008.1 > i586 > by-pkgid > e28667f4e1cf50e0b002c8a83e0e0d6f > files > 236

logwatch-7.3.6-2mdv2008.1.noarch.rpm


##########################################################################
# $Id: smartd,v 1.21 2007/04/09 14:46:46 kirk Exp $
##########################################################################

use strict;

my ($Device, $Msg, $Test);
my %ParamChanges = ();
my %TempChanges = ();
my %Pendsectors = ();
my %NumPendsectors = ();
my %Offsectors = ();
my %NumOffsectors = ();
my %Warnings = ();
my %UnableToReg = ();
my $ShutdownFailed = 0;
my $StartupFailed = 0;
my %NotInDatabase = ();
my %CantMonitor = ();
my %SelfTest = ();
my %Failed = ();
my @OtherList = ();
my $DLine = 0;
my %UnavailableDev = ();

my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
my $IgnoreUnmatched = $ENV{'smartd_ignore_unmatched'} || 0;

while (defined(my $ThisLine = <STDIN>)) {
   chomp($ThisLine);
   if ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), No such device(?: or address)?, open\(\) failed/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), is SMART capable. Adding to "monitor" list./ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), found in smartd database./ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), not found in smartd database./ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), opened/)) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), appears to lack SMART*/ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), enabled autosave \(cleared GLTSD bit\)\./ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), enabled SMART Attribute Autosave/ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), enabled SMART Automatic Offline Testing/ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), Self-Test Log error count increased from \d+ to \d+/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), new Self-Test Log error at hour timestamp \d+/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), same Attribute has different ID numbers:/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Num *Test_Description *Status *Remaining *LifeTime/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^# *[0-9]+  Short offline *Completed:/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^# *[0-9]+  Extended offline *Completed:/ )) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^# *[0-9]+  Offline *Fatal or unknown error/ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), not capable of SMART self-check/ )) {
       # ignore
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), is in STANDBY mode, skipping checks/ )) {
       # ignore
   } elsif ( $ThisLine =~ /^file \/var\/run\/smartd.pid written containing PID [0-9]+/ ) {
       # ignore
   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^ *$/ )) {
       # ignore empty lines
   } elsif ( ($ThisLine =~ /^smartd version/)
          || ($ThisLine =~ /^Home page/)
          || ($ThisLine =~ /configuration file/i)
          || ($ThisLine =~ /\[trip Temperature is \d+ Celsius\]/)
          || ($ThisLine =~ /^Monitoring/)
          || ($ThisLine =~ /smartd received signal 15: Terminated/)
          || ($ThisLine =~ /smartd is exiting \(exit status 0\)/)
          || ($ThisLine =~ /smartd has fork/)
	  || ($ThisLine =~ /smartd (startup|shutdown) succeeded/)
	  || ($ThisLine =~ /Unable to register device (.*) \(no Directive -d removable\). Exiting/)
	  || ($ThisLine =~ /Device (.*), SATA disks accessed via libata are not currently supported by smartmontools./) 
	  || ($ThisLine =~ /Device: (.*), IE \(SMART\) not enabled, skip device Try '.*' to turn on SMART features/) 
	  || ($ThisLine =~ /Device: (.*), Bad IEC (SMART) mode page, err=-5, skip device/))
   {
       # ignore

#   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), (.*)$/)) {
#      $ParamChanges{$Device}{$Msg}++;
   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), not found in smartd database./ )) {
      $NotInDatabase{$Device}++;
   } elsif ( my ($Device,$AttribType,$Code,$Name,undef,undef,$NewVal) = ($ThisLine =~ /^Device: ([^,]+), SMART ([A-Za-z]+) Attribute: ([0-9]+) ([A-Za-z_]+) changed from ([0-9]+) (\[Raw [0-9]+\] )?to ([0-9]+)/)) {
      push (@{$ParamChanges{$Device}{"$AttribType: $Name ($Code)"}}, $NewVal);
   # smartd reports temperature changes this way only for SCSI disks
   } elsif ( my ($Device,$NewVal) = ($ThisLine =~ /^Device: ([^,]+), initial Temperature is (\d+) Celsius/)) {
      push @{$TempChanges{$Device}},$NewVal;
   } elsif ( my ($Device,$NewVal) = ($ThisLine =~ /^Device: ([^,]+), Temperature changed -?\d+ Celsius to (\d+) Celsius/)) {
      push @{$TempChanges{$Device}},$NewVal;
   } elsif ( my ($Device, $Num) = ($ThisLine =~ /^Device: ([^,]+), (\d+) Currently unreadable \(pending\) sectors/) ) {
      $Pendsectors{$Device}++;
      $NumPendsectors{$Device} = $Num;
   } elsif ( my ($Device, $Num) = ($ThisLine =~ /^Device: ([^,]+), (\d+) Offline uncorrectable sectors/) ) {
      $Offsectors{$Device}++;
      $NumOffsectors{$Device} = $Num;
   } elsif ( my ($Device,$TestType) = ($ThisLine =~ /^Device: ([^,]+), starting scheduled (Short|Long) Self-Test/) ) {
      $SelfTest{$Device}{$TestType}++;
   } elsif ( my ($Device,$AttribType,$Code,$Name) = ($ThisLine =~ /^Device: ([^,]+), Failed SMART ([A-Za-z]+) Attribute: ([0-9]+) ([A-Za-z_]+)/)) {
      $Failed{$Device}{"$AttribType attribute: $Name ($Code)"}++;
   } elsif ( ( $ThisLine =~ /warning/i ) ) {
      $Warnings{$ThisLine}++;
   } elsif ( my ($Device, $Text) = ( $ThisLine =~ /^Device: ([^,]+), (can't monitor.*)$/i ) ) {
      $CantMonitor{$Device}{$Text}++;
   } elsif ( ($ThisLine =~ /smartd startup failed/ ) ) {
      $StartupFailed++;
   } elsif ( ($ThisLine =~ /smartd shutdown failed/ ) ) {
      $ShutdownFailed++;
   } elsif ( my ($Device,$DLine) = ($ThisLine =~ /Unable to register SCSI device (.*) at line ([0-9]*) of file/) ) {
      $UnableToReg{"$Device,$DLine"}++  
   } elsif ( ($Device) = ($ThisLine =~ /Device ([^ ]+) not available/)) {
      $UnavailableDev{$Device}++;
   } else {
      # Report any unmatched entries...
      push @OtherList,"$ThisLine\n";
   }

}

if (keys %NotInDatabase) {
   print "\n";
   foreach my $Device (sort keys %NotInDatabase) {
      print "$Device not in smartd database.\n";
   }
   
}

if (keys %CantMonitor) {
   foreach my $Device (sort keys %ParamChanges) {
      print "\n$Device :\n";
      foreach my $Line (sort keys %{$CantMonitor{$Device}}) {
         print "  $Line - " . $CantMonitor{$Device}{$Line} . " Time(s)\n";
      }
   }
}

if (keys %ParamChanges) {
   foreach my $Device (sort keys %ParamChanges) {
      print "\n$Device :\n";
      foreach my $Msg (sort keys %{$ParamChanges{$Device}}) {
         print "   $Msg changed to ";
         my $count=0;
         foreach (@{$ParamChanges{$Device}{$Msg}}) {
           # print 12 values to each line
           if ($count % 12 == 0) {
             print "\n     ";
           }
           print "$_, ";
           $count++;
         }
         print "\n";
      }
   }
}

if (keys %TempChanges) {
       print "Temperature Changes\n==================\n";
       my (@min,@max);
   foreach my $Device (sort keys %TempChanges) {
      if($Detail < 10) {
                       my @sorttemp = sort @{$TempChanges{$Device}};
                       push @min, $sorttemp[0];
                       push @max, $sorttemp[$#sorttemp];
      } elsif($Detail < 20) {
                       my @sorttemp = sort @{$TempChanges{$Device}};
                       print "$Device :  $sorttemp[0] - $sorttemp[$#sorttemp]\n";
               } else {
                       print "$Device : ";
                       print join ", ",@{$TempChanges{$Device}};
                       print "\n";
               }
   }
       if($Detail < 10) {
          my @sorttemp = sort @min;
               my $mint = $sorttemp[0];
          my @sorttemp = sort @max;
               my $maxt = $sorttemp[$#sorttemp];
          print "All devices: $mint - $maxt\n";
       }
}

if (keys %Pendsectors){
   print "\nCurrently unreadable (pending) sectors detected:\n";
   foreach my $Device (sort keys %Pendsectors) {
      print "\t" . $Device . " - " . $Pendsectors{$Device} . " Time(s)\n";
      print "\t" . $NumPendsectors{$Device} . " unreadable sectors detected\n";
   }

}

if (keys %Offsectors){
   print "\nOffline uncorrectable sectors detected:\n";
   foreach my $Device (sort keys %Offsectors) {
      print "\t" . $Device . " - " . $Offsectors{$Device} . " Time(s)\n";
      print "\t" . $NumOffsectors{$Device} . " offline uncorrectable sectors detected\n";
   }

}

if (keys %Failed) {
   foreach my $Device (sort keys %Failed) {
      print "\n$Device :\n";
      foreach my $Msg (sort keys %{$Failed{$Device}}) {
         print "   Failed $Msg " . $Failed{$Device}{$Msg} . " Time(s)\n";
      }
   }
}

if (keys %SelfTest) {
   foreach my $Device (sort keys %SelfTest) {
      print "\n$Device :\n";
      foreach my $Type (sort keys %{$SelfTest{$Device}}) {
         print "   started scheduled $Type self-test " . $SelfTest{$Device}{$Type} . " Time(s)\n";
      }
   }
}

if ( (keys %Warnings) ) {
   print "\nWarnings:\n";
   foreach my $Line (sort {$Warnings{$b} <=> $Warnings{$a}} keys %Warnings) {
      print "\t" . $Line . " - ". $Warnings{$Line} . " Time(s)\n";
   }
}

if ($StartupFailed) {
   print "\n Smartd startup failed: " . $StartupFailed . " Time(s)\n";
}

if ($ShutdownFailed) {
   print "\n Smartd shutdown failed: " . $ShutdownFailed . " Time(s)\n";
}

if ( (keys %UnableToReg) ) {
   print "\n Wrong configuration for devices:\n";
   foreach (sort keys %UnableToReg) {
      ($Device,$DLine) = split ",";
      print "   " . $Device . (" (line ") . $DLine . ") : ". $UnableToReg{"$Device,$DLine"} . " Time(s)\n";
   }
}

if (%UnavailableDev) {
   print "\nUnavailable device:\n";
   foreach my $Device (sort keys %UnavailableDev) {
      print "   Device " . $Device . " : " . $UnavailableDev{$Device} . " Time(s)\n";
   }
}

if (($#OtherList >= 0) and (not $IgnoreUnmatched)){
   print "\n**Unmatched Entries**\n";
   print @OtherList;
}

exit(0);

# vi: shiftwidth=3 tabstop=3 syntax=perl et