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 17import logging 18 19from health.constant_health_analyzer import HealthyIfGreaterThanConstantNumber 20from health.constant_health_analyzer import HealthyIfLessThanConstantNumber 21from health.constant_health_analyzer import HealthyIfEquals 22from health.constant_health_analyzer import HealthyIfStartsWith 23from health.custom_health_analyzer import HealthyIfNotIpAddress 24from health.constant_health_analyzer_wrapper import HealthyIfValsEqual 25 26 27class 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