Subversion Repositories vnag

Rev

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

  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. }
  143.