Subversion Repositories vnag

Rev

Rev 77 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * VNag - Nagios Framework for PHP
  5.  * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
  6.  * Licensed under the terms of the Apache 2.0 license
  7.  *
  8.  * Revision 2023-10-13
  9.  */
  10.  
  11. declare(ticks=1);
  12.  
  13. class MegaRaidCheck extends VNag {
  14.         private $argCmd = null;
  15.  
  16.         public function __construct() {
  17.                 parent::__construct();
  18.  
  19.                 if ($this->is_http_mode()) {
  20.                         // Don't allow the standard arguments via $_REQUEST
  21.                         $this->registerExpectedStandardArguments('');
  22.                 } else {
  23.                         $this->registerExpectedStandardArguments('Vhtv');
  24.                 }
  25.  
  26.                 $this->addExpectedArgument($this->argCmd = new VNagArgument('E', 'executable', VNagArgument::VALUE_OPTIONAL, 'executable', 'The path to the MegaCli64 executable.', '/opt/MegaRAID/MegaCli/MegaCli64'));
  27.  
  28.                 $this->getHelpManager()->setPluginName('vnag_megaraid');
  29.                 $this->getHelpManager()->setVersion('2023-10-13');
  30.                 $this->getHelpManager()->setShortDescription('This plugin checks the controller and disk status of a MegaRAID controller (using MegaCli64).');
  31.                 $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
  32.                 $this->getHelpManager()->setSyntax('$SCRIPTNAME$');
  33.                 $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
  34.         }
  35.  
  36.         private function megacli_logical_disk_status($adapter='ALL') {
  37.                 $mock_file = __DIR__.'/status_ld.mock';
  38.  
  39.                 if (file_exists($mock_file)) {
  40.                         $out = explode("\n", file_get_contents($mock_file));
  41.                 } else {
  42.                         $cmd = escapeshellcmd($this->argCmd->getValue()).' -LDInfo -Lall '.escapeshellarg('-a'.$adapter).' -NoLog';
  43.                         $out = array();
  44.                         exec($cmd, $out, $ec);
  45.  
  46.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  47.                 }
  48.  
  49.                 $drives = [];
  50.                 $cur_drive_id = '???';
  51.                 $cur_drive_name = '';
  52.                 foreach ($out as $line) {
  53.                         if (preg_match('@Virtual Drive: (\d+)@', $line, $m)) $cur_drive_id = $m[1];
  54.                         if (preg_match('@Name\s*:([^\n]*)@', $line, $m)) $cur_drive_name = trim($m[1]);
  55.                         if (preg_match('@State\s*:([^\n]*)@', $line, $m)) {
  56.                                 $drives[] = [$cur_drive_id, $cur_drive_name, trim($m[1])];
  57.                                 $cur_drive_id = '???';
  58.                                 $cur_drive_name = '';
  59.                         }
  60.                 }
  61.  
  62.                 $drives_ok = 0;
  63.                 $drives_fail = 0;
  64.  
  65.                 foreach ($drives as list($cur_drive_id, $cur_drive_name, $cur_drive_status)) {
  66.                         if (strtolower($cur_drive_status) == 'offline') $status = VNag::STATUS_CRITICAL/*?*/;
  67.                         else if (strpos($cur_drive_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL;
  68.                         else if (strtolower($cur_drive_status) == 'optimal') $status = VNag::STATUS_OK;
  69.                         else if (strtolower($cur_drive_status) == 'initialize') $status = VNag::STATUS_WARNING;
  70.                         else if (strtolower($cur_drive_status) == 'checkconsistency') $status = VNag::STATUS_WARNING;
  71.                         else $status = VNag::STATUS_UNKNOWN;
  72.  
  73.                         if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
  74.  
  75.                         $cur_drive_hf_name = $cur_drive_id . (!empty($cur_drive_name) ? " ($cur_drive_name)" : "");
  76.                         $msg = "Logical drive $cur_drive_hf_name: $cur_drive_status";
  77.                         $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  78.                         $this->addVerboseMessage($msg, $verbosity);
  79.                         $this->setStatus($status);
  80.                 }
  81.  
  82.                 $drives_total = $drives_ok + $drives_fail;
  83.                 return "$drives_fail/$drives_total arrays with problems";
  84.         }
  85.  
  86.         private function megacli_smart_disk_status($adapter='ALL') {
  87.                 $mock_file = __DIR__.'/status_pd.mock';
  88.  
  89.                 if (file_exists($mock_file)) {
  90.                         $out = explode("\n", file_get_contents($mock_file));
  91.                 } else {
  92.                         $cmd = escapeshellcmd($this->argCmd->getValue()).' -PDList '.escapeshellarg('-a'.$adapter).' -NoLog';
  93.                         $out = array();
  94.                         exec($cmd, $out, $ec);
  95.  
  96.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  97.                 }
  98.  
  99.                 $drives = [];
  100.                 $cur_drive_id = '???';
  101.                 foreach ($out as $line) {
  102.                         if (preg_match('@Slot Number: (\d+)@', $line, $m)) $cur_drive_id = $m[1];
  103.                         if (preg_match('@Drive has flagged a S.M.A.R.T alert\s*:([^\n]*)@', $line, $m)) {
  104.                                 $drives[] = [$cur_drive_id, trim($m[1])];
  105.                                 $cur_drive_id = '???';
  106.                         }
  107.                 }
  108.  
  109.                 $drives_ok = 0;
  110.                 $drives_fail = 0;
  111.  
  112.                 foreach ($drives as list($cur_drive_id, $cur_drive_status)) {
  113.                         if (strtolower($cur_drive_status) == 'no') $status = VNag::STATUS_OK;
  114.                         else $status = VNag::STATUS_CRITICAL; // unsure if there will be a "yes" or any other output
  115.  
  116.                         if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
  117.  
  118.                         $msg = "Physical drive $cur_drive_id: SMART alert? $cur_drive_status";
  119.                         $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  120.                         $this->addVerboseMessage($msg, $verbosity);
  121.                         $this->setStatus($status);
  122.                 }
  123.  
  124.                 $drives_total = $drives_ok + $drives_fail;
  125.                 return "$drives_fail/$drives_total drives have SMART alerts";
  126.         }
  127.  
  128.         private function megacli_battery_status($adapter='ALL') {
  129.                 $mock_file = __DIR__.'/status_battery.mock';
  130.  
  131.                 if (file_exists($mock_file)) {
  132.                         $out = explode("\n", file_get_contents($mock_file));
  133.                 } else {
  134.                         $cmd = escapeshellcmd($this->argCmd->getValue()).' -AdpBbuCmd '.escapeshellarg('-a'.$adapter).' -NoLog';
  135.                         $out = array();
  136.                         exec($cmd, $out, $ec);
  137.  
  138.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  139.                 }
  140.  
  141.                 $battery_status = '???';
  142.                 foreach ($out as $line) {
  143.                         if (preg_match('@Battery State\s*:([^\n]*)@', $line, $m)) {
  144.                                 $battery_status = trim($m[1]);
  145.                         }
  146.                 }
  147.  
  148.                 if (strtolower($battery_status) == 'missing') $status = VNag::STATUS_WARNING;
  149.                 else if (strtolower($battery_status) == 'optimal') $status = VNag::STATUS_OK;
  150.                 else if (strtolower($battery_status) == 'failed') $status = VNag::STATUS_CRITICAL;
  151.                 else if (strtolower($battery_status) == 'learning') $status = VNag::STATUS_WARNING;
  152.                 else if (strpos($battery_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL;
  153.                 else $status = VNag::STATUS_UNKNOWN;
  154.  
  155.                 $msg = "Battery Status: $battery_status";
  156.                 $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  157.                 $this->addVerboseMessage($msg, $verbosity);
  158.                 $this->setStatus($status);
  159.  
  160.                 return $status == VNag::STATUS_OK ? "Battery OK" : "Battery has problems";
  161.         }
  162.  
  163.         protected function cbRun() {
  164.                 $headlines = '';
  165.                 $headlines .= $this->megacli_logical_disk_status() . ', ';
  166.                 $headlines .= $this->megacli_smart_disk_status() . ', ';
  167.                 $headlines .= $this->megacli_battery_status();
  168.                 $this->setHeadline($headlines, true);
  169.         }
  170. }
  171.