Example #1
0
    def on_updated_host(updated, original):
        """
            What to do when an host live state is updated ...

            If the host monitored state is changing, recalculate the live synthesis, else
            simply update the livesynthesis
        """
        if original['_is_template']:
            return

        # If the host is not monitored and we do not change its monitoring state
        if not original['active_checks_enabled'] and not original['passive_checks_enabled'] \
                and 'active_checks_enabled' not in updated \
                and 'passive_checks_enabled' not in updated:
            return

        minus, plus = Livesynthesis.livesynthesis_to_update('hosts', updated, original)
        if minus is not False:
            livesynthesis_db = current_app.data.driver.db['livesynthesis']
            live_current = livesynthesis_db.find_one({'_realm': original['_realm']})
            if live_current is None or 'not_monitored' in minus \
                    or (plus and 'not_monitored' in plus):
                ls = Livesynthesis()
                ls.recalculate()
            else:
                data = {"$inc": {minus: -1}}
                if plus is not False:
                    data = {"$inc": {minus: -1, plus: 1}}
                current_app.logger.debug("LS - updated host %s: %s...", original['name'], data)
                current_app.data.driver.db.livesynthesis.update({'_id': live_current['_id']}, data)

                # Send livesynthesis to TSDB
                live_current = livesynthesis_db.find_one({'_realm': original['_realm']})
                Timeseries.send_livesynthesis_metrics(original['_realm'], live_current)
Example #2
0
    def on_inserted_service(items):
        """
            What to do when a service is inserted in the backend ...
        """
        livesynthesis_db = current_app.data.driver.db['livesynthesis']
        for _, item in enumerate(items):
            if item['_is_template']:
                continue

            live_current = livesynthesis_db.find_one({'_realm': item['_realm']})
            if live_current is None:
                ls = Livesynthesis()
                ls.recalculate()
            else:
                typecheck = 'services'
                if not item['active_checks_enabled'] and not item['passive_checks_enabled']:
                    data = {"$inc": {"%s_not_monitored" % typecheck: 1,
                                     "%s_total" % typecheck: 1}}
                else:
                    data = {"$inc": {"%s_%s_%s" % (typecheck, item['ls_state'].lower(),
                                                   item['ls_state_type'].lower()): 1,
                                     "%s_total" % typecheck: 1}}
                current_app.logger.debug("LS - inserted service %s: %s...", item['name'], data)
                current_app.data.driver.db.livesynthesis.update({'_id': live_current['_id']}, data)

                # Send livesynthesis to TSDB
                live_current = livesynthesis_db.find_one({'_realm': item['_realm']})
                Timeseries.send_livesynthesis_metrics(item['_realm'], live_current)
Example #3
0
def cron_timeseries():
    """
    Cron used to add perfdata from retention to timeseries databases

    :return: None
    """
    with app.test_request_context():
        timeseriesretention_db = current_app.data.driver.db[
            'timeseriesretention']
        if timeseriesretention_db.find().count() > 0:
            tsc = timeseriesretention_db.find({
                'for_graphite': True,
                'for_influxdb': False
            })
            for data in tsc:
                if not Timeseries.send_to_timeseries_graphite([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False,
                                    **lookup)
            tsc = timeseriesretention_db.find({
                'for_graphite': False,
                'for_influxdb': True
            })
            for data in tsc:
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False,
                                    **lookup)
            tsc = timeseriesretention_db.find({
                'for_graphite': True,
                'for_influxdb': True
            })
            for data in tsc:
                graphite_serv = True
                influxdb_serv = True
                if not Timeseries.send_to_timeseries_graphite([data]):
                    graphite_serv = False
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    influxdb_serv = False
                lookup = {"_id": data['_id']}
                if graphite_serv and influxdb_serv:
                    deleteitem_internal('timeseriesretention', False, False,
                                        **lookup)
                elif graphite_serv and not influxdb_serv:
                    patch_internal('timeseriesretention',
                                   {"for_graphite": False}, False, False,
                                   **lookup)
                elif influxdb_serv and not graphite_serv:
                    patch_internal('timeseriesretention',
                                   {"for_influxdb": False}, False, False,
                                   **lookup)
