Subversion Repositories vnag

Rev

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

  1. <?php /* <ViaThinkSoftSignature>
  2. R+VZLh3GAQ/vs4fO8eyTRn1IEqD7XS9dR7YFDqJM3h944GnPQKym1XAkDpiQkswyq
  3. Dtmsg1r43c/tkzPexDMu8YLjKC2RzT0arj86HzJgeBSoQ4W1ncmmPZ7zsP/2TGJSS
  4. 5rLft8xT2/XcUAi02RaHstg+j3Q6f8+wgcWTj4hg/R/uQaPoR7re27Zwx1+xsH2er
  5. hq7qo6oEf4kHno2gcLDyoQmUJbL2N7M0xfvrFPLoSSPuIL3EwtF9Cp3LZ3HXkUUnV
  6. Bqbfnyv59ZKzVcpn9spZZKobiQJFNHbtAc3z61cTilNSvO4/5LhSk17CXtM4kjfLU
  7. n1ZLgRqNmuiKNv+wPk/H4mM3VPc9DE67VRR6V+HZNr1PEdb9DbSiYgbmCONqs7lX9
  8. y09sojvRztAemua0M44er/STKnmKpIGigmmMQ4ZBYh4XD34IfLYwVeX2ErK2mnBhg
  9. DTbsKymyKxBVsDBv2Z7GvpZb3lxIFtZ5cz/NlVAfe5sKkmvO6J2VlaSzka0cl3kj/
  10. bZuNVjuRwNdD31otYbOkTE69ARnRH2RwqVD927+Bne5OQOTy4w3Tuz3SqJesbAavx
  11. pGwnmTCQoez+viiZqQBB6B55xBEEzsEVWgHiUmllgmz8xZMxEdNYfcw4H8T8oybLE
  12. hSQBicFDoZpO8kNSRoU31Q3RDg9l1AW8JyRHxTlV767/JmyFmgvMiKSxZDbvjuzW/
  13. i0dL1wurRTdfB2cXmfMQhXjl4t7rFzI9rIs4YMSDPDgZEjehYh7twrBZXelinDrrm
  14. HQkQtRvz2IUGL/5KzXo03Ul7uz098X+uxlL6RMbE+8pYZJp3NuF/G9NXo8pzELlrt
  15. FhP337/C7ASC6ua5OW9SzZ+EECCcaHWJjG7zZqFgBhzLNjakbA4a4iZHSztWsO4q4
  16. xyKTOBzL+dtM04ERwiGiCU+yjPcuYjmDmPEZXTtCENUdtDDEm77OvunTI04aFqZST
  17. XO00CNcCCByM8Q7m8qb06Od/4bjo79qhNPjHx4wYBTgLhYYKoQRTv3MyZY9BDgIE3
  18. /UPyHa0h2UPhS6IjqLoIuU3WZRh+kKJMExeTNWJ+F9yVvmpDlK2pPNo279g8H7jD6
  19. Dp5aSDwdwSqGE9mrMgwdDL2qjun8kWg0s69snfXSaI5qSTyoIjVmGIiSlNtdw8VsX
  20. gW/wO07WOUv+r5qsHkVZgSFKZxeGCETPKyGmGjgy9yibFyDWwoeK2NMijgJlO0QPR
  21. d02HfMGFQ30TyAnuVDkmZf1a02czFQ/YVQbu1Hq3siQ+gqkCC8ticsBRWux6dLYFL
  22. cYNvfVYj3c0IwBmxUNtNzFvSZLdJOAkKenk7ODGgrHSZarKNWOl6wkb3IYdNFefgM
  23. g==
  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.  *
  32.  * Revision 2021-05-13
  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.                 $code = 0;
  72.                 $out = array();
  73.                 exec('sudo smartctl --all '.escapeshellarg($dev), $out, $code);
  74.                 $cont = implode("\n", $out);
  75.  
  76.                 $msg = array();
  77.                 $status = -1;
  78.  
  79.                 if (stripos($cont, 'device lacks SMART capability') !== false)  {
  80.                         // At my system (Debian 9), I get exit code 4 (which is not fully accurate)
  81.                         $msg[] = 'Device lacks SMART capability';
  82.                         #$status = VNag::STATUS_UNKNOWN;
  83.                 } else if ($code == 0) {
  84.                         $status = VNag::STATUS_OK;
  85.                 } else {
  86.                         if ($code & 1) {
  87.                                 throw new Exception("smartctl reports 'command line did not parse' (code $code).");
  88.                         }
  89.                         if ($code & 2) {
  90.                                 $msg[] = "Device open failed. It is either completely defective, or in low-power mode.";
  91.                                 $status = max($status, VNag::STATUS_CRITICAL);
  92.                         }
  93.                         if ($code & 4) {
  94.                                 $msg[] = "SMART command failed or checksum is wrong.";
  95.                                 $status = max($status, VNag::STATUS_WARNING);
  96.                         }
  97.                         if ($code & 8) {
  98.                                 $msg[] = "SMART status returns 'DISK FAILING'";
  99.                                 $status = max($status, VNag::STATUS_CRITICAL);
  100.                         }
  101.                         if ($code & 16) {
  102.                                 $msg[] = "SMART found prefail attributes below threshold";
  103.                                 $status = max($status, VNag::STATUS_WARNING);
  104.                         }
  105.                         if ($code & 32) {
  106.                                 $msg[] = "SMART status is 'OK' but usage/prefail attributes have been below threshold in the past.";
  107.                                 $status = max($status, VNag::STATUS_WARNING);
  108.                         }
  109.                         if ($code & 64) {
  110.                                 $msg[] = "The device error log contains records of errors.";
  111.                                 $status = max($status, VNag::STATUS_WARNING);
  112.                         }
  113.                         if ($code & 128) {
  114.                                 $msg[] = "The self-test logs contains records of errors.";
  115.                                 $status = max($status, VNag::STATUS_WARNING);
  116.                         }
  117.                 }
  118.  
  119.                 $messages = implode(", ", $msg);
  120.                 if ($messages != '') $messages = ": $messages";
  121.  
  122.                 if ($status == VNag::STATUS_CRITICAL) {
  123.                         $this->addVerboseMessage("$dev (Critical)$messages", VNag::VERBOSITY_SUMMARY);
  124.                 } else if ($status == VNag::STATUS_WARNING) {
  125.                         $this->addVerboseMessage("$dev (Warning)$messages", VNag::VERBOSITY_SUMMARY);
  126.                 } else if ($status == VNag::STATUS_OK) {
  127.                         $this->addVerboseMessage("$dev (OK)$messages", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
  128.                 } else {
  129.                         $status = VNag::STATUS_UNKNOWN;
  130.                         $this->addVerboseMessage("$dev (Unknown)$messages", VNag::VERBOSITY_SUMMARY);
  131.                 }
  132.                 $this->setStatus($status);
  133.                 return $status;
  134.         }
  135.  
  136.         protected function cbRun() {
  137.                 $devices = array();
  138.                 $devices = array_merge($devices, glob('/dev/sd?'));
  139.                 $devices = array_merge($devices, glob('/dev/hd?'));
  140.  
  141.                 $count_total = 0;
  142.                 $count_ok = 0;
  143.                 $count_warning = 0;
  144.                 $count_critical = 0;
  145.                 $count_unknown = 0;
  146.                 foreach ($devices as $dev) {
  147.                         $count_total++;
  148.                         switch ($this->check_smart($dev)) {
  149.                                 case VNag::STATUS_OK:
  150.                                         $count_ok++;
  151.                                         break;
  152.                                 case VNag::STATUS_WARNING:
  153.                                         $count_warning++;
  154.                                         break;
  155.                                 case VNag::STATUS_CRITICAL:
  156.                                         $count_critical++;
  157.                                         break;
  158.                                 case VNag::STATUS_UNKNOWN:
  159.                                         $count_unknown++;
  160.                                         break;
  161.                         }
  162.                 }
  163.  
  164.                 $this->setHeadline(sprintf('Checked %d drives (%d OK, %d warning, %d critical, %d unknown)', $count_total, $count_ok, $count_warning, $count_critical, $count_unknown));
  165.         }
  166. }
  167.