def refresh_collectors(self, mongo_version, all_dbs, tags): collectors = [] if isinstance(self.deployment, ReplicaSetDeployment): if self.replica_check: collectors.append(ReplicaCollector(self, tags)) collectors.append(ReplicationOpLogCollector(self, tags)) if not isinstance(self.deployment, MongosDeployment): # The local database contains different information on each node. # But is only available for mongod instances. collectors.append(DbStatCollector(self, "local", tags)) collectors.append(FsyncLockCollector(self, self.db_name, tags)) if 'top' in self.additional_metrics: collectors.append(TopCollector(self, tags)) if self.deployment.is_principal(): if 'local' in all_dbs: # Already monitored for all instances all_dbs.remove('local') for db_name in all_dbs: collectors.append(DbStatCollector(self, db_name, tags)) if self.collections_indexes_stats: if LooseVersion(mongo_version) >= LooseVersion("3.2"): collectors.append( IndexStatsCollector(self, self.db_name, tags, self.coll_names)) else: msg = "'collections_indexes_stats' is only available starting from mongo 3.2: " "your mongo version is %s" self.log.error(msg, mongo_version) collectors.append( CollStatsCollector(self, self.db_name, tags, coll_names=self.coll_names)) # TODO: Is it the right place for custom queries? collectors.append( CustomQueriesCollector(self, self.db_name, tags, self.custom_queries)) collectors.append( ServerStatusCollector(self, self.db_name, tags, tcmalloc=self.collect_tcmalloc_metrics)) self.collectors = collectors
def refresh_collectors(self, deployment_type, mongo_version, all_dbs, tags): collect_tcmalloc_metrics = 'tcmalloc' in self._config.additional_metrics potential_collectors = [ ConnPoolStatsCollector(self, tags), ReplicationOpLogCollector(self, tags), FsyncLockCollector(self, self._config.db_name, tags), CollStatsCollector(self, self._config.db_name, tags, coll_names=self._config.coll_names), ServerStatusCollector(self, self._config.db_name, tags, tcmalloc=collect_tcmalloc_metrics), ] if self._config.replica_check: potential_collectors.append(ReplicaCollector(self, tags)) if 'jumbo_chunks' in self._config.additional_metrics: potential_collectors.append(JumboStatsCollector(self, tags)) if 'top' in self._config.additional_metrics: potential_collectors.append(TopCollector(self, tags)) if LooseVersion(mongo_version) >= LooseVersion("3.6"): potential_collectors.append(SessionStatsCollector(self, tags)) if self._config.collections_indexes_stats: if LooseVersion(mongo_version) >= LooseVersion("3.2"): potential_collectors.append( IndexStatsCollector(self, self._config.db_name, tags, self._config.coll_names) ) else: self.log.debug( "'collections_indexes_stats' is only available starting from mongo 3.2: " "your mongo version is %s", mongo_version, ) for db_name in all_dbs: potential_collectors.append(DbStatCollector(self, db_name, tags)) # Custom queries are always collected except if the node is a secondary or an arbiter in a replica set. # It is possible to collect custom queries from secondary nodes as well but this has to be explicitly # stated in the configuration of the query. is_secondary = isinstance(deployment_type, ReplicaSetDeployment) and deployment_type.is_secondary queries = self._config.custom_queries if is_secondary: # On a secondary node, only collect the custom queries that define the 'run_on_secondary' parameter. queries = [q for q in self._config.custom_queries if is_affirmative(q.get('run_on_secondary', False))] missing_queries = len(self._config.custom_queries) - len(queries) if missing_queries: self.log.debug( "{} custom queries defined in the configuration won't be run because the mongod node is a " "secondary and the queries don't specify 'run_on_secondary: true' in the configuration. " "Custom queries are only run on mongos, primaries, or standalone by default to prevent " "duplicated information." ) potential_collectors.append(CustomQueriesCollector(self, self._config.db_name, tags, queries)) self.collectors = [coll for coll in potential_collectors if coll.compatible_with(deployment_type)]
def refresh_collectors(self, mongo_version, all_dbs, tags): collectors = [] if self.deployment.use_shards: collectors.append(ConnPoolStatsCollector(self, tags)) if isinstance(self.deployment, ReplicaSetDeployment): if self.replica_check: collectors.append(ReplicaCollector(self, tags)) collectors.append(ReplicationOpLogCollector(self, tags)) if isinstance(self.deployment, MongosDeployment): if 'jumbo_chunks' in self.additional_metrics: collectors.append(JumboStatsCollector(self, tags)) if LooseVersion(mongo_version) >= LooseVersion("3.6"): collectors.append(SessionStatsCollector(self, tags)) else: # Some commands are not available on mongos. Also the 'local' database is # different on each node and its statistics should be fetched on any mongod node. collectors.append(DbStatCollector(self, "local", tags)) collectors.append(FsyncLockCollector(self, self.db_name, tags)) if 'top' in self.additional_metrics: collectors.append(TopCollector(self, tags)) if self.deployment.is_principal(): if 'local' in all_dbs: # Already monitored for all instances all_dbs.remove('local') for db_name in all_dbs: collectors.append(DbStatCollector(self, db_name, tags)) if self.collections_indexes_stats: if LooseVersion(mongo_version) >= LooseVersion("3.2"): collectors.append( IndexStatsCollector(self, self.db_name, tags, self.coll_names)) else: self.log.debug( "'collections_indexes_stats' is only available starting from mongo 3.2: " "your mongo version is %s", mongo_version, ) collectors.append( CollStatsCollector(self, self.db_name, tags, coll_names=self.coll_names)) # Custom queries are always collected except if the node is a secondary or an arbiter in a replica set. # It is possible to collect custom queries from secondary nodes as well but this has to be explicitly # stated in the configuration of the query. is_secondary = isinstance( self.deployment, ReplicaSetDeployment) and self.deployment.is_secondary queries = self.custom_queries if is_secondary: # On a secondary node, only collect the custom queries that define the 'run_on_secondary' parameter. queries = [ q for q in self.custom_queries if is_affirmative(q.get('run_on_secondary', False)) ] missing_queries = len(self.custom_queries) - len(queries) if missing_queries: self.log.debug( "{} custom queries defined in the configuration won't be run because the mongod node is a " "secondary and the queries don't specify 'run_on_secondary: true' in the configuration. " "Custom queries are only run on mongos, primaries on standalone by default to prevent " "duplicated information.") collectors.append( CustomQueriesCollector(self, self.db_name, tags, queries)) collectors.append( ServerStatusCollector(self, self.db_name, tags, tcmalloc=self.collect_tcmalloc_metrics)) self.collectors = collectors
def check(self, _): try: cli = pymongo.mongo_client.MongoClient( self.server, socketTimeoutMS=self.timeout, connectTimeoutMS=self.timeout, serverSelectionTimeoutMS=self.timeout, read_preference=pymongo.ReadPreference.PRIMARY_PREFERRED, **self.ssl_params) if self.do_auth: self.log.info("Using '%s' as the authentication database", self.auth_source) self._authenticate(cli[self.auth_source]) except Exception: self.service_check(SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags=self.service_check_tags) raise tags = deepcopy(self.base_tags) self.update_deployment(cli['admin']) if isinstance(self.deployment, ReplicaSetDeployment): tags.extend([ "replset_name:{}".format(self.deployment.replset_name), "replset_state:{}".format(self.deployment.replset_state_name), ]) try: mongo_version = cli.server_info().get('version', '0.0') self.set_metadata('version', mongo_version) except Exception: self.log.exception( "Error when collecting the version from the mongo server.") mongo_version = '0.0' collector = ServerStatusCollector( self, self.db_name, tags, tcmalloc=self.collect_tcmalloc_metrics) try: collector.collect(cli) except Exception: self.service_check(SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags=self.service_check_tags) raise else: self.service_check(SERVICE_CHECK_NAME, AgentCheck.OK, tags=self.service_check_tags) collector = CurrentOpCollector(self, self.db_name, tags) collector.collect(cli) collector = DbStatCollector(self, self.db_name, tags) collector.collect(cli) # Handle replica data, if any # See # http://www.mongodb.org/display/DOCS/Replica+Set+Commands#ReplicaSetCommands-replSetGetStatus # noqa if self.replica_check and isinstance(self.deployment, ReplicaSetDeployment): collector = ReplicaCollector(self, tags, last_state=self._previous_state) try: collector.collect(cli) self._previous_state = self.deployment.replset_state except Exception as e: if "OperationFailure" in repr(e) and ( "not running with --replSet" in str(e) or "replSetGetStatus" in str(e)): pass else: raise e dbnames = cli.list_database_names() self.gauge('mongodb.dbs', len(dbnames), tags=tags) for db_name in dbnames: collector = DbStatCollector(self, db_name, tags) collector.collect(cli) if self.collections_indexes_stats: if LooseVersion(mongo_version) >= LooseVersion("3.2"): collector = IndexStatsCollector(self, self.db_name, tags, coll_names=self.coll_names) collector.collect(cli) else: msg = "'collections_indexes_stats' is only available starting from mongo 3.2: your mongo version is %s" self.log.error(msg, mongo_version) # Report the usage metrics for dbs/collections if 'top' in self.additional_metrics: try: collector = TopCollector(self, tags) collector.collect(cli) except Exception as e: self.log.warning('Failed to record `top` metrics %s', e) if 'local' in dbnames: # it might not be if we are connecting through mongos collector = ReplicationOpLogCollector(self, tags) collector.collect(cli) else: self.log.debug( '"local" database not in dbnames. Not collecting ReplicationInfo metrics' ) # get collection level stats try: collector = CollStatsCollector(self, self.db_name, tags, coll_names=self.coll_names) collector.collect(cli) except Exception as e: self.log.warning(u"Failed to record `collection` metrics.") self.log.exception(e) collector = CustomQueriesCollector(self, self.db_name, tags, custom_queries=self.custom_queries) collector.collect(cli)