Subversion Repositories vnag

Rev

Rev 77 | 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
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
 *
79 daniel-mar 8
 * Revision 2023-10-13
68 daniel-mar 9
 */
10
 
11
declare(ticks=1);
12
 
13
class MegaRaidCheck extends VNag {
71 daniel-mar 14
        private $argCmd = null;
68 daniel-mar 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
 
71 daniel-mar 26
                $this->addExpectedArgument($this->argCmd = new VNagArgument('E', 'executable', VNagArgument::VALUE_OPTIONAL, 'executable', 'The path to the MegaCli64 executable.', '/opt/MegaRAID/MegaCli/MegaCli64'));
27
 
68 daniel-mar 28
                $this->getHelpManager()->setPluginName('vnag_megaraid');
79 daniel-mar 29
                $this->getHelpManager()->setVersion('2023-10-13');
68 daniel-mar 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 {
71 daniel-mar 42
                        $cmd = escapeshellcmd($this->argCmd->getValue()).' -LDInfo -Lall '.escapeshellarg('-a'.$adapter).' -NoLog';
68 daniel-mar 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
 
69 daniel-mar 62
                $drives_ok = 0;
63
                $drives_fail = 0;
64
 
68 daniel-mar 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
 
69 daniel-mar 73
                        if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
74
 
68 daniel-mar 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
                }
69 daniel-mar 81
 
82
                $drives_total = $drives_ok + $drives_fail;
83
                return "$drives_fail/$drives_total arrays with problems";
68 daniel-mar 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 {
71 daniel-mar 92
                        $cmd = escapeshellcmd($this->argCmd->getValue()).' -PDList '.escapeshellarg('-a'.$adapter).' -NoLog';
68 daniel-mar 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
 
69 daniel-mar 109
                $drives_ok = 0;
110
                $drives_fail = 0;
111
 
68 daniel-mar 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
 
69 daniel-mar 116
                        if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; }
117
 
68 daniel-mar 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
                }
69 daniel-mar 123
 
124
                $drives_total = $drives_ok + $drives_fail;
125
                return "$drives_fail/$drives_total drives have SMART alerts";
68 daniel-mar 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 {
71 daniel-mar 134
                        $cmd = escapeshellcmd($this->argCmd->getValue()).' -AdpBbuCmd '.escapeshellarg('-a'.$adapter).' -NoLog';
68 daniel-mar 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);
69 daniel-mar 159
 
160
                return $status == VNag::STATUS_OK ? "Battery OK" : "Battery has problems";
68 daniel-mar 161
        }
162
 
163
        protected function cbRun() {
69 daniel-mar 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);
68 daniel-mar 169
        }
170
}