Advertisement
Guest User

Bitcoin Nagios Plugin

a guest
Jul 30th, 2010
905
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.99 KB | None | 0 0
  1. #!/usr/bin/php5
  2. <?php
  3.  
  4. // Wow, getopt() is a stupid function that just barely works :(
  5. $options = getopt('u:p:h:');
  6.  
  7. // Lets see if the user has a bitcoin.conf file in the usual location of $HOME/.bitcoin/bitcoin.conf
  8. $bcconf = getenv('HOME') . '/.bitcoin/bitcoin.conf';
  9. if(file_exists($bcconf)) {
  10.     // Looks like they have a config file, so lets see if we can find the username and password
  11.     $bcconf_text = file_get_contents($bcconf);
  12.     $bcconf_text = explode("\n",$bcconf_text);
  13.     $username = $password = NULL;
  14.     // Now we'll just scan through each line of the file looking for the username and password
  15.     foreach($bcconf_text as $line) {
  16.         $setting = substr($line,0,strpos($line,'='));
  17.         $data = substr($line,strpos($line,'=') + 1);
  18.         if($setting == "rpcuser" && $username == NULL) {
  19.             // Found the username!
  20.             $rpcuser = $data;
  21.         } elseif($setting == "rpcpassword" && $password == NULL) {
  22.             // Found the password!
  23.             $rpcpass = $data;
  24.         }
  25.     }
  26. }
  27.  
  28. // If -u or $rpcuser aren't set we'll assume a default username of 'user' since leaving this blank doesn't work with php's fopen()
  29. if(isset($options['u'])) {
  30.     $rpcuser = $options['u'];
  31. } elseif(empty($rpcuser)) {
  32.     $rpcuser = 'user';
  33. }
  34.  
  35. // We need a password to be set
  36. if(isset($options['p'])) {
  37.     $rpcpass = $options['p'];
  38. } elseif(empty($rpcpass)) {
  39.     // The user didn't specify a password at the command line and didn't have one in his bitcoin.conf :(
  40.     echo "Usage: {$argv[0]} -p <password> [-u username] [-h hostname/IP]\n";
  41.     // Why not exit with 1? Because then nagios would think this was a warning
  42.     die(255);
  43. }
  44.  
  45. // If -h isn't set we'll assume that the hostname is 'localhost'
  46. if(!isset($options['h'])) {
  47.     $rpchost = 'localhost';
  48. } else {
  49.     $rpchost = $options['h'];
  50. }
  51.  
  52. try {
  53.     $bitcoin = new jsonRPCClient("http://{$rpcuser}:{$rpcpass}@{$rpchost}:8332/");
  54.     $info = $bitcoin->getinfo();
  55. } catch (Exception $e) {
  56.     // The node is down! I think I'm leaking!
  57.     echo "CRITICAL: Bitcoin is down!\n";
  58.     die(2);
  59. }
  60.  
  61. // Convert from khps to hps. Why? Because this way my graphs don't have weird units of measure like "Kkhash/ps"
  62. $info['KHPS'] = $info['KHPS'] * 1000;
  63.  
  64. // Format the performance data
  65. $perfdata = "connections={$info['connections']};;;; difficulty={$info['difficulty']};;;; hashs={$info['KHPS']}hash/ps;;;;";
  66.  
  67. if($info['balance'] != '0') {
  68.     // Throw a warning since we have a balance
  69.     echo "WARNING: Balance is at {$info['balance']} | {$perfdata}\n";
  70.     die(1);
  71. } elseif($info['connections'] == 0) {
  72.     // Something is wrong, the node is up but we have no connections
  73.     echo "CRITICAL: Bitcoin has no connections! | {$perfdata}\n";
  74.     die(2);
  75. } elseif($info['generate'] == 0) {
  76.     // The node is online but is not generating blocks
  77.     echo "CRITICAL: Bitcoin is not generating blocks! | {$perfdata}\n";
  78.     die(2);
  79. } else {
  80.     // Everything is good
  81.     echo "OK: Bitcoin is online and generating blocks | {$perfdata}\n";
  82.     die(0);
  83. }
  84.  
  85. /*
  86.                     COPYRIGHT
  87.  
  88. Copyright 2007 Sergio Vaccaro <sergio@inservibile.org>
  89.  
  90. This file is part of JSON-RPC PHP.
  91.  
  92. JSON-RPC PHP is free software; you can redistribute it and/or modify
  93. it under the terms of the GNU General Public License as published by
  94. the Free Software Foundation; either version 2 of the License, or
  95. (at your option) any later version.
  96.  
  97. JSON-RPC PHP is distributed in the hope that it will be useful,
  98. but WITHOUT ANY WARRANTY; without even the implied warranty of
  99. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  100. GNU General Public License for more details.
  101.  
  102. You should have received a copy of the GNU General Public License
  103. along with JSON-RPC PHP; if not, write to the Free Software
  104. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  105. */
  106.  
  107. /**
  108.  * The object of this class are generic jsonRPC 1.0 clients
  109.  * http://json-rpc.org/wiki/specification
  110.  *
  111.  * @author sergio <jsonrpcphp@inservibile.org>
  112.  */
  113. class jsonRPCClient {
  114.    
  115.     /**
  116.      * Debug state
  117.      *
  118.      * @var boolean
  119.      */
  120.     private $debug;
  121.    
  122.     /**
  123.      * The server URL
  124.      *
  125.      * @var string
  126.      */
  127.     private $url;
  128.     /**
  129.      * The request id
  130.      *
  131.      * @var integer
  132.      */
  133.     private $id;
  134.     /**
  135.      * If true, notifications are performed instead of requests
  136.      *
  137.      * @var boolean
  138.      */
  139.     private $notification = false;
  140.    
  141.     /**
  142.      * Takes the connection parameters
  143.      *
  144.      * @param string $url
  145.      * @param boolean $debug
  146.      */
  147.     public function __construct($url,$debug = false) {
  148.         // server URL
  149.         $this->url = $url;
  150.         // proxy
  151.         empty($proxy) ? $this->proxy = '' : $this->proxy = $proxy;
  152.         // debug state
  153.         empty($debug) ? $this->debug = false : $this->debug = true;
  154.         // message id
  155.         $this->id = 1;
  156.     }
  157.    
  158.     /**
  159.      * Sets the notification state of the object. In this state, notifications are performed, instead of requests.
  160.      *
  161.      * @param boolean $notification
  162.      */
  163.     public function setRPCNotification($notification) {
  164.         empty($notification) ?
  165.                             $this->notification = false
  166.                             :
  167.                             $this->notification = true;
  168.     }
  169.    
  170.     /**
  171.      * Performs a jsonRCP request and gets the results as an array
  172.      *
  173.      * @param string $method
  174.      * @param array $params
  175.      * @return array
  176.      */
  177.     public function __call($method,$params) {
  178.        
  179.         // check
  180.         if (!is_scalar($method)) {
  181.             throw new Exception('Method name has no scalar value');
  182.         }
  183.        
  184.         // check
  185.         if (is_array($params)) {
  186.             // no keys
  187.             $params = array_values($params);
  188.         } else {
  189.             throw new Exception('Params must be given as array');
  190.         }
  191.        
  192.         // sets notification or request task
  193.         if ($this->notification) {
  194.             $currentId = NULL;
  195.         } else {
  196.             $currentId = $this->id;
  197.         }
  198.        
  199.         // prepares the request
  200.         $request = array(
  201.                         'method' => $method,
  202.                         'params' => $params,
  203.                         'id' => $currentId
  204.                         );
  205.         $request = json_encode($request);
  206.         $this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n";
  207.        
  208.         // performs the HTTP POST
  209.         $opts = array ('http' => array (
  210.                             'method'  => 'POST',
  211.                             'header'  => 'Content-type: application/json',
  212.                             'content' => $request
  213.                             ));
  214.         $context  = stream_context_create($opts);
  215.         // I added an @ infront of fopen() because I got tired of seeing warnings
  216.         if ($fp = @fopen($this->url, 'r', false, $context)) {
  217.             $response = '';
  218.             while($row = fgets($fp)) {
  219.                 $response.= trim($row)."\n";
  220.             }
  221.             $this->debug && $this->debug.='***** Server response *****'."\n".$response.'***** End of server response *****'."\n";
  222.             $response = json_decode($response,true);
  223.         } else {
  224.             throw new Exception('Unable to connect to '.$this->url);
  225.         }
  226.        
  227.         // debug output
  228.         if ($this->debug) {
  229.             echo nl2br($debug);
  230.         }
  231.        
  232.         // final checks and return
  233.         if (!$this->notification) {
  234.             // check
  235.             if ($response['id'] != $currentId) {
  236.                 throw new Exception('Incorrect response id (request id: '.$currentId.', response id: '.$response['id'].')');
  237.             }
  238.             if (!is_null($response['error'])) {
  239.                 throw new Exception('Request error: '.$response['error']);
  240.             }
  241.            
  242.             return $response['result'];
  243.            
  244.         } else {
  245.             return true;
  246.         }
  247.     }
  248. }
  249. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement