Skip to content

Commit ca2065c

Browse files
Add verbose output for smartctl commands in smart-v1 script (#614)
1 parent ad01567 commit ca2065c

1 file changed

Lines changed: 72 additions & 3 deletions

File tree

snmp/smart-v1

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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 );
105107
use MIME::Base64 qw( encode_base64 );
106108
use IO::Compress::Gzip qw(gzip);
107109
use Scalar::Util qw( looks_like_number );
110+
use List::Util qw( min );
108111

109112
my $cache = '/var/cache/smart';
110113
my $smartctl = '/usr/bin/env smartctl';
@@ -114,11 +117,13 @@ my $useSN = 1;
114117
$Getopt::Std::STANDARD_HELP_VERSION = 1;
115118

116119
sub main::VERSION_MESSAGE {
117-
print "SMART SNMP extend 0.3.2\n";
120+
print "SMART SNMP extend 0.3.4\n";
118121
}
119122

120123
sub 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
150155
my %opts = ();
151-
getopts( 'ugc:pZhvCSGt:U', \%opts );
156+
my $verbose = 0;
157+
getopts( 'ugc:pZhvVCSGt:U', \%opts );
152158

153159
if ( $opts{h} ) {
154160
&HELP_MESSAGE;
155161
exit;
156162
}
157163
if ( $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+
}
581594
foreach 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

10571119
if ( !$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

Comments
 (0)