• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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