Subversion Repositories vnag

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 daniel-mar 1
<?php /* <ViaThinkSoftSignature>
2
JzjmNSphjJTRHMsIRHh892nocNxwZ2Es+ZcviS31H/rsieUvZmhp9cok7T2tEye/Q
3
wVbEbouz4zSVd9vP3Pvq37NJoqHC6s0zttRWeBrXKqkBpJnucsuT1M+OTkxdxu+Cv
4
XupKWifcXjUpQF+yxg+rPji/oaF5V8r4BZK7/GgZUyvovpuXSn2e0w91PtkrE7j9W
5
eq8LS1SqcYeTh4AeozQC+GjWrrzzW6w90hDM1b4HSp+S5KcBQOTRY1h1umJp41XNe
6
Yb7/sPkmCsIbpf4YuzUFg4v7q9epYH/qwnfRI3Ll0jrFNYdGHFbgPGApmNkklNf7h
7
SpWMAB1LaUh/4i/gkxceyHA8xt9i2pdHJIRiHoxzUFyIXevst0GOneUoeEUdLAyG3
8
xCYxuai85ZvzeffkKQCVbEkQu/vitQUW6JiE3yeOMJFF9mEwPbHFC7uYEpnbV98FE
9
segNrxdM8vscinKmr/cGg/P2j+BjPVT+Uag+7ps5xxcmSHFIHZuD0VoKnyyDAyzOs
10
8YhloJq0P8ovBTcJyvmj4Qzcs2UaM4WKmkFbFJhos2DxFxoPfh+DfiLVQJaO57npZ
11
OkbjX86+ann5OjkgJRgMDc4EFbfApfK1t4L57FTNJwEWIlmUl2X5k0LOXiLl0ShFG
12
gpqfAIUvB+K7TQbEh3wRdqSuUhTigUqL/aEFygygueEPh2DhIPc//QENU22fSMcxT
13
+Ud+uNJWgXqxCg6NxjyshWTNwvIFWX14LtqauL80TUhXnYZZVtq4tbCNqb3DAxIvq
14
K+F1aTbgQnb/JIq+4ntHjR9t2Jp22zQ+EEzdgIabG9YRfJNYLggwgUFrlmmFht0sV
15
JVCl4dLPo/CuK6VVTIj1PLSIKpa0mnt+cadUMrJVY1kogJHCmyzLpiwj4sff483Ya
16
H5gcOqAdJ1NlvnDJvhxZLV4JSIvuk8dGCdcuaa2HJfoVOxBFUguXB5wHsgTvOT7Ia
17
8WpqbF6SJDfH2YqoUsAiifCUxi1C/NHffQ3mZc4ko7nzdTVHJgtfaPT1kkFscH2ZV
18
6GZzUdJx0wcSr9e7d2zDCElP7R1rF01aiHCGlMOfdC4GnzxYH5MCgwBL/GNMN9qJm
19
BK4sDFwJ6PiuJUlz20NlVlm/rwV0SfVaMHMtDZ7/L+ynva8W13SfsQeYhWoJxH8Um
20
0dlvf5DG+Aq4mzMbCShHxG9zIrNSFfmYrKuh5ldot+/9FN6b4WTP7Ej1D0l55+1fc
21
wBrXwxl8w9+awryEhXzuRtxuewnkNopqv+U3SEPlqK5nyZt8GwQZpqw1DzdGiA7jY
22
7yAx/fTMeMs4ypVpxQJzt3Sct/BUkKHSkhSY0UrHyP2k4k29VGhwaAqZHBChglawv
23
w==
24
</ViaThinkSoftSignature> */ ?>
2 daniel-mar 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 2018-07-17
33
 */
34
 
35
declare(ticks=1);
36
 
