Add : first version of the receiver daemon.
[shinken.git] / libexec / check_shinken.py
blob33450757dbd75269478823cb337cc2abcfad9c93
1 #!/usr/bin/env python
2 #Copyright (C) 2009-2011 :
3 # Denis GERMAIN, dt.germain@gmail.com
4 # Gabes Jean, naparuba@gmail.com
5 # Gerhard Lausser, Gerhard.Lausser@consol.de
6 # Gregory Starck, g.starck@gmail.com
7 # Hartmut Goebel, h.goebel@goebel-consult.de
9 #This file is part of Shinken.
11 #Shinken is free software: you can redistribute it and/or modify
12 #it under the terms of the GNU Affero General Public License as published by
13 #the Free Software Foundation, either version 3 of the License, or
14 #(at your option) any later version.
16 #Shinken is distributed in the hope that it will be useful,
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 #GNU Affero General Public License for more details.
21 #You should have received a copy of the GNU Affero General Public License
22 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
24 ################################################
25 # check_shinken.py :
26 # This check is getting daemons state from
27 # a arbiter connexion.
28 ################################################
30 import os
32 # Exit statuses recognized by Nagios and thus by Shinken
33 OK = 0
34 WARNING = 1
35 CRITICAL = 2
36 UNKNOWN = 3
38 #Name of the Pyro Object we are searching
39 PYRO_OBJECT = 'ForArbiter'
40 daemon_types = ['arbiter', 'broker', 'scheduler', 'poller', 'reactionner']
42 try:
43 import shinken
44 except ImportError:
45 # If importing shinken fails, try to load from current directory
46 # or parent directory to support running without installation.
47 # Submodules will then be loaded from there, too.
48 import imp
49 if not hasattr(os, "getuid") or os.getuid() != 0:
50 imp.load_module('shinken', *imp.find_module('shinken', [".", ".."]))
53 from optparse import OptionParser
54 try:
55 import shinken.pyro_wrapper as pyro
56 from shinken.pyro_wrapper import Pyro
57 except ImportError, exp:
58 print 'CRITICAL : check_shinken requires the Python Pyro and the shinken.pyro_wrapper module. Please install it. (%s)' % exp
59 raise SystemExit, CRITICAL
62 def check_deamons_numbers(result, target):
63 total_number = len(result)
64 alive_number = len([e for e in result.values() if e['alive']])
65 total_spare_number = len([e for e in result.values() if e['spare']])
66 alive_spare_number = len([e for e in result.values() if e['spare'] and e['alive']])
67 dead_number = total_number - alive_number
68 dead_list = ','.join([n for n in result if not result[n]['alive']])
69 #TODO : perfdata to graph deamons would be nice (in big HA architectures)
70 #if alive_number <= critical, then we have a big problem
71 if alive_number <= options.critical:
72 print "CRITICAL - only %d/%d %s(s) UP. Down elements : %s" % (alive_number, total_number, target, dead_list)
73 raise SystemExit, CRITICAL
74 #We are not in a case where there is no more daemons, but are there daemons down?
75 elif dead_number >= options.warning:
76 print "WARNING - %d/%d %s(s) DOWN :%s" % (dead_number, total_number, target, dead_list)
77 raise SystemExit, WARNING
78 #Everything seems fine. But that's no surprise, is it?
79 else :
80 print "OK - %d/%d %s(s) UP, with %d/%d spare(s) UP" % (alive_number, total_number, target, alive_spare_number, total_spare_number)
81 raise SystemExit, OK
83 # Adding options. None are required, check_shinken will use shinken defaults
84 #TODO : Add more control in args problem and usage than the default OptionParser one
85 parser = OptionParser()
86 parser.add_option('-a', '--hostname', dest='hostname', default='127.0.0.1')
87 parser.add_option('-p', '--portnumber', dest='portnum', default=7770)
88 parser.add_option('-s', '--ssl', dest='ssl', default=False)
89 #TODO : Add a list of correct values for target and don't authorize anything else
90 parser.add_option('-t', '--target', dest='target')
91 parser.add_option('-d', '--daemonname', dest='daemon', default='')
92 #In HA architectures, a warning should be displayed if there's one daemon down
93 parser.add_option('-w','--warning', dest='warning', default = 1)
94 #If no deamon is left, display a critical (but shinken will be probably dead already)
95 parser.add_option('-c', '--critical', dest='critical', default = 0)
97 #Retrieving options
98 options, args = parser.parse_args()
99 #TODO : for now, helpme doesn't work as desired
100 options.helpme = False
102 # Check for required option target
103 if not getattr(options, 'target'):
104 print 'CRITICAL - target is not specified; You must specify which daemons you want to check!'
105 parser.print_help()
106 raise SystemExit, CRITICAL
107 elif options.target not in daemon_types:
108 print 'CRITICAL - target %s is not a Shinken daemon!' % options.target
109 parser.print_help()
110 raise SystemExit, CRITICAL
112 uri = pyro.create_uri(options.hostname, options.portnum, PYRO_OBJECT , options.ssl)
114 if options.daemon:
115 # We just want a check for a single satellite daemon
116 # Only OK or CRITICAL here
117 daemon_name = options.daemon
118 try:
119 result = Pyro.core.getProxyForURI(uri).get_satellite_status(options.target, daemon_name)
120 except Pyro.errors.ProtocolError, exp:
121 print "CRITICAL : the Arbiter is not reachable : (%s)." % exp
122 raise SystemExit, CRITICAL
124 if result:
125 if result['alive']:
126 print 'OK - %s alive' % daemon_name
127 raise SystemExit, OK
128 else:
129 print 'CRITICAL - %s down' % daemon_name
130 raise SystemExit, CRITICAL
131 else:
132 print 'UNKNOWN - %s status could not be retrieved' % daemon_name
133 raise SystemExit, UNKNOWN
134 else:
135 # If no daemonname is specified, we want a general overview of the "target" daemons
136 result = {}
138 try:
139 daemon_list = Pyro.core.getProxyForURI(uri).get_satellite_list(options.target)
140 except Pyro.errors.ProtocolError, exp:
141 print "CRITICAL : the Arbiter is not reachable : (%s)." % exp
142 raise SystemExit, CRITICAL
144 for daemon_name in daemon_list:
145 # Getting individual daemon and putting status info in the result dictionnary
146 try:
147 result[daemon_name] = Pyro.core.getProxyForURI(uri).get_satellite_status(options.target, daemon_name)
148 except Pyro.errors.ProtocolError, exp:
149 print "CRITICAL : the Arbiter is not reachable : (%s)." % exp
150 raise SystemExit, CRITICAL
152 # Now we have all data
153 if result:
154 check_deamons_numbers(result, options.target)
155 else :
156 print 'UNKNOWN - Arbiter could not retrieve status for %s' % options.target
157 raise SystemExit, UNKNOWN