#!/usr/bin/perl -w # # Munin plugin to monitor 3ware RAID controllers: # tw_cli_bbu - the BBU (Battery Backup Unit) capacity in hours. Shows how # long the BBU can keep the controller-cache valid. If any # BBU Attribute (Temperature, Status, ...) is abnormal the # capacity is reported as 0 otherwise the correct value # reported by tw_cli will be displayed. # tw_cli_units - the status of all avaible RAID-Units in the system. The # resulting Diagramm will show the status in numbers between 0 # and 2: # 2 - best possible status - full redudancy avaible, # full performance, all is pretty well. # 1<=x<2 - RAID Unit is ok, full redundancy is avaible but # some maintainence is going on # (verifying/initializing). # 0<=x<1 - RAID Unit is degraded, no or reduced redundancy # is avaible, check your RAID-Unit. # OK(2), Initializing(1+%) Verifying(1+%), Degraded(0), Rebulding (0+%), Migrating(0+%), Others(0) # # tw_cli_drives - the status of all drives in the system. The resulting # Diagramm will show the status in numbers between 0 and 2: # 2 - best possible status - full redudancy avaible, # full performance, all is pretty well. # 1<=x<2 - Drive is ok, full redundancy is avaible but # some maintainence is going on # (verifying/initializing). # 0<=x<1 - RAID Unit is degraded, no or reduced redundancy # is avaible, check your drive. # OK(2), Initializing(1+%) Verifying(1+%), Degraded(0), Rebulding (0+%), Migrating(0+%), Others(0) # # # Authors: Pascal Hofmann, Christian 'Raptor 2101' Kölpin # # Parameters: # # config (required) # autoconf (optional - only used by munin-config) # # Magic markers #%# family=auto #%# capabilities=autoconf suggest use strict; use warnings; my $tw_cli = FindBinary('tw_cli'); my $mode = $0 =~ /.*tw_cli_(\w+)$/ ? lc($1) : 'controller'; my $desc = { 'units' => { 'graph_title' => 'RAID-unit status', 'graph_vlabel' => 'Status', # 'graph_info' => '', 'graph_args' => '--base 1000 --lower-limit 0 --upper-limit 2', }, 'drives' => { 'graph_title' => 'Drive status', 'graph_vlabel' => 'Status', # 'graph_info' => '', 'graph_args' => '--base 1000 --lower-limit 0 --upper-limit 2', }, 'bbu' => { 'graph_title' => 'BBU Capactiy', 'graph_vlabel' => 'Capacity in Hours', # 'graph_info' => '', 'graph_args' => '--base 1000 --lower-limit 0', }, }; sub FindBinary { my ($name) = @_; my $bin = exists $ENV{$name} ? $ENV{$name} : undef; $bin = `which $name` unless $bin; chomp $bin; $bin = undef unless -x $bin; my @dirs = qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin); until ($bin or @dirs == 0) { my $dir = shift @dirs; my $path = "$dir/$name"; $bin = $path if -x $path; } return $bin; } # ______________________________________________________________________________ # # tw_cli_units # ______________________________________________________________________________ sub tw_cli_units { my ($config) = @_; my @stringArray; open(my $query_controller_list, "$tw_cli show|") or die "Could not open tw_cli, $!"; while (<$query_controller_list>) { next unless ($_ =~ m/(^c(\d)*)/); my $controller_id = $1; open(my $query_unitcount,"$tw_cli /$controller_id show numunits|") or die "Could not open tw_cli, $!"; @stringArray = split('=', <$query_unitcount>); next unless ($stringArray[1] =~ m/(\d+)/); my $unit_count = $1; for (my $unit_number = 0; $unit_number < $unit_count; $unit_number++) { # Get unit name open(my $query_unitname, "$tw_cli /$controller_id/u$unit_number show name|") or die "Could not open tw_cli, $!"; @stringArray = split('=', <$query_unitname>); my $unit_name = "Unit$unit_number"; $unit_name = $1 if ($stringArray[1] =~ m/(\w+)/); my $label = "${controller_id}_u$unit_number"; if ($config) { print "$label.label $unit_name\n"; print "$label.warning 0.99:\n"; print "$label.critical 0.01:\n"; next; } open(my $query_status_list, "$tw_cli /$controller_id/u$unit_number show|") or die "Could not open tw_cli, $!"; while (<$query_status_list>) { next unless($_ =~ /RAID-\d/); my $value = 0; my ($unit, $type, $status, $rebuild_progress, $misc_progress) = split(' ', $_); if ($status eq 'OK') { $value = 2; } elsif ($status =~ /^VERIFY/ or $status =~ /^INIT/) { # Possible Status: VERIFYING and VERIFY-PAUSED # Possible Status: INITIALIZING and INIT-PAUSED $value = 1; if ($misc_progress =~ m/(\d+)/) { $value += $1/100; } } elsif ($status =~ /^MIGRAT/) { # Possible Status: MIGRATING and MIGRATE-PAUSED $value = 0; if ($misc_progress =~ m/(\d+)/) { $value += $1/100; } } elsif ($status =~ /^REBUILD/) { # Possible Status: REBUILDING and REBUILD-PAUSED $value = 0; if ($rebuild_progress =~ m/(\d+)/) { $value += $1/100; } } print "$label.value $value\n"; } } } } # ______________________________________________________________________________ # # tw_cli_drives # ______________________________________________________________________________ sub tw_cli_drives { my ($config) = @_; my @stringArray; open(my $query_controller_list, "$tw_cli show|") or die "Could not open tw_cli, $!"; while (<$query_controller_list>) { next unless ($_ =~ m/(^c(\d)*)/); my $controller_id = $1; open(my $query_unitcount,"$tw_cli /$controller_id show numunits|") or die "Could not open tw_cli, $!"; @stringArray = split('=', <$query_unitcount>); next unless ($stringArray[1] =~ m/(\d+)/); my $unit_count = $1; for (my $unit_number = 0; $unit_number < $unit_count; $unit_number++) { # Get unit name open(my $query_unitname, "$tw_cli /$controller_id/u$unit_number show name|") or die "Could not open tw_cli, $!"; @stringArray = split('=', <$query_unitname>); my $unit_name = "Unit$unit_number"; $unit_name = $1 if ($stringArray[1] =~ m/(\w+)/); open(my $query_status_list, "$tw_cli /$controller_id/u$unit_number show|") or die "Could not open tw_cli, $!"; while (<$query_status_list>) { next unless($_ =~ /DISK/); my ($unit, $type, $status, $rebuild_progress, $misc_progress, $port) = split(' ',$_); my $label = "${controller_id}_u${unit_number}_$port"; if ($config) { print "$label.label $unit_name Drive $port\n"; print "$label.warning 0.99:\n"; print "$label.critical 0.01:\n"; next; } my $value = 0; if ($status eq 'OK') { $value = 2; } elsif ($status =~ /^VERIFY/ or $status =~ /^INIT/) { # Possible Status: VERIFYING and VERIFY-PAUSED # Possible Status: INITIALIZING and INIT-PAUSED $value = 1; if ($misc_progress =~ m/(\d+)/) { $value += $1/100; } } elsif ($status =~ /^MIGRAT/) { # Possible Status: MIGRATING and MIGRATE-PAUSED $value = 0; if ($misc_progress =~ m/(\d+)/) { $value += $1/100; } } elsif ($status =~ /^REBUILD/) { # Possible Status: REBUILDING and REBUILD-PAUSED $value = 0; if ($rebuild_progress =~ m/(\d+)/) { $value += $1/100; } } print "$label.value $value\n"; } } } } # ______________________________________________________________________________ # # tw_cli_bbu # ______________________________________________________________________________ sub tw_cli_bbu { my ($config) = @_; open(my $query_controller_list, "$tw_cli show|") or die "Could not open tw_cli, $!"; while (<$query_controller_list>) { next unless ($_ =~ /(^c(\d)*)/); my ($controller_id, $controller_name) = split(' ', $_); if ($config) { print "$controller_id.label $controller_name\n"; print "$controller_id.warning 100:\n"; print "$controller_id.critical 50:\n"; next; } open(my $query_controller_information, "$tw_cli /$controller_id show|") or die "Could not open tw_cli, $!"; while (<$query_controller_information>) { next unless ($_ =~ /^bbu/); my ($name, $onlinestate, $bbuready, $status, $volt, $temp, $hours) = split(' ', $_); if ($onlinestate eq 'On' && $bbuready eq 'Yes' && $status eq 'OK' && $volt eq 'OK' && $temp eq 'OK') { print "$controller_id.value $hours\n"; } else { print "$controller_id.value 0\n"; } } } } $ARGV[0] = '' unless (defined($ARGV[0])); if ($ARGV[0] eq 'config') { print "graph_title " . $desc->{$mode}->{"graph_title"} . "\n"; print "graph_vlabel " . $desc->{$mode}->{"graph_vlabel"} . "\n"; # print "graph_info " . $desc->{$mode}->{"graph_info"} . "\n"; print "graph_scale yes\n"; print "graph_category disk\n"; print "graph_args " . $desc->{$mode}->{"graph_args"} . "\n"; if ($mode eq 'units') { tw_cli_units(1); } elsif ($mode eq 'drives') { tw_cli_drives(1); } elsif ($mode eq 'bbu') { tw_cli_bbu(1); } } elsif($ARGV[0] eq 'autoconf') { print "yes\n"; } elsif($ARGV[0] eq 'suggest') { print "units\n"; print "drives\n"; print "bbu\n"; } else { if ($mode eq 'units') { tw_cli_units(0); } elsif ($mode eq 'drives') { tw_cli_drives(0); } elsif ($mode eq 'bbu') { tw_cli_bbu(0); } }