def cron_timeseries():
    """
    Cron used to add perfdata from retention to timeseries databases

    :return: None
    """
    with app.test_request_context():
        timeseriesretention_db = current_app.data.driver.db['timeseriesretention']
        if timeseriesretention_db.find().count() > 0:
            tsc = timeseriesretention_db.find({'for_graphite': True, 'for_influxdb': False})
            for data in tsc:
                if not Timeseries.send_to_timeseries_graphite([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False, **lookup)
            tsc = timeseriesretention_db.find({'for_graphite': False, 'for_influxdb': True})
            for data in tsc:
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    break
                lookup = {"_id": data['_id']}
                deleteitem_internal('timeseriesretention', False, False, **lookup)
            tsc = timeseriesretention_db.find({'for_graphite': True, 'for_influxdb': True})
            for data in tsc:
                graphite_serv = True
                influxdb_serv = True
                if not Timeseries.send_to_timeseries_graphite([data]):
                    graphite_serv = False
                if not Timeseries.send_to_timeseries_influxdb([data]):
                    influxdb_serv = False
                lookup = {"_id": data['_id']}
                if graphite_serv and influxdb_serv:
                    deleteitem_internal('timeseriesretention', False, False, **lookup)
                elif graphite_serv and not influxdb_serv:
                    patch_internal('timeseriesretention', {"for_graphite": False}, False, False,
                                   **lookup)
                elif influxdb_serv and not graphite_serv:
                    patch_internal('timeseriesretention', {"for_influxdb": False}, False, False,
                                   **lookup)
Example #5
0
    def on_deleted_service(item):
        """When delete a service, decrement livesynthesis

        :param item: fields of the item deleted
        :type item: dict
        :return: None
        """
        if item['_is_template']:
            return

        livesynthesis_db = current_app.data.driver.db['livesynthesis']
        live_current = livesynthesis_db.find_one({'_realm': item['_realm']})
        if live_current is None:
            ls = Livesynthesis()
            ls.recalculate()
        else:
            minus = Livesynthesis.livesynthesis_to_delete('services', item)
            data = {"$inc": {minus: -1, 'services_total': -1}}
            current_app.logger.debug("LS - Deleted service %s: %s", item['name'], data)
            current_app.data.driver.db.livesynthesis.update({'_id': live_current['_id']}, data)

            # Send livesynthesis to TSDB
            live_current = livesynthesis_db.find_one({'_realm': item['_realm']})
            Timeseries.send_livesynthesis_metrics(item['_realm'], live_current)
    def test_prepare_data(self):
        """
        Prepare timeseries from a web perfdata

        :return: None
        """
        item = {
            'host': 'srv001',
            'service': 'check_xxx',
            'state': 'OK',
            'state_type': 'HARD',
            'state_id': 0,
            'acknowledged': False,
            'last_check': int(time.time()),
            'last_state': 'OK',
            'output': 'NGINX OK -  0.161 sec. response time, Active: 25 (Writing: 3 Reading: 0 '
                      'Waiting: 22) ReqPerSec: 58.000 ConnPerSec: 1.200 ReqPerConn: 4.466',
            'long_output': '',
            'perf_data': 'Writing=3;;;; Reading=0;;;; Waiting=22;;;; Active=25;1000;2000;; '
                         'ReqPerSec=58.000000;100;200;; ConnPerSec=1.200000;200;300;; '
                         'ReqPerConn=4.465602;;;;',
            '_realm': 'All.Propieres'
        }

        ret = Timeseries.prepare_data(item)
        reference = {
            'data': [
                {
                    'name': 'ReqPerConn',
                    'value': {
                        'name': 'ReqPerConn',
                        'min': None,
                        'max': None,
                        'value': 4.465602,
                        'warning': None,
                        'critical': None,
                        'uom': ''
                    }
                },
                {
                    'name': 'Writing',
                    'value': {
                        'name': 'Writing',
                        'min': None,
                        'max': None,
                        'value': 3,
                        'warning': None,
                        'critical': None,
                        'uom': ''
                    }
                },
                {
                    'name': 'Waiting',
                    'value': {
                        'name': 'Waiting',
                        'min': None,
                        'max': None,
                        'value': 22,
                        'warning': None,
                        'critical': None,
                        'uom': ''
                    }
                },
                {
                    'name': 'ConnPerSec',
                    'value': {
                        'name': 'ConnPerSec',
                        'min': None,
                        'max': None,
                        'value': 1.2,
                        'warning': 200,
                        'critical': 300,
                        'uom': ''
                    }
                },
                {
                    'name': 'Active',
                    'value': {
                        'name': 'Active',
                        'min': None,
                        'max': None,
                        'value': 25,
                        'warning': 1000,
                        'critical': 2000,
                        'uom': ''
                    }
                },
                {
                    'name': 'ReqPerSec',
                    'value': {
                        'name': 'ReqPerSec',
                        'min': None,
                        'max': None,
                        'value': 58,
                        'warning': 100,
                        'critical': 200,
                        'uom': ''
                    }
                },
                {
                    'name': 'Reading',
                    'value': {
                        'name': 'Reading',
                        'min': None,
                        'max': None,
                        'value': 0,
                        'warning': None,
                        'critical': None,
                        'uom': ''
                    }
                }
            ]
        }
        self.assertItemsEqual(reference, ret)
Example #7
0
    def recalculate():
        """
            Recalculate all the live synthesis counters
        """
        current_app.logger.debug("LS - Recalculating...")
        livesynthesis = current_app.data.driver.db['livesynthesis']
        realmsdrv = current_app.data.driver.db['realm']
        allrealms = realmsdrv.find()
        for _, realm in enumerate(allrealms):
            live_current = livesynthesis.find_one({'_realm': realm['_id']})
            if live_current is None:
                current_app.logger.debug("     new LS for realm %s", realm['name'])
                data = {
                    'hosts_total': 0,
                    'hosts_not_monitored': 0,
                    'hosts_up_hard': 0,
                    'hosts_up_soft': 0,
                    'hosts_down_hard': 0,
                    'hosts_down_soft': 0,
                    'hosts_unreachable_hard': 0,
                    'hosts_unreachable_soft': 0,
                    'hosts_acknowledged': 0,
                    'hosts_in_downtime': 0,
                    'hosts_flapping': 0,
                    'services_total': 0,
                    'services_not_monitored': 0,
                    'services_ok_hard': 0,
                    'services_ok_soft': 0,
                    'services_warning_hard': 0,
                    'services_warning_soft': 0,
                    'services_critical_hard': 0,
                    'services_critical_soft': 0,
                    'services_unreachable_hard': 0,
                    'services_unreachable_soft': 0,
                    'services_unknown_hard': 0,
                    'services_unknown_soft': 0,
                    'services_acknowledged': 0,
                    'services_in_downtime': 0,
                    'services_flapping': 0,
                    '_realm': realm['_id']
                }
                livesynthesis.insert(data)
                live_current = livesynthesis.find_one({'_realm': realm['_id']})

            # Update hosts live synthesis
            hosts = current_app.data.driver.db['host']
            hosts_count = hosts.count({'_is_template': False, '_realm': realm['_id']})
            data = {'hosts_total': hosts_count}

            data['hosts_not_monitored'] = hosts.count({
                '_is_template': False,
                'active_checks_enabled': False, 'passive_checks_enabled': False,
                '_realm': realm['_id']
            })
            data['hosts_up_hard'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UP', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['hosts_down_hard'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'DOWN', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['hosts_unreachable_hard'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNREACHABLE', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })

            data['hosts_up_soft'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UP', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['hosts_down_soft'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'DOWN', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['hosts_unreachable_soft'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNREACHABLE', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })

            data['hosts_acknowledged'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_acknowledged': True, '_realm': realm['_id']
            })
            data['hosts_in_downtime'] = hosts.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_downtimed': True, '_realm': realm['_id']
            })

            current_app.logger.debug("     realm %s, hosts LS: %s", realm['name'], data)

            lookup = {"_id": live_current['_id']}
            patch_internal('livesynthesis', data, False, False, **lookup)

            # Send livesynthesis to TSDB
            Timeseries.send_livesynthesis_metrics(realm['_id'], data)

            # Update services live synthesis
            services = current_app.data.driver.db['service']
            services_count = services.count({'_is_template': False, '_realm': realm['_id']})
            data = {'services_total': services_count}

            data['services_not_monitored'] = services.count({
                '_is_template': False,
                'active_checks_enabled': False, 'passive_checks_enabled': False,
                '_realm': realm['_id']
            })
            data['services_ok_hard'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'OK', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_warning_hard'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'WARNING', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_critical_hard'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'CRITICAL', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_unknown_hard'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNKNOWN', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_unreachable_hard'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNREACHABLE', 'ls_state_type': 'HARD',
                'ls_acknowledged': False, '_realm': realm['_id']
            })

            data['services_ok_soft'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'OK', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_warning_soft'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'WARNING', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_critical_soft'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'CRITICAL', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_unknown_soft'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNKNOWN', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })
            data['services_unreachable_soft'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_state': 'UNREACHABLE', 'ls_state_type': 'SOFT',
                'ls_acknowledged': False, '_realm': realm['_id']
            })

            data['services_acknowledged'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_acknowledged': True, '_realm': realm['_id']
            })
            data['services_in_downtime'] = services.count({
                '_is_template': False,
                '$or': [{'active_checks_enabled': True}, {'passive_checks_enabled': True}],
                'ls_downtimed': True, '_realm': realm['_id']
            })

            current_app.logger.debug("     realm %s, services LS: %s", realm['name'], data)

            lookup = {"_id": live_current['_id']}
            patch_internal('livesynthesis', data, False, False, **lookup)

            # Send livesynthesis to TSDB
            Timeseries.send_livesynthesis_metrics(realm['_id'], data)
