Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright 2017 - The Android Open Source Project |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | |
Annie Chen | 5d7e400 | 2017-07-14 11:02:10 -0700 | [diff] [blame] | 17 | import logging |
| 18 | |
Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 19 | from health.constant_health_analyzer import HealthyIfGreaterThanConstantNumber |
| 20 | from health.constant_health_analyzer import HealthyIfLessThanConstantNumber |
| 21 | from health.constant_health_analyzer import HealthyIfEquals |
Cameron Moberg | a95211e | 2017-08-07 15:59:44 -0700 | [diff] [blame] | 22 | from health.constant_health_analyzer import HealthyIfStartsWith |
Cameron Moberg | 8451719 | 2017-06-28 17:35:07 -0700 | [diff] [blame] | 23 | from health.custom_health_analyzer import HealthyIfNotIpAddress |
Annie Chen | 87af10c | 2017-06-30 17:57:39 -0700 | [diff] [blame] | 24 | from health.constant_health_analyzer_wrapper import HealthyIfValsEqual |
Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 25 | |
| 26 | |
| 27 | class HealthChecker(object): |
| 28 | """Takes a dictionary of metrics and returns whether each is healthy |
| 29 | Attributes: |
| 30 | _analyzers: a list of metric, analyzer tuples where metric is a string |
| 31 | representing a metric name ('DiskMetric') and analyzer is a |
| 32 | constant_health_analyzer object |
Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 33 | config: |
| 34 | a dict formatted as follows: |
| 35 | { |
| 36 | metric_name: { |
| 37 | field_to_compare: { |
| 38 | constant : a constant to compare to |
| 39 | compare : a string specifying a way to compare |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | |
| 45 | """ |
| 46 | |
| 47 | COMPARER_CONSTRUCTOR = { |
| 48 | 'GREATER_THAN': lambda k, c: HealthyIfGreaterThanConstantNumber(k, c), |
| 49 | 'LESS_THAN': lambda k, c: HealthyIfLessThanConstantNumber(k, c), |
Cameron Moberg | 8451719 | 2017-06-28 17:35:07 -0700 | [diff] [blame] | 50 | 'EQUALS': lambda k, c: HealthyIfEquals(k, c), |
Annie Chen | 87af10c | 2017-06-30 17:57:39 -0700 | [diff] [blame] | 51 | 'IP_ADDR': lambda k, c: HealthyIfNotIpAddress(k), |
Cameron Moberg | a95211e | 2017-08-07 15:59:44 -0700 | [diff] [blame] | 52 | 'EQUALS_DICT': lambda k, c: HealthyIfValsEqual(k, c), |
| 53 | 'STARTS_WITH': lambda k, c: HealthyIfStartsWith(k, c) |
Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | def __init__(self, config): |
| 57 | self._config = config |
| 58 | self._analyzers = [] |
| 59 | # Create comparators from config object |
| 60 | for metric_name, metric_configs in self._config.items(): |
| 61 | # creates a constant_health_analyzer object for each field |
| 62 | for field_name in metric_configs: |
| 63 | compare_type = metric_configs[field_name]['compare'] |
| 64 | constant = metric_configs[field_name]['constant'] |
| 65 | comparer = self.COMPARER_CONSTRUCTOR[compare_type](field_name, |
| 66 | constant) |
| 67 | self._analyzers.append((metric_name, comparer)) |
| 68 | |
| 69 | def get_unhealthy(self, response_dict): |
| 70 | """Calls comparators to check if metrics are healthy |
| 71 | |
| 72 | Attributes: |
| 73 | response_dict: a dict mapping metric names (as strings) to the |
| 74 | responses returned from gather_metric() |
| 75 | |
| 76 | Returns: |
| 77 | a list of keys, where keys are strings representing |
| 78 | the name of a metric (ex: 'DiskMetric') |
| 79 | """ |
| 80 | # loop through and check if healthy |
| 81 | unhealthy_metrics = [] |
| 82 | for (metric, analyzer) in self._analyzers: |
Annie Chen | 5d7e400 | 2017-07-14 11:02:10 -0700 | [diff] [blame] | 83 | try: |
| 84 | # if not healthy, add to list so value can be reported |
| 85 | if not analyzer.is_healthy(response_dict[metric]): |
| 86 | unhealthy_metrics.append(metric) |
| 87 | # don't exit whole program if error in config file, just report |
| 88 | except KeyError as e: |
| 89 | logging.warning( |
| 90 | 'Error in config file, "%s" not a health metric\n' % e) |
| 91 | |
Annie Chen | 60002cf | 2017-06-15 11:25:54 -0700 | [diff] [blame] | 92 | return unhealthy_metrics |