Rev 69 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
68 | daniel-mar | 1 | <?php /* <ViaThinkSoftSignature> |
71 | daniel-mar | 2 | Tc+nyWiSG99g+rn5Kxz4Qq1U8OIq3W83DIzZN42wndPJit2lZMknPYjt/OUTmtTcv |
3 | u/8ef2+7k7VFr6pzqlVi2lfG9FcRwSl0BSXfs+b5Aw0y4YVdM3k0IE+XJlOmJKhuO |
||
4 | TrNHq6OCIoA4bJlSOgJ02PSy2LCReAsEQfwfCsQy+j1WAm0Pno8PB/PbBhxGUoO3c |
||
5 | f1O/DbJh17NfcQNzfulUBFYwGx3mBnNg5JqE4H435y/A5irelloX4GgZJjq6YJu8p |
||
6 | rzgLCHgaDdAlbypK3YFxlQWmMI8yfUwaaX3DDT276lBeA7TjSj0iwQu1VnSux4vmb |
||
7 | AjHGkoexDa6JG7qHoNGG8LF5JTQ+35f4hcTwUWwkWts5N3yQ+xOP6MzBoL0oFtQZS |
||
8 | s3amlKuiWmtk3Ft45hnoq0KepEGgMFnEdz1AmeZ+HJc1gYTuPmhF0XGq8bBPhA0GL |
||
9 | OIqo6AIhBzAcpFyad6Ag+Wkq3OEmpDv+5NjR1Fd/p6968oGVTPjPCjyw122PxfqzJ |
||
10 | C3fGEQWwKisoMOwg/4wDJP8bUDOgeb3U5OGYJ/p4dHI5Em2vHCAHJk8fEWpaMFk8j |
||
11 | 3h+3+8RnVxllVx3qeIpdoMEeHZn5olToa+5yM2puf9aHbJD9DB+g68zLLjRH5May6 |
||
12 | fkGKlJ2GiIX0+JUy2PCnhI5lpwweBA75ADAZLfcmgxJNSsZYOYE1RwcfdCRMU7wA2 |
||
13 | BAD+A3PR31LZpAy5mPtStCwlMO2W3BcLv2bZGpNnExoAiL5YqoPhVGMF4Xer3SxlP |
||
14 | uxFhzAq0RbG8fXGr9w+c+gh2hV/LO0G0qwJV9mBmlg2ZBUO8HN6Wi+Oe/NfZg3IOo |
||
15 | z7cSzkWdmfY6m1PwKcDIae+EAnfqr9jN3CImE7Yt8pdSwCC4aEN3d+/TQtrimOlxT |
||
16 | 94fg0z0+5mgve7AEQaieINSlDkJAARaYQVQvRrYryMmhjjSYQCXuMjXYu2ZOTvtgy |
||
17 | wbNfOWPT6EKAyxRiL8X2R6L5kSozABxonkKycrXX6uEel+MwVNs6ymS0czt8skInk |
||
18 | 8+Q2KxH6PDjYU4iRxtSpCRhwCBC9vgrHGNi+sgx+EN7aU7/bgCN/7ZjxFJYPYn0mR |
||
19 | 2rezG9g0sWospPHhMetHf170FQXdS4OCLxIfcqwrGXEIb7nNQl1hXrw2Gg1cFEGtN |
||
20 | XJOOeTSszuPBH70JvqH+dRaZB44pyF0pMbcyWD3lJi6DIckzgHQQg/DiIgjLLRX5v |
||
21 | g+E81ICL86W+q3sEhbtFc0XEFpOBdB4TRxS02vAZP0pyUPTX1P3YIcguS12E+yzwT |
||
22 | VkeVK2fFuhi03QuBiJIMnBlP7g5MwtMyxjuLcT8P7BTH5GnlLrv0idVO00maYnv9Z |
||
23 | g== |
||
68 | daniel-mar | 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 | * |
||
71 | daniel-mar | 32 | * Revision 2023-09-14 |
68 | daniel-mar | 33 | * |
34 | * Changelog: |
||
35 | * 2023-09-13 1.0 Initial release |
||
71 | daniel-mar | 36 | * 2023-09-14 1.0.1 Executable path is now configurable |
68 | daniel-mar | 37 | */ |
38 | |||
39 | declare(ticks=1); |
||
40 | |||
41 | class MegaRaidCheck extends VNag { |
||
71 | daniel-mar | 42 | private $argCmd = null; |
68 | daniel-mar | 43 | |
44 | public function __construct() { |
||
45 | parent::__construct(); |
||
46 | |||
47 | if ($this->is_http_mode()) { |
||
48 | // Don't allow the standard arguments via $_REQUEST |
||
49 | $this->registerExpectedStandardArguments(''); |
||
50 | } else { |
||
51 | $this->registerExpectedStandardArguments('Vhtv'); |
||
52 | } |
||
53 | |||
71 | daniel-mar | 54 | $this->addExpectedArgument($this->argCmd = new VNagArgument('E', 'executable', VNagArgument::VALUE_OPTIONAL, 'executable', 'The path to the MegaCli64 executable.', '/opt/MegaRAID/MegaCli/MegaCli64')); |
55 | |||
68 | daniel-mar | 56 | $this->getHelpManager()->setPluginName('vnag_megaraid'); |
57 | $this->getHelpManager()->setVersion('1.0'); |
||
58 | $this->getHelpManager()->setShortDescription('This plugin checks the controller and disk status of a MegaRAID controller (using MegaCli64).'); |
||
59 | $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.'); |
||
60 | $this->getHelpManager()->setSyntax('$SCRIPTNAME$'); |
||
61 | $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com'); |
||
62 | } |
||
63 | |||
64 | private function megacli_logical_disk_status($adapter='ALL') { |
||
65 | $mock_file = __DIR__.'/status_ld.mock'; |
||
66 | |||
67 | if (file_exists($mock_file)) { |
||
68 | $out = explode("\n", file_get_contents($mock_file)); |
||
69 | } else { |
||
71 | daniel-mar | 70 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -LDInfo -Lall '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 71 | $out = array(); |
72 | exec($cmd, $out, $ec); |
||
73 | |||
74 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
75 | } |
||
76 | |||
77 | $drives = []; |
||
78 | $cur_drive_id = '???'; |
||
79 | $cur_drive_name = ''; |
||
80 | foreach ($out as $line) { |
||
81 | if (preg_match('@Virtual Drive: (\d+)@', $line, $m)) $cur_drive_id = $m[1]; |
||
82 | if (preg_match('@Name\s*:([^\n]*)@', $line, $m)) $cur_drive_name = trim($m[1]); |
||
83 | if (preg_match('@State\s*:([^\n]*)@', $line, $m)) { |
||
84 | $drives[] = [$cur_drive_id, $cur_drive_name, trim($m[1])]; |
||
85 | $cur_drive_id = '???'; |
||
86 | $cur_drive_name = ''; |
||
87 | } |
||
88 | } |
||
89 | |||
69 | daniel-mar | 90 | $drives_ok = 0; |
91 | $drives_fail = 0; |
||
92 | |||
68 | daniel-mar | 93 | foreach ($drives as list($cur_drive_id, $cur_drive_name, $cur_drive_status)) { |
94 | if (strtolower($cur_drive_status) == 'offline') $status = VNag::STATUS_CRITICAL/*?*/; |
||
95 | else if (strpos($cur_drive_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL; |
||
96 | else if (strtolower($cur_drive_status) == 'optimal') $status = VNag::STATUS_OK; |
||
97 | else if (strtolower($cur_drive_status) == 'initialize') $status = VNag::STATUS_WARNING; |
||
98 | else if (strtolower($cur_drive_status) == 'checkconsistency') $status = VNag::STATUS_WARNING; |
||
99 | else $status = VNag::STATUS_UNKNOWN; |
||
100 | |||
69 | daniel-mar | 101 | if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; } |
102 | |||
68 | daniel-mar | 103 | $cur_drive_hf_name = $cur_drive_id . (!empty($cur_drive_name) ? " ($cur_drive_name)" : ""); |
104 | $msg = "Logical drive $cur_drive_hf_name: $cur_drive_status"; |
||
105 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
106 | $this->addVerboseMessage($msg, $verbosity); |
||
107 | $this->setStatus($status); |
||
108 | } |
||
69 | daniel-mar | 109 | |
110 | $drives_total = $drives_ok + $drives_fail; |
||
111 | return "$drives_fail/$drives_total arrays with problems"; |
||
68 | daniel-mar | 112 | } |
113 | |||
114 | private function megacli_smart_disk_status($adapter='ALL') { |
||
115 | $mock_file = __DIR__.'/status_pd.mock'; |
||
116 | |||
117 | if (file_exists($mock_file)) { |
||
118 | $out = explode("\n", file_get_contents($mock_file)); |
||
119 | } else { |
||
71 | daniel-mar | 120 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -PDList '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 121 | $out = array(); |
122 | exec($cmd, $out, $ec); |
||
123 | |||
124 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
125 | } |
||
126 | |||
127 | $drives = []; |
||
128 | $cur_drive_id = '???'; |
||
129 | foreach ($out as $line) { |
||
130 | if (preg_match('@Slot Number: (\d+)@', $line, $m)) $cur_drive_id = $m[1]; |
||
131 | if (preg_match('@Drive has flagged a S.M.A.R.T alert\s*:([^\n]*)@', $line, $m)) { |
||
132 | $drives[] = [$cur_drive_id, trim($m[1])]; |
||
133 | $cur_drive_id = '???'; |
||
134 | } |
||
135 | } |
||
136 | |||
69 | daniel-mar | 137 | $drives_ok = 0; |
138 | $drives_fail = 0; |
||
139 | |||
68 | daniel-mar | 140 | foreach ($drives as list($cur_drive_id, $cur_drive_status)) { |
141 | if (strtolower($cur_drive_status) == 'no') $status = VNag::STATUS_OK; |
||
142 | else $status = VNag::STATUS_CRITICAL; // unsure if there will be a "yes" or any other output |
||
143 | |||
69 | daniel-mar | 144 | if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; } |
145 | |||
68 | daniel-mar | 146 | $msg = "Physical drive $cur_drive_id: SMART alert? $cur_drive_status"; |
147 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
148 | $this->addVerboseMessage($msg, $verbosity); |
||
149 | $this->setStatus($status); |
||
150 | } |
||
69 | daniel-mar | 151 | |
152 | $drives_total = $drives_ok + $drives_fail; |
||
153 | return "$drives_fail/$drives_total drives have SMART alerts"; |
||
68 | daniel-mar | 154 | } |
155 | |||
156 | private function megacli_battery_status($adapter='ALL') { |
||
157 | $mock_file = __DIR__.'/status_battery.mock'; |
||
158 | |||
159 | if (file_exists($mock_file)) { |
||
160 | $out = explode("\n", file_get_contents($mock_file)); |
||
161 | } else { |
||
71 | daniel-mar | 162 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -AdpBbuCmd '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 163 | $out = array(); |
164 | exec($cmd, $out, $ec); |
||
165 | |||
166 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
167 | } |
||
168 | |||
169 | $battery_status = '???'; |
||
170 | foreach ($out as $line) { |
||
171 | if (preg_match('@Battery State\s*:([^\n]*)@', $line, $m)) { |
||
172 | $battery_status = trim($m[1]); |
||
173 | } |
||
174 | } |
||
175 | |||
176 | if (strtolower($battery_status) == 'missing') $status = VNag::STATUS_WARNING; |
||
177 | else if (strtolower($battery_status) == 'optimal') $status = VNag::STATUS_OK; |
||
178 | else if (strtolower($battery_status) == 'failed') $status = VNag::STATUS_CRITICAL; |
||
179 | else if (strtolower($battery_status) == 'learning') $status = VNag::STATUS_WARNING; |
||
180 | else if (strpos($battery_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL; |
||
181 | else $status = VNag::STATUS_UNKNOWN; |
||
182 | |||
183 | $msg = "Battery Status: $battery_status"; |
||
184 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
185 | $this->addVerboseMessage($msg, $verbosity); |
||
186 | $this->setStatus($status); |
||
69 | daniel-mar | 187 | |
188 | return $status == VNag::STATUS_OK ? "Battery OK" : "Battery has problems"; |
||
68 | daniel-mar | 189 | } |
190 | |||
191 | protected function cbRun() { |
||
69 | daniel-mar | 192 | $headlines = ''; |
193 | $headlines .= $this->megacli_logical_disk_status() . ', '; |
||
194 | $headlines .= $this->megacli_smart_disk_status() . ', '; |
||
195 | $headlines .= $this->megacli_battery_status(); |
||
196 | $this->setHeadline($headlines, true); |
||
68 | daniel-mar | 197 | } |
198 | } |