Home | History | Annotate | Download | only in lab
      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 
     17 import logging
     18 
     19 from health.constant_health_analyzer import HealthyIfGreaterThanConstantNumber
     20 from health.constant_health_analyzer import HealthyIfLessThanConstantNumber
     21 from health.constant_health_analyzer import HealthyIfEquals
     22 from health.constant_health_analyzer import HealthyIfStartsWith
     23 from health.custom_health_analyzer import HealthyIfNotIpAddress
     24 from health.constant_health_analyzer_wrapper import HealthyIfValsEqual
     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
     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),
     50         'EQUALS': lambda k, c: HealthyIfEquals(k, c),
     51         'IP_ADDR': lambda k, c: HealthyIfNotIpAddress(k),
     52         'EQUALS_DICT': lambda k, c: HealthyIfValsEqual(k, c),
     53         'STARTS_WITH': lambda k, c: HealthyIfStartsWith(k, c)
     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:
     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 
     92         return unhealthy_metrics
     93