Subversion Repositories vnag

Rev

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

  1. <?php /* <ViaThinkSoftSignature>
  2. jq/ej1RUUthsz1FZirM8duHgne60T2KTbQhO51DfGBEjFOFE85A87oHVBm2AuqjwL
  3. 5FpCdrGNPxR0bSOOrVg5Sa7sgg/L2x/c/XltvFiWd5PCp3xX7mH5Q2g3G3IZtRoYB
  4. aNOxv4dadjGHr4tqw2y211Nb9/dsSm0K7+zRXu5jJGki7T6mrVSc0FnYNE+1IL56A
  5. Pz55VEuqzIhGfpe9W80mzx7j8naQTk9l50sF5MrYNhe7sypVpaqPzdWuvCe2xJ3x2
  6. ui1Z1hZ0tNHcGpyqtB2SYj20E7du9q8ApCS530YSLjvOlttnDQOM8FCEiBJMaqo3K
  7. ZAjRgUeiS8WRwfyIg5FaT+4fojL/zYxW/bbpFeA/5s5IFIGCY6zIt24eaUbryd8tr
  8. EDa2uj5yDS6Hbg7p+W71kZ393OH8YKcHUEdY3i9ZigkognQfpU427IzqbG8AyQVNc
  9. SnZI69IomUgPQan7oRB8EoW1JSOjTjoG/uOdJTtr5S2L+Jn8VwScAvnBubwUEFi/K
  10. 7odB2qIyba6M7vB7c1ZuvrZIpncUPCaEeheo49u0hcF9Uq6Ot4HCeuiA/ks9omQm5
  11. dzpjdmPYk1ESWGT2OEnnLNHDHdKc2zppYlUSEVqoK4wSW+Mz9dOJejuM4WzFD+2N0
  12. YlaNG0Xxc6622ToU89iAEc1pnjdObl9HhIneLDygoqy+1KP/kp8rJCz+aKz/vznoY
  13. qt+P3W51tGq53ee0fvhscILuHjLLTlWUhCUizKXIz8xaksM368lQUwPyX/Lt05DNu
  14. jrGmEGfTc3gE7rHrSHP4CM5gMc2Qx8z9O/klINM/tdFTZ5v6/MuCaqCudBnTFM8Ya
  15. 9y2uOrv8nAy6c6Rse5JnE39TakJ8dg5cym5LlY83ZA2iIF5I3sg7nZv9/EySintwg
  16. 47/AfqdAd/3Oi3pjh2C3kHGe9jUKaBHqjA6CXwmgb+6GccXDuxgeA49UOYEaR8VOU
  17. QJDK/FN/PsM+lnG5l9IZKuYHbDFvyF6dcwmJCh4ssfhLBuYY5nkmFDlUNCicJnd7t
  18. HOyDK82jw7Eixyx5n7BpB6lSFa2sfTJb6XEDj4mmH7ZdV2z2HZ9qS9BFCz9/BE+Lp
  19. pp3dPr/rBMX+r3c4ou/PMuDC+eiGbUy8v53wqUoUdDDJxM1q46fhbrv5zqA64W8OY
  20. PyEpOkvGBGBLi+yRoclqYAk3mxr/AOyLj2fsUyOavj/i1I7k/F7kuAbHmmEToxsQU
  21. 78DzGjFPNrLvWoqi2EIsaSJuw+9OhJSUFgBikRiT4TP0OIInaZaDzCvEq4X78x+IK
  22. ICn+us9G5Ay/qnfHeBM1CA8/S+Qc38YTAvA/AHVUEqAgX8yXJG1f6YE8RHM3GHBb9
  23. Q==
  24. </ViaThinkSoftSignature> */ ?>
  25. <?php
  26.  
  27. /*
  28.  * VNag - Nagios Framework for PHP
  29.  * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
  30.  * Licensed under the terms of the Apache 2.0 license
  31.  *
  32.  * Revision 2023-09-13
  33.  *
  34.  * Changelog:
  35.  * 2023-09-13   1.0   Initial release
  36.  */
  37.  
  38. declare(ticks=1);
  39.  
  40. class MegaRaidCheck extends VNag {
  41.         private $executable = '/opt/MegaRAID/MegaCli/MegaCli64'; // TODO: make configurable (Also with sudo?)
  42.  
  43.         public function __construct() {
  44.                 parent::__construct();
  45.  
  46.                 if ($this->is_http_mode()) {
  47.                         // Don't allow the standard arguments via $_REQUEST
  48.                         $this->registerExpectedStandardArguments('');
  49.                 } else {
  50.                         $this->registerExpectedStandardArguments('Vhtv');
  51.                 }
  52.  
  53.                 $this->getHelpManager()->setPluginName('vnag_megaraid');
  54.                 $this->getHelpManager()->setVersion('1.0');
  55.                 $this->getHelpManager()->setShortDescription('This plugin checks the controller and disk status of a MegaRAID controller (using MegaCli64).');
  56.                 $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
  57.                 $this->getHelpManager()->setSyntax('$SCRIPTNAME$');
  58.                 $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
  59.         }
  60.  
  61.         private function megacli_logical_disk_status($adapter='ALL') {
  62.                 $mock_file = __DIR__.'/status_ld.mock';
  63.  
  64.                 if (file_exists($mock_file)) {
  65.                         $out = explode("\n", file_get_contents($mock_file));
  66.                 } else {
  67.                         $cmd = escapeshellcmd($this->executable).' -LDInfo -Lall '.escapeshellarg('-a'.$adapter).' -NoLog';
  68.                         $out = array();
  69.                         exec($cmd, $out, $ec);
  70.  
  71.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  72.                 }
  73.  
  74.                 $drives = [];
  75.                 $cur_drive_id = '???';
  76.                 $cur_drive_name = '';
  77.                 foreach ($out as $line) {
  78.                         if (preg_match('@Virtual Drive: (\d+)@', $line, $m)) $cur_drive_id = $m[1];
  79.                         if (preg_match('@Name\s*:([^\n]*)@', $line, $m)) $cur_drive_name = trim($m[1]);
  80.                         if (preg_match('@State\s*:([^\n]*)@', $line, $m)) {
  81.                                 $drives[] = [$cur_drive_id, $cur_drive_name, trim($m[1])];
  82.                                 $cur_drive_id = '???';
  83.                                 $cur_drive_name = '';
  84.                         }
  85.                 }
  86.  
  87.                 $drives_ok = 0;
  88.                 $drives_fail = 0;
  89.  
  90.                 foreach ($drives as list($cur_drive_id, $cur_drive_name, $cur_drive_status)) {
  91.                         if (strtolower($cur_drive_status) == 'offline') $status = VNag::STATUS_CRITICAL/*?*/;
  92.                         else if (strpos($cur_drive_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL;
  93.                         else if (strtolower($cur_drive_status) == 'optimal') $status = VNag::STATUS_OK;
  94.                         else if (strtolower($cur_drive_status) == 'initialize') $status = VNag::STATUS_WARNING;
  95.                         else if (strtolower($cur_drive_status) == 'checkconsistency') $status = VNag::STATUS_WARNING;
  96.                         else $status = VNag::STATUS_UNKNOWN;
  97.  
  98.                         if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
  99.  
  100.                         $cur_drive_hf_name = $cur_drive_id . (!empty($cur_drive_name) ? " ($cur_drive_name)" : "");
  101.                         $msg = "Logical drive $cur_drive_hf_name: $cur_drive_status";
  102.                         $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  103.                         $this->addVerboseMessage($msg, $verbosity);
  104.                         $this->setStatus($status);
  105.                 }
  106.  
  107.                 $drives_total = $drives_ok + $drives_fail;
  108.                 return "$drives_fail/$drives_total arrays with problems";
  109.         }
  110.  
  111.         private function megacli_smart_disk_status($adapter='ALL') {
  112.                 $mock_file = __DIR__.'/status_pd.mock';
  113.  
  114.                 if (file_exists($mock_file)) {
  115.                         $out = explode("\n", file_get_contents($mock_file));
  116.                 } else {
  117.                         $cmd = escapeshellcmd($this->executable).' -PDList '.escapeshellarg('-a'.$adapter).' -NoLog';
  118.                         $out = array();
  119.                         exec($cmd, $out, $ec);
  120.  
  121.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  122.                 }
  123.  
  124.                 $drives = [];
  125.                 $cur_drive_id = '???';
  126.                 foreach ($out as $line) {
  127.                         if (preg_match('@Slot Number: (\d+)@', $line, $m)) $cur_drive_id = $m[1];
  128.                         if (preg_match('@Drive has flagged a S.M.A.R.T alert\s*:([^\n]*)@', $line, $m)) {
  129.                                 $drives[] = [$cur_drive_id, trim($m[1])];
  130.                                 $cur_drive_id = '???';
  131.                         }
  132.                 }
  133.  
  134.                 $drives_ok = 0;
  135.                 $drives_fail = 0;
  136.  
  137.                 foreach ($drives as list($cur_drive_id, $cur_drive_status)) {
  138.                         if (strtolower($cur_drive_status) == 'no') $status = VNag::STATUS_OK;
  139.                         else $status = VNag::STATUS_CRITICAL; // unsure if there will be a "yes" or any other output
  140.  
  141.                         if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
  142.  
  143.                         $msg = "Physical drive $cur_drive_id: SMART alert? $cur_drive_status";
  144.                         $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  145.                         $this->addVerboseMessage($msg, $verbosity);
  146.                         $this->setStatus($status);
  147.                 }
  148.  
  149.                 $drives_total = $drives_ok + $drives_fail;
  150.                 return "$drives_fail/$drives_total drives have SMART alerts";
  151.         }
  152.  
  153.         private function megacli_battery_status($adapter='ALL') {
  154.                 $mock_file = __DIR__.'/status_battery.mock';
  155.  
  156.                 if (file_exists($mock_file)) {
  157.                         $out = explode("\n", file_get_contents($mock_file));
  158.                 } else {
  159.                         $cmd = escapeshellcmd($this->executable).' -AdpBbuCmd '.escapeshellarg('-a'.$adapter).' -NoLog';
  160.                         $out = array();
  161.                         exec($cmd, $out, $ec);
  162.  
  163.                         // DEBUG: file_put_contents($mock_file, implode("\n", $out));
  164.                 }
  165.  
  166.                 $battery_status = '???';
  167.                 foreach ($out as $line) {
  168.                         if (preg_match('@Battery State\s*:([^\n]*)@', $line, $m)) {
  169.                                 $battery_status = trim($m[1]);
  170.                         }
  171.                 }
  172.  
  173.                 if (strtolower($battery_status) == 'missing') $status = VNag::STATUS_WARNING;
  174.                 else if (strtolower($battery_status) == 'optimal') $status = VNag::STATUS_OK;
  175.                 else if (strtolower($battery_status) == 'failed') $status = VNag::STATUS_CRITICAL;
  176.                 else if (strtolower($battery_status) == 'learning') $status = VNag::STATUS_WARNING;
  177.                 else if (strpos($battery_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL;
  178.                 else $status = VNag::STATUS_UNKNOWN;
  179.  
  180.                 $msg = "Battery Status: $battery_status";
  181.                 $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY;
  182.                 $this->addVerboseMessage($msg, $verbosity);
  183.                 $this->setStatus($status);
  184.  
  185.                 return $status == VNag::STATUS_OK ? "Battery OK" : "Battery has problems";
  186.         }
  187.  
  188.         protected function cbRun() {
  189.                 $headlines = '';
  190.                 $headlines .= $this->megacli_logical_disk_status() . ', ';
  191.                 $headlines .= $this->megacli_smart_disk_status() . ', ';
  192.                 $headlines .= $this->megacli_battery_status();
  193.                 $this->setHeadline($headlines, true);
  194.         }
  195. }
  196.