示例#1
0
    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)]
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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)