1 | #!/usr/bin/python |
---|
2 | |
---|
3 | import sys, getopt, httplib, subprocess, os, re, pdb, traceback, datetime |
---|
4 | import simplejson as json |
---|
5 | #import xml.etree.ElementTree |
---|
6 | |
---|
7 | |
---|
8 | DESCRIPTION = "Discojuice JSON" |
---|
9 | |
---|
10 | nagios_codes = { |
---|
11 | 'OK' : 0, |
---|
12 | 'WARNING' : 1, |
---|
13 | 'CRITICAL' : 2, |
---|
14 | 'UNKNOWN' : 3, |
---|
15 | 'DEPENDENT' : 4 |
---|
16 | } |
---|
17 | |
---|
18 | def usage() : |
---|
19 | """ returns nagios status UNKNOWN with |
---|
20 | a one line usage description |
---|
21 | usage() calls nagios_return() |
---|
22 | """ |
---|
23 | nagios_return('UNKNOWN', |
---|
24 | "usage: %s -h host" % (sys.argv[0])) |
---|
25 | |
---|
26 | def nagios_return_complex(results) : |
---|
27 | def deal_with_result(result) : |
---|
28 | print result['code'] + ": " + result['message'] |
---|
29 | return result['code'] |
---|
30 | |
---|
31 | # Scan all condition/status check results and create a list of appropriate exit codes. |
---|
32 | exit_code_keys = map(lambda result : deal_with_result(result), results) |
---|
33 | suggested_exit_codes = list(map(lambda key : nagios_codes[key], exit_code_keys)) |
---|
34 | |
---|
35 | # Exit with the highest suggested exit code, because the higher the exit code the more problematic the status is and problems have priority over harmony. |
---|
36 | sys.exit(max(suggested_exit_codes)) |
---|
37 | |
---|
38 | def check_response_data_well_formedness(data, descriptive_string) : |
---|
39 | |
---|
40 | timestamp = datetime.datetime.today().isoformat() |
---|
41 | |
---|
42 | try : |
---|
43 | json.loads(data) |
---|
44 | except : |
---|
45 | traceback_string = traceback.format_exc() |
---|
46 | #pdb.set_trace() |
---|
47 | |
---|
48 | err_log_file_path = os.path.normpath("/tmp/err_unparseable." + descriptive_string.replace('/' , '__') + "_" + timestamp + ".log") |
---|
49 | |
---|
50 | with open(name = err_log_file_path, mode = "wt") as debugging_output_file : |
---|
51 | debugging_output_file.write(traceback_string) |
---|
52 | |
---|
53 | return False |
---|
54 | else : |
---|
55 | return True |
---|
56 | |
---|
57 | def check_condition(host, UP_URL) : |
---|
58 | |
---|
59 | def handle_connection_failure(problem_description) : |
---|
60 | err_log_file_path = os.path.normpath("/tmp/err_connection_failure." + UP_URL.replace('/' , '__') + "_" + timestamp + ".log") |
---|
61 | |
---|
62 | with open(name = err_log_file_path, mode = "wt") as debugging_output_file : |
---|
63 | debugging_output_file.write(problem_description) |
---|
64 | |
---|
65 | timestamp = datetime.datetime.today().isoformat() |
---|
66 | |
---|
67 | try : |
---|
68 | conn = httplib.HTTPConnection(host) |
---|
69 | |
---|
70 | request = conn.request("GET", UP_URL) |
---|
71 | except : |
---|
72 | traceback_string = traceback.format_exc() |
---|
73 | |
---|
74 | handle_connection_failure(traceback_string + "\nThis problem originates from location 1 in 'check_clarin_discojuice_json.py'.") |
---|
75 | |
---|
76 | return { |
---|
77 | "code" : "CRITICAL", |
---|
78 | "message" : '[%s] HTTP connection to host %s failed.' % (DESCRIPTION, host) |
---|
79 | } |
---|
80 | else : |
---|
81 | try : |
---|
82 | response = conn.getresponse() |
---|
83 | |
---|
84 | data = response.read() |
---|
85 | |
---|
86 | conn.close() |
---|
87 | except : |
---|
88 | traceback_string = traceback.format_exc() |
---|
89 | |
---|
90 | handle_connection_failure(traceback_string + "\nThis problem originates from location 2 in 'check_clarin_discojuice_json.py'.") |
---|
91 | else : |
---|
92 | if response.status == 200 : |
---|
93 | well_formed = check_response_data_well_formedness(data, UP_URL) |
---|
94 | |
---|
95 | if well_formed : |
---|
96 | return { |
---|
97 | "code" : "OK", |
---|
98 | "message" : '[%s] Host %s is up and returns parseable JSON data at "%s".' % (DESCRIPTION, host, UP_URL) |
---|
99 | } |
---|
100 | else : |
---|
101 | return { |
---|
102 | "code" : "CRITICAL", |
---|
103 | "message" : '[%s] Host %s is up but returns unparseable JSON data at "%s".' % (DESCRIPTION, host, UP_URL) |
---|
104 | } |
---|
105 | else : |
---|
106 | |
---|
107 | handle_connection_failure("Unreachable URL: HTTP response code" + str(response.status) + "\nThis problem originates from location 3 in 'check_clarin_discojuice_json.py'.") |
---|
108 | return { |
---|
109 | "code" : "CRITICAL", |
---|
110 | "message" : '[%s] Host %s has a problem with the URL path component "%s".' % (DESCRIPTION, host, UP_URL) |
---|
111 | } |
---|
112 | |
---|
113 | def main() : |
---|
114 | """ example options processing |
---|
115 | here we're expecting 1 option "-h" |
---|
116 | with a parameter |
---|
117 | """ |
---|
118 | |
---|
119 | if len(sys.argv) < 2 : |
---|
120 | usage() |
---|
121 | |
---|
122 | try: |
---|
123 | opts, args = getopt.getopt(sys.argv[1:], "h:") |
---|
124 | except getopt.GetoptError, err : |
---|
125 | usage() |
---|
126 | |
---|
127 | for o, value in opts : |
---|
128 | if o == "-h" : |
---|
129 | host = value |
---|
130 | else : |
---|
131 | usage() |
---|
132 | |
---|
133 | UP_URLs = ("/discojuice/metadata_clarin1.json", "/discojuice/metadata_clarin2.json",) |
---|
134 | |
---|
135 | # Check status for all UP_URLs. |
---|
136 | results = map(lambda UP_URL : check_condition(host = host, UP_URL = UP_URL), |
---|
137 | UP_URLs) |
---|
138 | |
---|
139 | nagios_return_complex(results) |
---|
140 | |
---|
141 | if __name__ == "__main__" : |
---|
142 | main() |
---|