Subversion Repositories vnag

Rev

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
}