コード例 #1
0
def test_stats():
    # The min is not enabled by default
    stats = Stats()

    metric_stats = {
        'foo': 2,
        'bar': 5,
    }

    # setters
    stats.set_stat('metrics', 4)
    stats.set_stat('events', 2)
    stats.set_stat('service_checks', 1)
    # totals
    stats.inc_stat('metrics_total', 4)
    stats.inc_stat('events_total', 2)
    stats.inc_stat('service_checks_total', 1)
    # info
    stats.set_info('metric_stats', metric_stats)

    stats_snapshot, info_snapshot = stats.snapshot()
    assert info_snapshot['metric_stats'] == metric_stats
    assert stats_snapshot['metrics'] == 4
    assert stats_snapshot['events'] == 2
    assert stats_snapshot['service_checks'] == 1
    assert stats_snapshot['metrics_total'] == 4
    assert stats_snapshot['events_total'] == 2
    assert stats_snapshot['service_checks_total'] == 1

    # test we got a deepcopy for stats
    stats.set_stat('metrics', 10)
    stats.inc_stat('metrics_total', 10)
    assert stats_snapshot != metric_stats
    assert stats_snapshot['metrics'] != stats.get_stat('metrics')

    # test we got a deepcopy for info
    metric_stats['bar'] += 1
    stats.set_info('metric_stats', metric_stats)
    assert info_snapshot != metric_stats
    assert info_snapshot['metric_stats']['foo'] == metric_stats['foo']
    assert info_snapshot['metric_stats']['bar'] != metric_stats['bar']

    # test for updated snapshots
    stats_snapshot, info_snapshot = stats.snapshot()
    assert stats_snapshot['metrics'] == 10
    assert stats_snapshot['metrics_total'] == 14
    assert info_snapshot['metric_stats']['foo'] == metric_stats['foo']
    assert info_snapshot['metric_stats']['bar'] == metric_stats['bar']

    # test strict get
    with pytest.raises(KeyError):
        stats.get_stat('nonexistent', strict=True)
    with pytest.raises(KeyError):
        stats.get_info('nonexistent', strict=True)
コード例 #2
0
class Collector(object):
    CORE_CHECKS = ['cpu', 'load', 'iostat', 'memory', 'filesystem', 'uptime']

    def __init__(self, config, aggregator=None):
        self._config = config
        self._loaders = []
        self._check_classes = {}
        self._check_classes_errors = defaultdict(dict)
        self._check_instance_errors = defaultdict(dict)
        self._check_instances = defaultdict(list)
        self._check_instance_signatures = {}
        self._hostname = get_hostname()
        self._aggregator = aggregator
        self._status = Stats()

        self.set_loaders()

    def set_loaders(self):
        check_loader = CheckLoader()
        check_loader.add_place(self._config['additional_checksd'])
        self._loaders = [check_loader]
        self._loaders.append(WheelLoader(namespace=DD_WHEEL_NAMESPACE))

    def set_aggregator(self, aggregator):
        if not isinstance(aggregator, Aggregator):
            raise ValueError('argument should be of type Aggregator')

        self._aggregator = aggregator

    @property
    def status(self):
        return self._status

    def load_core_checks(self):
        from checks.corechecks.system import (Cpu, Load, Memory, IOStat,
                                              Filesystem, UptimeCheck)
        self._check_classes['cpu'] = Cpu
        self._check_classes['filesystem'] = Filesystem
        self._check_classes['iostat'] = IOStat
        self._check_classes['load'] = Load
        self._check_classes['memory'] = Memory
        self._check_classes['filesystem'] = Filesystem
        self._check_classes['uptime'] = UptimeCheck

    def load_check_classes(self):
        self.load_core_checks()

        for _, check_configs in self._config.get_check_configs().items():
            for check_name in check_configs:
                log.debug("Found config for check %s...", check_name)

                if check_name in self._check_classes:
                    continue

                for loader in self._loaders:
                    try:
                        check_class, errors = loader.load(check_name)
                        if check_class:
                            self._check_classes[check_name] = check_class
                        if errors:
                            self._check_classes_errors[check_name][type(
                                loader).__name__] = errors

                        if check_class:
                            log.debug("Class found for %s...", check_name)
                            break
                    except Exception:
                        log.exception("unexpected error loading check %s",
                                      check_name)

        self._status.set_info('check_classes', copy(
            self._check_classes))  # shallow copy suffices
        self._status.set_info('loader_errors',
                              deepcopy(self._check_classes_errors))

    def instantiate_checks(self):
        for source, check_configs in self._config.get_check_configs().items():
            for check_name, configs in check_configs.items():
                log.debug('Trying to instantiate: %s', check_name)
                check_class = self._check_classes.get(check_name)
                if check_class:
                    for config in configs:
                        init_config = config.get('init_config', {})
                        if init_config is None:
                            init_config = {}
                        instances = config.get(
                            'instances')  # should be single instance
                        for instance in instances:
                            signature = (check_name, init_config, instance)
                            signature_hash = AgentCheck.signature_hash(
                                *signature)
                            if signature_hash in self._check_instance_signatures:
                                log.info(
                                    'instance with identical signature already configured - skipping'
                                )
                                continue

                            try:
                                check_instance = check_class(
                                    check_name, init_config, instance,
                                    self._aggregator)
                                self._check_instances[check_name].append(
                                    check_instance)
                                self._check_instance_signatures[
                                    signature_hash] = signature
                            except Exception as e:
                                log.error(
                                    "unable to instantiate instance %s for %s: %s",
                                    instance, check_name, e)

        for check_name in self.CORE_CHECKS:
            if check_name in self._check_instances:
                # already instantiated - skip
                continue

            check_class = self._check_classes[check_name]
            signature = (check_name, {}, {})
            signature_hash = AgentCheck.signature_hash(*signature)
            try:
                check_instance = check_class(*signature)
                check_instance.set_aggregator(self._aggregator)
                self._check_instances[check_name] = [check_instance]
                self._check_instance_signatures[signature_hash] = signature
            except Exception:
                log.error("unable to instantiate core check %s", check_name)

    def run_checks(self):
        for name, checks in self._check_instances.items():
            log.info('running check %s...', name)
            for check in checks:
                try:
                    result = check.run()
                except Exception:
                    log.exception("error for instance: %s",
                                  str(check.instance))

                if result:
                    self._check_instance_errors[name][check.signature] = result
                    log.error('There was an error running your %s: %s', name,
                              result.get('message'))
                    log.error('Traceback %s: %s', name,
                              result.get('traceback'))

        self._status.set_info('runtime_errors',
                              deepcopy(self._check_instance_errors))