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)
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", [])