]> git.datanom.net - check_http.git/blame_incremental - check_actuator_health.py
rename file
[check_http.git] / check_actuator_health.py
... / ...
CommitLineData
1#! /usr/bin/env python
2
3###############################################################################
4# Nagios plugin template
5#
6# Notes
7# - The RHEL boxes I work on are currently limited to Python 2.6.6, hence the
8# use of (deprecated) optparse. If I can ever get them all updated to
9# Python 2.7 (or better yet, 3.3), I'll switch to argparse
10# - This template runs in 2.6-3.3. Any changes made will need to be appropriate
11# to the Python distro you want to use
12#
13###############################################################################
14
15__author__ = 'mr.it@cbs.dk - Michael Rasmussen'
16__version__= 0.1
17
18try: # RHEL8 RHEL9
19 from optparse import OptionParser, OptionGroup #
20 import logging as log
21 import sys
22 import urllib3 as urllib # python3-urllib3-1.24.2-5.el8.noarch.rpm python3-urllib3-1.26.5-3.el9.noarch.rpm
23 import json
24except:
25 sys.exit(2)
26
27## These will override any args passed to the script normally. Comment out after testing.
28#testargs = '--help'
29#testargs = '--version'
30#testargs = '-vvv'
31testing = True
32
33OK_RESPONSE = """
34{
35 "status": "UP",
36 "components": {
37 "db": {
38 "status": "UP",
39 "details": {
40 "database": "PostgreSQL",
41 "validationQuery": "isValid()"
42 }
43 },
44 "diskSpace": {
45 "status": "UP",
46 "details": {
47 "total": 2013582688256,
48 "free": 1635574571008,
49 "threshold": 10485760,
50 "path": "/home/mir/git/soasi-course-catalog-course-target-adapter/.",
51 "exists": true
52 }
53 },
54 "ping": {
55 "status": "UP"
56 }
57 }
58}"""
59DOWN_RESPONSE = """
60{
61 "status": "DOWN",
62 "components": {
63 "db": {
64 "status": "DOWN",
65 "components": {
66 "adapterDataSource": {
67 "status": "DOWN",
68 "details": {
69 "error": "org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection"
70 }
71 },
72 "es3DataSource": {
73 "status": "UP",
74 "details": {
75 "database": "Microsoft SQL Server",
76 "validationQuery": "isValid()"
77 }
78 },
79 "providersDataSource": {
80 "status": "DOWN",
81 "details": {
82 "error": "org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection"
83 }
84 }
85 }
86 },
87 "diskSpace": {
88 "status": "UP",
89 "details": {
90 "total": 1013309239296,
91 "free": 882010726400,
92 "threshold": 10485760,
93 "path": "C:\\Users\\hf.it\\Projects\\smart-integrations\\adapters\\target\\soasi-invigilation-report-target-adapter",
94 "exists": true
95 }
96 },
97 "ping": {
98 "status": "UP"
99 }
100 }
101}
102"""
103def main():
104 """ Main plugin logic goes here """
105
106 ## Parse command-line arguments
107 args, args2 = parse_args()
108
109 ## Uncomment to test logging levels against verbosity settings
110 # log.debug('debug message')
111 # log.info('info message')
112 # log.warning('warning message')
113 # log.error('error message')
114 # log.critical('critical message')
115 # log.fatal('fatal message')
116 options = vars(args)
117 keyword = options['keyword']
118 url = options['url']
119 agent = options['agent']
120 if keyword is None or url is None:
121 message = "Keywork: {0} url: {1}".format(keyword, url)
122 status = 3
123 log.fatal(message)
124 else:
125 try:
126 if not testing:
127 req_headers = {
128 'User-Agent': agent
129 }
130 http = urllib.PoolManager()
131 response = http.request(
132 'GET', url, headers = req_headers
133 )
134 data = response.data.decode('utf-8').replace("\\"," ")
135 else:
136 data = DOWN_RESPONSE.replace("\\"," ")
137 data = json.loads(data)
138 if 'status' in data and data['status'] == keyword:
139 message = "UP"
140 status = 2
141 else:
142 message = gather_message(data)
143 status = 0
144 except Exception as e:
145 print(e)
146 message = "DOWN"
147 status = 2
148
149 gtfo(status, message)
150
151def gather_message(json_data):
152 """ Assemble error messages """
153 msg = None
154 try:
155 if 'components' in json_data:
156 components = json_data['components']
157 for component in components:
158 items = components[component]
159 if 'components' in items:
160 for item in items['components']:
161 if 'status' in items['components'][item] and items['components'][item]['status'].upper() == 'DOWN':
162 if msg is not None:
163 msg += "\n{0}: {1}".format(item, items['components'][item]['details']['error'])
164 else:
165 msg = "{0}: {1}".format(item, items['components'][item]['details']['error'])
166 else:
167 if 'status' in items and items['status'].upper() == 'DOWN':
168 if msg is not None:
169 if 'details' in items and 'error' in items['details']:
170 error = items['details']['error']
171 else:
172 error = "No error message"
173 if msg is not None:
174 msg += "\n{0}: {1}".format(component, error)
175 else:
176 msg = "{0}: {1}".format(component, error)
177 else:
178 sys.exit(3)
179 except:
180 sys.exit(3)
181 return msg
182
183
184def parse_args():
185 """ Parse command-line arguments """
186
187 parser = OptionParser(usage='usage: %prog [-v|vv|vvv] [options]',
188 version='{0}: v.{1} by {2}'.format('%prog', __version__, __author__))
189
190 ## Verbosity (want this first, so it's right after --help and --version)
191 parser.add_option('-v', help='Set verbosity level',
192 action='count', default=0, dest='v')
193
194 ## CLI arguments specific to this script
195 group = OptionGroup(parser,'Plugin Options')
196 group.add_option('-a', '--agent', help="User agent for request. Default: Python-nagios",
197 default="Python-nagios", type='string')
198 group.add_option('-k', '--keyword', help="Keyword to search for in response", default=None)
199 group.add_option('-t', '--testing', help="Run in testing mode", default=False, action='store_true')
200 group.add_option('-u', '--url', help="URL to requested resource", default=None)
201
202 ## Common CLI arguments
203 #parser.add_option('-c', '--critical', help='Set the critical threshold. Default: %(default)s',
204 # default=97, type=float, dest='crit', metavar='##')
205 #parser.add_option('-w', '--warning', help='Set the warning threshold. Default: %(default)s',
206 # default=95, type=float, dest='warn', metavar='##')
207
208 parser.add_option_group(group)
209
210 ## Try to parse based on the testargs variable. If it doesn't exist, use args
211 try:
212 args, args2 = parser.parse_args(testargs.split())
213 except NameError:
214 args, args2 = parser.parse_args()
215
216 ## Set the logging level based on the -v arg
217 log.getLogger().setLevel([log.ERROR, log.WARN, log.INFO, log.DEBUG][args.v])
218
219 log.debug('Parsed arguments: {0}'.format(args))
220 log.debug('Other arguments: {0}'.format(args2))
221
222 return args, args2
223
224def gtfo(exitcode, message=''):
225 """ Exit gracefully with exitcode and (optional) message """
226
227 log.debug('Exiting with status {0}. Message: {1}'.format(exitcode, message))
228
229 if message:
230 print(message)
231 exit(exitcode)
232
233if __name__ == '__main__':
234 ## Initialize logging before hitting main, in case we need extra debuggability
235 log.basicConfig(level=log.DEBUG, format='%(asctime)s - %(funcName)s - %(levelname)s - %(message)s')
236 main()
This page took 0.041622 seconds and 5 git commands to generate.