[Logwatch-Devel] smartd patch

Mark Nienberg gmane at tippingmar.com
Tue Feb 7 15:28:31 MST 2006


Apologies if this is a duplicate msg.  I think my first attempt bounced.

The attached patch for the smartd service provides the following 
enhancements:

First, it lists the changes in parameters in the correct order and 
doesn't leave any out. This allows you to see the trend (if there is 
one).  For example:

/dev/twa0 [3ware_disk_01] :
     Usage: SomeAttribute (190) changed to
       98, 99, 97, 99, 98, 97, 96, 97,

The old version would sort these and remove duplicates, which made it 
appear that the values were always rising.  For example, it would yield: 
96, 97, 98, 99 for the above example, which gives the wrong impression.


Second, it reports on Failed attributes separately, like this:

/dev/twa0 [3ware_disk_02] :
     Failed usage attribute: SomeAttribute (190) 10 Time(s)


Third, it reports self tests like this:

/dev/twa0 [3ware_disk_00] :
     started scheduled Long self-test 1 Time(s)
     started scheduled Short self-test 2 Time(s)

Finally, it cleans up a couple more unrecognized lines.

Mark Nienberg
Tipping Mar + associates
Berkeley, CA
-------------- next part --------------
--- smartd.orig	2006-01-18 21:34:25.000000000 -0800
+++ smartd	2006-02-07 11:35:15.000000000 -0800
@@ -13,6 +13,8 @@
 my %Offsectors = ();
 my %NumOffsectors = ();
 my %Warnings = ();
+my %SelfTest = ();
+my %Failed = ();
 my @OtherList = ();
 
 my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0;
@@ -26,14 +28,14 @@
        # 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,$Test) = ($ThisLine =~ /^Device: ([^,]+), starting scheduled (Short|Long) Self-Test\./ )) {
-       # 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+/ )) {
@@ -60,13 +62,14 @@
           || ($ThisLine =~ /smartd received signal 15: Terminated/)
           || ($ThisLine =~ /smartd is exiting \(exit status 0\)/)
           || ($ThisLine =~ /smartd has fork/)
+          || ($ThisLine =~ /enabled SMART Automatic Offline Testing/)
           || ($ThisLine =~ /smartd startup succeeded/)  ) {
        # ignore
 
 #   } elsif ( ($Device,$Msg) = ($ThisLine =~ /^Device: ([^,]+), (.*)$/)) {
 #      $ParamChanges{$Device}{$Msg}++;
    } 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]+)/)) {
-      $ParamChanges{$Device}{"$AttribType: $Name ($Code)"}{$NewVal}++;
+      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;
@@ -78,6 +81,10 @@
    } 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}++;
    } else {
@@ -92,15 +99,16 @@
       print "\n$Device :\n";
       foreach my $Msg (sort keys %{$ParamChanges{$Device}}) {
          print "   $Msg changed to ";
-         my $vv="";
-         foreach my $Val (sort keys %{$ParamChanges{$Device}{$Msg}}) {
-            if (! $vv eq "") {
-               print "$vv, ";
-            }
-            $vv = "$Val";
-            #$vv .= " ($ParamChanges{$Device}{$Msg}{$Val} times)";
+         my $count=0;
+         foreach (@{$ParamChanges{$Device}{$Msg}}) {
+           # print 12 values to each line
+           if ($count % 12 == 0) {
+             print "\n     ";
+           }
+           print "$_, ";
+           $count++;
          }
-         print "$vv\n";
+         print "\n";
       }
    }
 }
@@ -149,6 +157,24 @@
 
 }
 
+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) {


More information about the Logwatch-Devel mailing list