Example #8
0
    def build_target(self, item, fields):
        """

        :param item: concerned host or service
        :type item: dict
        :param fields: fields of the concerned metric:
                    {'name': u'uptime_minutes',
                     'min': None, 'max': None,
                     'value': 92348,
                     'warning': None, 'critical': None,
                     'uom': u''}
        :type fields: dict
        :return:
        """
        # Find the TS corresponding to the host realm
        ts = self.timeseries[item['_realm']]
        # Add statsd, graphite and realm prefixes
        my_target = ''
        if ts['statsd_prefix'] != '':
            my_target = '$statsd_prefix'
        if ts['ts_prefix'] != '':
            my_target += '.$ts_prefix'
        if ts.get('realms_prefix'):
            my_target += '.' + Timeseries.get_realms_prefix(item['_realm'])
        if 'host' in item:
            my_target += '.' + item['hostname'] + '.' + item['name']
        else:
            my_target += '.' + item['name']
        my_target += '.' + fields['name']
        while my_target.startswith('.'):
            my_target = my_target[1:]

        # Sanitize field name for Graphite:
        # + becomes a _
        my_target = my_target.replace("+", "_")
        # / becomes a -
        my_target = my_target.replace("/", "-")
        # space becomes a _
        my_target = my_target.replace(" ", "_")
        # % becomes _pct
        my_target = my_target.replace("%", "_pct")
        # all character not in [a-zA-Z_-0-9.] is removed
        my_target = re.sub(r'[^a-zA-Z_\-0-9\.\$]', '', my_target)

        # Build path for each metric
        targets = {'main': {'name': fields['name'], 'target': my_target}}
        overrides = []
        if fields['warning'] is not None:
            targets.update({
                'warning': {
                    'name': fields['name'] + ' (w)',
                    'target': my_target + '_warning'
                }
            })
            overrides.append({
                'alias': fields['name'] + ' (w)',
                'fill': 0,
                'legend': False,
                'color': '#CCA300'
            })

        if fields['critical'] is not None:
            targets.update({
                'critical': {
                    'name': fields['name'] + ' (c)',
                    'target': my_target + '_critical'
                }
            })
            overrides.append({
                'alias': fields['name'] + ' (c)',
                'fill': 0,
                'legend': False,
                'color': '#890F02'
            })

        if fields['min'] is not None:
            targets.update({
                'min': {
                    'name': fields['name'] + ' (min)',
                    'target': my_target + '_min'
                }
            })
            overrides.append({
                'alias': fields['name'] + ' (min)',
                'fill': 0,
                'legend': False,
                'color': '#447EBC'
            })

        if fields['max'] is not None:
            targets.update({
                'max': {
                    'name': fields['name'] + ' (max)',
                    'target': my_target + '_max'
                }
            })
            overrides.append({
                'alias': fields['name'] + ' (max)',
                'fill': 0,
                'legend': False,
                'color': '#447EBC'
            })

        alias = True
        if alias:
            for t_name, t_value in iteritems(targets):
                targets[t_name] = "alias(" + t_value[
                    'target'] + ", '%s'" % t_value['name'] + ")"

        return targets, overrides