GUI CSS: Removed snapin styles from py modules and added a _snapins.scss for the...
[check_mk.git] / checks / aws_elb
blobef5d1dcff8c2f3f189e26fb9ffe190457e35d5d6
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2019 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
28 def parse_aws_elb(info):
29 metrics = _extract_aws_metrics_by_labels([
30 "RequestCount",
31 "SurgeQueueLength",
32 "SpilloverCount",
33 "Latency",
34 "HTTPCode_ELB_4XX",
35 "HTTPCode_ELB_5XX",
36 "HTTPCode_Backend_2XX",
37 "HTTPCode_Backend_3XX",
38 "HTTPCode_Backend_4XX",
39 "HTTPCode_Backend_5XX",
40 "HealthyHostCount",
41 "UnHealthyHostCount",
42 "BackendConnectionErrors",
43 ], parse_aws(info))
44 # We get exactly one entry: {INST-ID: METRICS}
45 # INST-ID is the piggyback host name
46 try:
47 return metrics.values()[-1]
48 except IndexError:
49 return {}
52 # .--statistics----------------------------------------------------------.
53 # | _ _ _ _ _ |
54 # | ___| |_ __ _| |_(_)___| |_(_) ___ ___ |
55 # | / __| __/ _` | __| / __| __| |/ __/ __| |
56 # | \__ \ || (_| | |_| \__ \ |_| | (__\__ \ |
57 # | |___/\__\__,_|\__|_|___/\__|_|\___|___/ |
58 # | |
59 # '----------------------------------------------------------------------'
61 # SpilloverCount: When the SurgeQueueLength reaches the maximum of 1,024 queued
62 # Requests, new requests are dropped, the user receives a 503 error, and the
63 # Spillover count metric is incremented. In a healthy system, this metric is
64 # Always equal to zero.
66 factory_settings['aws_elb_statistics'] = {
67 'levels_surge_queue_length': (1024, 1024),
68 'levels_spillover': (1, 1),
72 def check_aws_elb_statistics(item, params, parsed):
73 queue_length = parsed.get('SurgeQueueLength')
74 if queue_length is not None:
75 yield check_levels(
76 queue_length,
77 'aws_surge_queue_length',
78 params['levels_surge_queue_length'],
79 infoname='Surge queue length')
81 spillover = parsed.get('SpilloverCount')
82 if spillover is not None:
83 yield check_levels(
84 spillover, 'aws_spillover', params['levels_spillover'], infoname='Spillover')
87 check_info['aws_elb'] = {
88 'parse_function': parse_aws_elb,
89 'inventory_function': lambda p: inventory_aws_generic_single(
90 p, ['SurgeQueueLength', 'SpilloverCount']),
91 'check_function': check_aws_elb_statistics,
92 'service_description': 'AWS/ELB Statistics',
93 'includes': ['aws.include'],
94 'has_perfdata': True,
95 'default_levels_variable': 'aws_elb_statistics',
96 'group': 'aws_elb_statistics',
100 # .--latency-------------------------------------------------------------.
101 # | _ _ |
102 # | | | __ _| |_ ___ _ __ ___ _ _ |
103 # | | |/ _` | __/ _ \ '_ \ / __| | | | |
104 # | | | (_| | || __/ | | | (__| |_| | |
105 # | |_|\__,_|\__\___|_| |_|\___|\__, | |
106 # | |___/ |
107 # '----------------------------------------------------------------------'
110 def check_aws_elb_latency(item, params, parsed):
111 latency = parsed.get("Latency")
112 if latency is not None:
113 yield check_levels(
114 latency,
115 'aws_load_balancer_latency',
116 params.get('levels_latency'),
117 human_readable_func=get_age_human_readable)
120 check_info['aws_elb.latency'] = {
121 'inventory_function': lambda p: inventory_aws_generic_single(p, ['Latency']),
122 'check_function': check_aws_elb_latency,
123 'service_description': 'AWS/ELB Latency',
124 'includes': ['aws.include'],
125 'has_perfdata': True,
126 'group': 'aws_elb_latency',
130 # .--HTTP ELB------------------------------------------------------------.
131 # | _ _ _____ _____ ____ _____ _ ____ |
132 # | | | | |_ _|_ _| _ \ | ____| | | __ ) |
133 # | | |_| | | | | | | |_) | | _| | | | _ \ |
134 # | | _ | | | | | | __/ | |___| |___| |_) | |
135 # | |_| |_| |_| |_| |_| |_____|_____|____/ |
136 # | |
137 # '----------------------------------------------------------------------'
140 def check_aws_elb_http_elb(item, params, parsed):
141 now = time.time()
142 request_count = parsed.get('RequestCount')
143 if request_count is not None:
144 request_rate = get_rate('aws_elb_statistics', now, request_count)
145 yield 0, 'Requests: %s/s' % request_rate, [('requests_per_second', request_rate)]
146 else:
147 request_rate = 0
149 for http_errors_nr in ["4", "5"]:
150 http_errors = parsed.get('HTTPCode_ELB_%sXX' % http_errors_nr)
151 if http_errors is None:
152 continue
154 http_errors_rate = get_rate('aws_elb_http_backend.%sxx' % http_errors_nr, now, http_errors)
155 yield (0, '%s00-Errors: %s/s' % (http_errors_nr, http_errors_rate),
156 [('http_%sxx_rate' % http_errors_nr, http_errors_rate)])
158 try:
159 http_errors_perc = 100.0 * http_errors_rate / request_rate
160 except ZeroDivisionError:
161 pass
162 else:
163 yield check_levels(
164 http_errors_perc,
165 'http_%sxx_perc' % http_errors_nr,
166 params.get('levels_http_%sxx_perc' % http_errors_nr),
167 human_readable_func=get_percent_human_readable,
168 infoname="%s00-Errors of total requests" % http_errors_nr)
171 check_info['aws_elb.http_elb'] = {
172 'inventory_function': lambda p: inventory_aws_generic_single(
173 p, ['RequestCount', 'HTTPCode_ELB_4XX', 'HTTPCode_ELB_5XX']),
174 'check_function': check_aws_elb_http_elb,
175 'service_description': 'AWS/ELB HTTP ELB',
176 'includes': ['aws.include'],
177 'has_perfdata': True,
178 'group': 'aws_elb_http',
182 # .--HTTP Backend--------------------------------------------------------.
183 # | _ _ _____ _____ ____ ____ _ _ |
184 # | | | | |_ _|_ _| _ \ | __ ) __ _ ___| | _____ _ __ __| | |
185 # | | |_| | | | | | | |_) | | _ \ / _` |/ __| |/ / _ \ '_ \ / _` | |
186 # | | _ | | | | | | __/ | |_) | (_| | (__| < __/ | | | (_| | |
187 # | |_| |_| |_| |_| |_| |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |
188 # | |
189 # '----------------------------------------------------------------------'
192 def check_aws_elb_http_backend(item, params, parsed):
193 now = time.time()
194 request_count = parsed.get('RequestCount')
195 if request_count is not None:
196 request_rate = get_rate('aws_elb_statistics', now, request_count)
197 yield 0, 'Requests: %s/s' % request_rate, [('requests_per_second', request_rate)]
198 else:
199 request_rate = 0
201 for http_errors_nr in ["4", "5"]:
202 http_errors = parsed.get('HTTPCode_ELB_%sXX' % http_errors_nr)
203 if http_errors is None:
204 continue
206 http_errors_rate = get_rate('aws_elb_http_backend.%sxx' % http_errors_nr, now, http_errors)
207 yield (0, '%s00-Errors: %s/s' % (http_errors_nr, http_errors_rate),
208 [('http_%sxx_rate' % http_errors_nr, http_errors_rate)])
210 try:
211 http_errors_perc = 100.0 * http_errors_rate / request_rate
212 except ZeroDivisionError:
213 pass
214 else:
215 yield check_levels(
216 http_errors_perc,
217 'http_%sxx_perc' % http_errors_nr,
218 params.get('levels_http_%sxx_perc' % http_errors_nr),
219 human_readable_func=get_percent_human_readable,
220 infoname="%s00-Errors of total requests" % http_errors_nr)
222 http_backend_2xx = parsed.get('HTTPCode_Backend_2XX')
223 if http_backend_2xx is not None:
224 yield 0, '200-Requests: %s/s' % get_rate('aws_elb_http_backend.2xx', now, http_backend_2xx)
226 http_backend_3xx = parsed.get('HTTPCode_Backend_3XX')
227 if http_backend_3xx is not None:
228 yield 0, '300-Requests: %s/s' % get_rate('aws_elb_http_backend.3xx', now, http_backend_3xx)
231 check_info['aws_elb.http_backend'] = {
232 'inventory_function': lambda p: inventory_aws_generic_single(p, [
233 'RequestCount', 'HTTPCode_Backend_2XX', 'HTTPCode_Backend_3XX', 'HTTPCode_Backend_4XX',
234 'HTTPCode_Backend_5XX'
236 'check_function': check_aws_elb_http_backend,
237 'service_description': 'AWS/ELB HTTP Backend',
238 'includes': ['aws.include'],
239 'has_perfdata': True,
240 'group': 'aws_elb_http',
244 # .--Healthy hosts-------------------------------------------------------.
245 # | _ _ _ _ _ _ _ |
246 # | | | | | ___ __ _| | |_| |__ _ _ | |__ ___ ___| |_ ___ |
247 # | | |_| |/ _ \/ _` | | __| '_ \| | | | | '_ \ / _ \/ __| __/ __| |
248 # | | _ | __/ (_| | | |_| | | | |_| | | | | | (_) \__ \ |_\__ \ |
249 # | |_| |_|\___|\__,_|_|\__|_| |_|\__, | |_| |_|\___/|___/\__|___/ |
250 # | |___/ |
251 # '----------------------------------------------------------------------'
254 def check_aws_elb_healthy_hosts(item, params, parsed):
255 try:
256 healthy_hosts = int(parsed["HealthyHostCount"])
257 except (KeyError, ValueError):
258 healthy_hosts = None
260 try:
261 unhealthy_hosts = int(parsed["UnHealthyHostCount"])
262 except (KeyError, ValueError):
263 unhealthy_hosts = None
265 if healthy_hosts is not None:
266 yield 0, 'Healthy hosts: %s' % healthy_hosts
268 if unhealthy_hosts is not None:
269 yield 0, 'Unhealthy hosts: %s' % unhealthy_hosts
271 if healthy_hosts is not None and unhealthy_hosts is not None:
272 total_hosts = unhealthy_hosts + healthy_hosts
273 yield 0, 'Total: %s' % total_hosts
275 try:
276 perc = 100.0 * healthy_hosts / total_hosts
277 except ZeroDivisionError:
278 perc = None
280 if perc is not None:
281 yield check_levels(
282 perc,
283 'aws_overall_hosts_health_perc',
284 params.get('levels_overall_hosts_health_perc'),
285 human_readable_func=get_percent_human_readable,
286 infoname="Proportion of healthy hosts")
289 check_info['aws_elb.healthy_hosts'] = {
290 'inventory_function': lambda p: inventory_aws_generic_single(
291 p, ['HealthyHostCount', 'UnHealthyHostCount']),
292 'check_function': check_aws_elb_healthy_hosts,
293 'service_description': 'AWS/ELB Healthy Hosts',
294 'includes': ['aws.include'],
295 'group': 'aws_elb_healthy_hosts',
299 # .--Backend errors------------------------------------------------------.
300 # | ____ _ _ |
301 # | | __ ) __ _ ___| | _____ _ __ __| | |
302 # | | _ \ / _` |/ __| |/ / _ \ '_ \ / _` | |
303 # | | |_) | (_| | (__| < __/ | | | (_| | |
304 # | |____/ \__,_|\___|_|\_\___|_| |_|\__,_| |
305 # | |
306 # | |
307 # | ___ _ __ _ __ ___ _ __ ___ |
308 # | / _ \ '__| '__/ _ \| '__/ __| |
309 # | | __/ | | | | (_) | | \__ \ |
310 # | \___|_| |_| \___/|_| |___/ |
311 # | |
312 # '----------------------------------------------------------------------'
315 def check_aws_elb_backend_connection_errors(item, params, parsed):
316 now = time.time()
317 backend_connection_errors = parsed.get("BackendConnectionErrors")
318 if backend_connection_errors is not None:
319 yield check_levels(
320 get_rate('aws_elb_backend_connection_errors', now, backend_connection_errors),
321 'backend_connection_errors_rate', params.get('levels_backend_connection_errors_rate'))
324 check_info['aws_elb.backend_connection_errors'] = {
325 'inventory_function': lambda p: inventory_aws_generic_single(p, ['BackendConnectionErrors']),
326 'check_function': check_aws_elb_backend_connection_errors,
327 'service_description': 'AWS/ELB Backend Connection Errors',
328 'includes': ['aws.include'],
329 'has_perfdata': True,
330 'group': 'aws_elb_backend_connection_errors',