Subversion Repositories vnag

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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