@@ -72,6 +72,8 @@ Switches:
7272-u Update
7373-p Pretty print the JSON.
7474-Z GZip+Base64 compress the results.
75+ -v Verbose output (print status info to STDERR)
76+ -V Print version and exit
7577
7678-g Guess at the config and print it to STDOUT
7779-C Enable manual checking for guess and cciss.
@@ -105,6 +107,7 @@ use JSON qw( decode_json );
105107use MIME::Base64 qw( encode_base64 ) ;
106108use IO::Compress::Gzip qw( gzip) ;
107109use Scalar::Util qw( looks_like_number ) ;
110+ use List::Util qw( min ) ;
108111
109112my $cache = ' /var/cache/smart' ;
110113my $smartctl = ' /usr/bin/env smartctl' ;
@@ -114,11 +117,13 @@ my $useSN = 1;
114117$Getopt::Std::STANDARD_HELP_VERSION = 1;
115118
116119sub main ::VERSION_MESSAGE {
117- print " SMART SNMP extend 0.3.2 \n " ;
120+ print " SMART SNMP extend 0.3.4 \n " ;
118121}
119122
120123sub main ::HELP_MESSAGE {
121124 &VERSION_MESSAGE;
125+ print " \n " . " -v Verbose output\n " ;
126+ print " -V Print version and exit\n " ;
122127 print " \n " . " -u Update '" . $cache . " '\n " . ' -g Guess at the config and print it to STDOUT
123128-c <config> The config file to use.
124129-p Pretty print the JSON.
@@ -148,13 +153,17 @@ Scan Modes:
148153
149154# gets the options
150155my %opts = ();
151- getopts( ' ugc:pZhvCSGt:U' , \%opts );
156+ my $verbose = 0;
157+ getopts( ' ugc:pZhvVCSGt:U' , \%opts );
152158
153159if ( $opts {h } ) {
154160 &HELP_MESSAGE;
155161 exit ;
156162}
157163if ( $opts {v } ) {
164+ $verbose = 1;
165+ }
166+ if ( $opts {V } ) {
158167 &VERSION_MESSAGE;
159168 exit ;
160169}
@@ -578,6 +587,10 @@ my $to_return = {
578587 ' error' => 0,
579588 ' errorString' => ' ' ,
580589};
590+
591+ if ($verbose ) {
592+ print " Processing " . scalar (@disks ) . " disks (useSN=$useSN )\n " ;
593+ }
581594foreach my $line (@disks ) {
582595 my $disk ;
583596 my $name ;
@@ -591,7 +604,28 @@ foreach my $line (@disks) {
591604 $disk = ' /dev/' . $disk ;
592605 }
593606
607+ if ($verbose ) {
608+ print " Processing disk: $name -> $disk \n " ;
609+ }
610+
611+ if ($verbose ) {
612+ print " Command: $smartctl --json -a $disk \n " ;
613+ }
614+
594615 my $output = ` $smartctl --json -a $disk ` ;
616+ my $exit_code = $? >> 8;
617+
618+ if ($verbose && $exit_code != 0) {
619+ print " WARNING: smartctl exit code: $exit_code \n " ;
620+ my @output_lines = split (/ \n / , $output );
621+ if (@output_lines > 0) {
622+ print " First few lines of output:\n " ;
623+ for my $i (0..min($#output_lines , 5)) {
624+ print " $output_lines [$i ]\n " ;
625+ }
626+ }
627+ }
628+
595629 my %IDs = (
596630 ' 5' => undef ,
597631 ' 10' => undef ,
@@ -776,6 +810,9 @@ foreach my $line (@disks) {
776810 } # # end if ( defined( $a_output->{'ata_smart_attributes'...}))
777811
778812 # get the selftest logs
813+ if ($verbose ) {
814+ print " Command: $smartctl -l selftest $disk \n " ;
815+ }
779816 $output = ` $smartctl -l selftest $disk ` ;
780817 my @outputA = split ( / \n / , $output );
781818 my @completed = grep ( / Completed/ , @outputA );
@@ -1029,15 +1066,40 @@ foreach my $line (@disks) {
10291066
10301067 # only bother to save this if useSN is not being used
10311068 if ( !$useSN ) {
1069+ if ($verbose ) {
1070+ print " Adding disk (useSN disabled): $disk_id \n " ;
1071+ }
10321072 $to_return -> {data }{disks }{$disk_id } = \%IDs ;
1033- } elsif ( $IDs {exit } == 0 && defined ($disk_id ) ) {
1073+ } elsif ( $IDs {' json_err' } == 0 && defined ($disk_id ) && defined ( $IDs {' serial' } ) ) {
1074+ if ($verbose ) {
1075+ my $exit_info = ' ' ;
1076+ if ( $IDs {exit } != 0 ) {
1077+ $exit_info = " (smartctl exit: " . ($IDs {exit } >> 8) . " )" ;
1078+ }
1079+ print " Adding disk: $disk_id (serial: $IDs {serial}$exit_info )\n " ;
1080+ }
10341081 $to_return -> {data }{disks }{$disk_id } = \%IDs ;
1082+ } else {
1083+ if ($verbose ) {
1084+ my $reason = ' ' ;
1085+ if ( !defined ($disk_id ) ) {
1086+ $reason = ' undefined disk_id' ;
1087+ } elsif ( !defined ( $IDs {' serial' } ) ) {
1088+ $reason = ' no serial number' ;
1089+ } elsif ( $IDs {' json_err' } != 0 ) {
1090+ $reason = " JSON parse error" ;
1091+ }
1092+ print " Skipping disk: $name (reason: $reason )\n " ;
1093+ }
10351094 }
10361095
10371096 # smartctl will in some cases exit zero when it can't pull data for cciss
10381097 # so if we get a zero exit, but no serial then it means something errored
10391098 # and the device is likely dead
10401099 if ( $IDs {exit } == 0 && !defined ( $IDs {serial } ) ) {
1100+ if ($verbose ) {
1101+ print " Marking disk as unhealthy (no serial): $name \n " ;
1102+ }
10411103 $to_return -> {data }{unhealthy }++;
10421104 }
10431105} # # end foreach my $line (@disks)
@@ -1055,6 +1117,13 @@ $compressed =~ s/\n//g;
10551117$compressed = $compressed . " \n " ;
10561118
10571119if ( !$noWrite ) {
1120+ if ($verbose ) {
1121+ my @disk_keys = keys %{ $to_return -> {data }{disks } };
1122+ print " Writing " . scalar (@disk_keys ) . " disks to cache\n " ;
1123+ print " Exit non-zero: $to_return ->{data}{exit_nonzero}\n " ;
1124+ print " Dev errors: $to_return ->{data}{dev_error}\n " ;
1125+ print " Unhealthy: $to_return ->{data}{unhealthy}\n " ;
1126+ }
10581127 open ( my $writefh , " >" , $cache ) or die " Can't open '" . $cache . " '" ;
10591128 print $writefh $toReturn ;
10601129 close ($writefh );
0 commit comments