#!/usr/bin/perl -w
#
# Munin plugin for MegaRAID 
# This plugin can graph:- Currently Drive Temperature and Error Count
# 
#---------------------
# Examples
# Create a symbolic link to MegaRaid_<AdapterNumber>_<temp|error|other|predictive>
#       ln -s /usr/share/munin/plugins/MegaRaid_ /etc/munin/plugins/MegaRaid_0_temp
#           graph temperature on adapter 0
# 
#       ln -s /usr/share/munin/plugins/MegaRaid_ /etc/munin/plugins/MegaRaid_0_error
#           graph media errors on adapter 0
# 
#       ln -s /usr/share/munin/plugins/MegaRaid_ /etc/munin/plugins/MegaRaid_1_temp
#           graph temperature on adapter 1
# 
#---------------------
# Log
# Revision 0.1  2011/04/16  idobson
# -First version only basic support of the MegaRaid controller
# 
# Revision 0.2  2011/04/17 fkatzenb
# -Added bash statement to remove the log file created each time MegaCli64 is ran
# -Added a few comments and visual changes
# 
# Revision 1.0 2011/04/17 fkatzenb
# -Revamped Code to symbolic link for sensor type and future growth
# 
# Revision 1.1 2011/04/17 fkatzenb
# -Revised scalling
# 
# Revision 1.2 2011/04/28 fkatzenb
# -Added support for graph_info support
# -Added warning & critical alerts support
# -Added data info
# 
# Revision 2.0 2011/04/29 fkatzenb
# -Added remaining support for SMART Errors
# 
# Revision 2.1 2011/04/29 fkatzenb
# -Added version information for in the graph description
# 
# 
#---------------------
# 
# Add the following to your /etc/munin/plugin-conf.d/munin-node:
# 
#       [MegaRaid_*]
#       user root
# 
#---------------------
# 
# 
# Magic markers (optional - used by munin-config and installation scripts):
# 
#%# family=auto
#%# capabilities=autoconf
# 
my $DisplayVer=2.1;

use strict;
use warnings;

my $DevID=0; 		#Device Number found
my $DevData=0; 		#Device Data found 

# Parse out Adapter number and parameter desired from file name and remove whitespace
my $Parameters=`basename $0 | sed 's/^MegaRaid_//g' | tr '_' '-'` ;	
chomp $Parameters;
my ($Adapter,$Type)=split(/-/,$Parameters);

# Locate MegaCli64 application and remove whitespace
my $Command=`which MegaCli64`;
chomp $Command;

# Use this to define future parameters to monitor
my %config = (
  temp => {
    lookfor => 'Drive Temperature :',
    label => 'Temp',
    title => "MegaRAID Adapter $Adapter: Drive Temperatures",
    vlabel => 'Celsius',
    graph_args => '--base 1000 -l 0',
    warning => '55',
    critical => '65',
    info_tag => "Temperature (C)",
    description => "Internal Temperatures for drives on Adapter $Adapter."
  },
  error => {
    lookfor => 'Media Error Count: ',
    label => 'Media Err',
    title => "MegaRAID Adapter $Adapter: Media Errors (SMART)",
    vlabel => 'Number of Errors',
    graph_args => '--base 1000 -l 0',
    warning => '',
    critical => '',
    info_tag => "Media Errors (SMART)",
    description => "Number of SMART errors related to the drive's media on Adapter $Adapter."
  },
  other => {
    lookfor => 'Other Error Count: ',
    label => 'Other Err',
    title => "MegaRAID Adapter $Adapter: Others Errors (SMART)",
    vlabel => 'Number of Errors',
    graph_args => '--base 1000 -l 0',
    warning => '',
    critical => '',
    info_tag => "Other Errors (SMART)",
    description => "Number of SMART errors not related to the drive's media on Adapter $Adapter."
  },
  predictive => {
    lookfor => 'Predictive Failure Count: ',
    label => 'Predictive Err',
    title => "MegaRAID Adapter $Adapter: Predictive Errors (SMART)",
    vlabel => 'Number of Errors',
    graph_args => '--base 1000 -l 0',
    warning => '',
    critical => '',
    info_tag => "Predictive Errors (SMART)",
    description => "Number of SMART errors for each drive on Adapter $Adapter."
  }
);

#Auto config options
if ($ARGV[0] and $ARGV[0] eq "autoconf" ) {
   if (-e $Command ) {
      print "yes\n";
      exit 0;
      } else {
      print "no\n";     
      exit 1
     }
}

#Read Output of MegaRaid command
$Command.=" -PDList -a".$Adapter; 
my @Output=qx($Command);

#Munin Config Options
if ($ARGV[0] and $ARGV[0] eq "config"){
   print "graph_title $config{$Type}->{title}\n";
   print "graph_vlabel $config{$Type}->{vlabel}\n";
   print "graph_args $config{$Type}->{graph_args}\n";
   print "graph_scale yes\n";
   print "graph_category disk\n";
   print "graph_info $config{$Type}->{description} <br />Generated by MegaRaid_, Version $DisplayVer<br />\n";
    
   foreach my $Line (@Output) {
      $Line=~ s/\r//g;
      $Line=~ s/\n//g;
      
      #Find the device ID
      if ( $Line=~ m/Slot Number: /i ) { 
         $DevID=$Line; 
         $DevID=~ s/Slot Number: //;
         print "A".$Adapter."_D".$DevID."_$Type.label A$Adapter:D$DevID $config{$Type}->{label}\n";
         print "A".$Adapter."_D".$DevID."_$Type.info Adapter: $Adapter / Drive: $DevID - $config{$Type}->{info_tag}\n";
         if ($config{$Type}->{warning} ne '' ) {
            print "A".$Adapter."_D".$DevID."_$Type.warning $config{$Type}->{warning}\n";
            }
         if ($config{$Type}->{critical} ne '') {
            print "A".$Adapter."_D".$DevID."_$Type.critical $config{$Type}->{critical}\n";
            }   
      }
   } 
   exit 0;
}

#Actually dump the data
foreach my $Line (@Output) {
   $Line=~ s/\r//g;
   $Line=~ s/\n//g;

   #Find the device ID
   if ( $Line=~ m/Slot Number: /i ) { $DevID=$Line; $DevID=~ s/Slot Number: //; chomp $DevID; }

   #Find the data and print it out
   if ( $Line=~ m/$config{$Type}->{lookfor}/i ) { 
      $DevData=$Line;
      $DevData=~s/$config{$Type}->{lookfor}//;
      $DevData=~s/C.*//;
      chomp $DevData;
      print "A".$Adapter."_D".$DevID."_$Type.value $DevData\n";
   }
}

#Remove log file created by running MegaCli
   unlink "MegaSAS.log";

exit 0;