37
class SmartCheck extends VNag {
38
        public function __construct() {
39
                parent::__construct();
40
 
41
                if ($this->is_http_mode()) {
42
                        // Don't allow the standard arguments via $_REQUEST
43
                        $this->registerExpectedStandardArguments('');
44
                } else {
45
                        $this->registerExpectedStandardArguments('Vhtv');
46
                }
47
 
48
                $this->getHelpManager()->setPluginName('vnag_smart');
49
                $this->getHelpManager()->setVersion('1.0');
50
                $this->getHelpManager()->setShortDescription('This plugin checks the contents of the SMART data and warns when a harddisk has failed.');
51
                $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
52
                $this->getHelpManager()->setSyntax('$SCRIPTNAME$ (no additional arguments expected)');
53
                $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
54
        }
55
 
56
        private function check_smart($dev) {
57
                if (!`which which`) {
58
                        throw new VNagException("Program 'which' is not installed on your system");
59
                }
60
 
61
                if (!`which smartctl`) {
62
                        throw new VNagException("Program 'smartctl' (usually included in package smartmontools) is not installed on your system");
63
                }
64
 
65
                if (!`sudo cat /proc/cpuinfo`) {
66
                        // To make this work, please run "visudo" and add the following line:
67
                        // nagios ALL=NOPASSWD: /usr/sbin/smartctl
68
                        throw new VNagException("You don't have SUDO privileges. Please run 'visudo' and allow the command /usr/sbin/smartctl for user ".get_current_user().".");
69
                }
70
 
71
                unset($out);
72
                exec('sudo smartctl --all '.escapeshellarg($dev), $out, $code);
73
                $cont = implode("\n", $out);
74
 
75
                $msg = array();
76
                $status = -1;
77
 
78
                if (stripos($cont, 'device lacks SMART capability') !== false)  {
79
                        // At my system (Debian 9), I get exit code 4 (which is not fully accurate)
80
                        $msg[] = 'Device lacks SMART capability';
81
                        #$status = VNag::STATUS_UNKNOWN;
82
                } else if ($code == 0) {
83
                        $status = VNag::STATUS_OK;
84
                } else {
85
                        if ($code & 1) {
86
                                throw new Exception("smartctl reports 'command line did not parse' (code $code).");
87
                        }
88
                        if ($code & 2) {
89
                                $msg[] = "Device open failed. It is either completely defective, or in low-power mode.";
90
                                $status = max($status, VNag::STATUS_CRITICAL);
91
                        }
92
                        if ($code & 4) {
93
                                $msg[] = "SMART command failed or checksum is wrong.";
94
                                $status = max($status, VNag::STATUS_WARNING);
95
                        }
96
                        if ($code & 8) {
97
                                $msg[] = "SMART status returns 'DISK FAILING'";
98
                                $status = max($status, VNag::STATUS_CRITICAL);
99
                        }
100
                        if ($code & 16) {
101
                                $msg[] = "SMART found prefail attributes below threshold";
102
                                $status = max($status, VNag::STATUS_WARNING);
103
                        }
104
                        if ($code & 32) {
105
                                $msg[] = "SMART status is 'OK' but usage/prefail attributes have been below threshold in the past.";
106
                                $status = max($status, VNag::STATUS_WARNING);
107
                        }
108
                        if ($code & 64) {
109
                                $msg[] = "The device error log contains records of errors.";
110
                                $status = max($status, VNag::STATUS_WARNING);
111
                        }
112
                        if ($code & 128) {
113
                                $msg[] = "The self-test logs contains records of errors.";
114
                                $status = max($status, VNag::STATUS_WARNING);
115
                        }
116
                }
117
 
118
                $messages = implode(", ", $msg);
119
                if ($messages != '') $messages = ": $messages";
120
 
121
                if ($status == VNag::STATUS_CRITICAL) {
122
                        $this->addVerboseMessage("$dev (Critical)$messages", VNag::VERBOSITY_SUMMARY);
123
                } else if ($status == VNag::STATUS_WARNING) {
124
                        $this->addVerboseMessage("$dev (Warning)$messages", VNag::VERBOSITY_SUMMARY);
125
                } else if ($status == VNag::STATUS_OK) {
126
                        $this->addVerboseMessage("$dev (OK)$messages", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
127
                } else {
128
                        $status = VNag::STATUS_UNKNOWN;
129
                        $this->addVerboseMessage("$dev (Unknown)$messages", VNag::VERBOSITY_SUMMARY);
130
                }
131
                $this->setStatus($status);
132
                return $status;
133
        }
134
 
135
        protected function cbRun() {
136
                $devices = array();
137
                $devices = array_merge($devices, glob('/dev/sd?'));
138
                $devices = array_merge($devices, glob('/dev/hd?'));
139
 
140
                $count_total = 0;
141
                $count_ok = 0;
142
                $count_warning = 0;
143
                $count_critical = 0;
144
                $count_unknown = 0;
145
                foreach ($devices as $dev) {
146
                        $count_total++;
147
                        switch ($this->check_smart($dev)) {
148
                                case VNag::STATUS_OK:
149
                                        $count_ok++;
150
                                        break;
151
                                case VNag::STATUS_WARNING:
152
                                        $count_warning++;
153
                                        break;
154
                                case VNag::STATUS_CRITICAL:
155
                                        $count_critical++;
156
                                        break;
157
                                case VNag::STATUS_UNKNOWN:
158
                                        $count_unknown++;
159
                                        break;
160
                        }
161
                }
162
 
163
                $this->setHeadline(sprintf('Checked %d drives (%d OK, %d warning, %d critical, %d unknown)', $count_total, $count_ok, $count_warning, $count_critical, $count_unknown));
164
        }
165
}