Esempio n. 1
0
    def submit_metric(self, name, snmp_value, forced_type, tags):
        # type: (str, Any, Optional[str], List[str]) -> None
        """
        Convert the values reported as pysnmp-Managed Objects to values and
        report them to the aggregator.
        """
        if reply_invalid(snmp_value):
            # Metrics not present in the queried object
            self.log.warning('No such Mib available: %s', name)
            return

        metric_name = self.normalize(name, prefix='snmp')

        value = 0.0  # type: float

        if forced_type:
            forced_type = forced_type.lower()
            if forced_type == 'gauge':
                value = int(snmp_value)
                self.gauge(metric_name, value, tags)
            elif forced_type == 'percent':
                value = total_time_to_temporal_percent(int(snmp_value),
                                                       scale=1)
                self.rate(metric_name, value, tags)
            elif forced_type == 'counter':
                value = int(snmp_value)
                self.rate(metric_name, value, tags)
            elif forced_type == 'monotonic_count':
                value = int(snmp_value)
                self.monotonic_count(metric_name, value, tags)
            else:
                self.warning('Invalid forced-type specified: %s in %s',
                             forced_type, name)
                raise ConfigurationError(
                    'Invalid forced-type in config file: {}'.format(name))
            return

        # Ugly hack but couldn't find a cleaner way
        # Proper way would be to use the ASN1 method isSameTypeWith but it
        # wrongfully returns True in the case of CounterBasedGauge64
        # and Counter64 for example
        snmp_class = snmp_value.__class__.__name__
        if snmp_class in SNMP_COUNTERS:
            value = int(snmp_value)
            self.rate(metric_name, value, tags)
            return
        if snmp_class in SNMP_GAUGES:
            value = int(snmp_value)
            self.gauge(metric_name, value, tags)
            return

        if snmp_class == 'Opaque':
            # Try support for floats
            try:
                value = float(decoder.decode(bytes(snmp_value))[0])
            except Exception:
                pass
            else:
                self.gauge(metric_name, value, tags)
                return

        # Falls back to try to cast the value.
        try:
            value = float(snmp_value)
        except ValueError:
            pass
        else:
            self.gauge(metric_name, value, tags)
            return

        self.log.warning('Unsupported metric type %s for %s', snmp_class,
                         metric_name)
Esempio n. 2
0
    def __init__(self, name, init_config, instances=None):
        super(MongoDb, self).__init__(name, init_config, instances)

        # Members' last replica set states
        self._last_state_by_server = {}

        self.collection_metrics_names = tuple(
            key.split('.')[1] for key in metrics.COLLECTION_METRICS)

        # x.509 authentication
        ssl_params = {
            'ssl': self.instance.get('ssl', None),
            'ssl_keyfile': self.instance.get('ssl_keyfile', None),
            'ssl_certfile': self.instance.get('ssl_certfile', None),
            'ssl_cert_reqs': self.instance.get('ssl_cert_reqs', None),
            'ssl_ca_certs': self.instance.get('ssl_ca_certs', None),
        }
        self.ssl_params = {
            key: value
            for key, value in iteritems(ssl_params) if value is not None
        }

        if 'server' in self.instance:
            self.warning(
                'Option `server` is deprecated and will be removed in a future release. Use `hosts` instead.'
            )
            self.server = self.instance['server']
        else:
            hosts = self.instance.get('hosts', [])
            if not hosts:
                raise ConfigurationError('No `hosts` specified')

            username = self.instance.get('username')
            password = self.instance.get('password')

            if username and not password:
                raise ConfigurationError(
                    '`password` must be set when a `username` is specified')

            if password and not username:
                raise ConfigurationError(
                    '`username` must be set when a `password` is specified')

            self.server = self._build_connection_string(
                hosts,
                scheme=self.instance.get('connection_scheme', 'mongodb'),
                username=username,
                password=password,
                database=self.instance.get('database'),
                options=self.instance.get('options'),
            )

        (
            self.username,
            self.password,
            self.db_name,
            self.nodelist,
            self.clean_server_name,
            self.auth_source,
        ) = self._parse_uri(self.server,
                            sanitize_username=bool(self.ssl_params))

        self.additional_metrics = self.instance.get('additional_metrics', [])

        # Get the list of metrics to collect
        self.collect_tcmalloc_metrics = 'tcmalloc' in self.additional_metrics
        self.metrics_to_collect = self._build_metric_list_to_collect()

        if not self.db_name:
            self.log.info(
                'No MongoDB database found in URI. Defaulting to admin.')
            self.db_name = 'admin'

        # Tagging
        custom_tags = list(set(self.instance.get('tags', [])))
        self.service_check_tags = ["db:%s" % self.db_name] + custom_tags

        # ...add the `server` tag to the metrics' tags only
        # (it's added in the backend for service checks)
        self.tags = custom_tags + ['server:%s' % self.clean_server_name]

        if self.nodelist:
            host = self.nodelist[0][0]
            port = self.nodelist[0][1]
            self.service_check_tags = self.service_check_tags + [
                "host:%s" % host, "port:%s" % port
            ]

        self.timeout = float(self.instance.get('timeout',
                                               DEFAULT_TIMEOUT)) * 1000

        # Authenticate
        self.do_auth = True
        self.use_x509 = self.ssl_params and not self.password
        if not self.username:
            self.log.debug(u"A username is required to authenticate to `%s`",
                           self.server)
            self.do_auth = False

        self.replica_check = is_affirmative(
            self.instance.get('replica_check', True))
        self.collections_indexes_stats = is_affirmative(
            self.instance.get('collections_indexes_stats'))
        self.coll_names = self.instance.get('collections', [])
        self.custom_queries = self.instance.get("custom_queries", [])