summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Morilha <daniel.morilha@mongodb.com>2022-06-30 13:16:45 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-30 14:11:31 +0000
commitfae8410364c1f02ee62e77076ef60b8ee418368f (patch)
tree9909ee46de6ef7822236a468bfff95a6e61385dd /src
parent50a8545e444e8bfc7e3892a1319515302b568739 (diff)
downloadmongo-fae8410364c1f02ee62e77076ef60b8ee418368f.tar.gz
SERVER-65987 ServerStatusMetric API refresh
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/clientcursor.cpp27
-rw-r--r--src/mongo/db/collection_index_usage_tracker.cpp13
-rw-r--r--src/mongo/db/commands.cpp6
-rw-r--r--src/mongo/db/commands.h15
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp7
-rw-r--r--src/mongo/db/commands/run_aggregate.h2
-rw-r--r--src/mongo/db/commands/server_status.cpp1
-rw-r--r--src/mongo/db/commands/server_status_command.cpp22
-rw-r--r--src/mongo/db/commands/server_status_internal.cpp132
-rw-r--r--src/mongo/db/commands/server_status_internal.h64
-rw-r--r--src/mongo/db/commands/server_status_metric.cpp120
-rw-r--r--src/mongo/db/commands/server_status_metric.h145
-rw-r--r--src/mongo/db/commands/update_metrics.cpp8
-rw-r--r--src/mongo/db/commands/update_metrics.h12
-rw-r--r--src/mongo/db/concurrency/exception_util.cpp16
-rw-r--r--src/mongo/db/curop.cpp6
-rw-r--r--src/mongo/db/curop_metrics.cpp30
-rw-r--r--src/mongo/db/cursor_manager.cpp32
-rw-r--r--src/mongo/db/exec/histogram_server_status_metric.h5
-rw-r--r--src/mongo/db/exec/multi_plan.cpp15
-rw-r--r--src/mongo/db/metric_tree_test.cpp95
-rw-r--r--src/mongo/db/query/classic_plan_cache.cpp7
-rw-r--r--src/mongo/db/query/plan_cache.h3
-rw-r--r--src/mongo/db/query/sbe_runtime_planner.cpp13
-rw-r--r--src/mongo/db/repl/bgsync.cpp19
-rw-r--r--src/mongo/db/repl/initial_syncer_common_stats.cpp13
-rw-r--r--src/mongo/db/repl/initial_syncer_common_stats.h7
-rw-r--r--src/mongo/db/repl/oplog_applier_impl.cpp11
-rw-r--r--src/mongo/db/repl/oplog_buffer.h14
-rw-r--r--src/mongo/db/repl/oplog_fetcher.cpp15
-rw-r--r--src/mongo/db/repl/repl_set_commands.cpp20
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_impl.cpp11
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp25
-rw-r--r--src/mongo/db/repl/reporter.cpp7
-rw-r--r--src/mongo/db/repl/topology_coordinator.cpp8
-rw-r--r--src/mongo/db/service_entry_point_common.cpp8
-rw-r--r--src/mongo/db/stats/api_version_metrics.cpp9
-rw-r--r--src/mongo/db/stats/api_version_metrics.h2
-rw-r--r--src/mongo/db/stats/counters.h54
-rw-r--r--src/mongo/db/ttl.cpp15
-rw-r--r--src/mongo/db/write_concern.cpp21
-rw-r--r--src/mongo/s/chunk_manager_targeter.cpp8
-rw-r--r--src/mongo/s/cluster_cursor_stats.cpp5
-rw-r--r--src/mongo/s/query/cluster_client_cursor_impl.cpp10
46 files changed, 476 insertions, 604 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 079f19712f1..f26cf836af2 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -2685,6 +2685,7 @@ if wiredtiger:
'logical_session_cache_test.cpp',
'logical_session_id_test.cpp',
'logical_time_test.cpp',
+ 'metric_tree_test.cpp',
'mirroring_sampler_test.cpp',
'multi_key_path_tracker_test.cpp',
'namespace_string_test.cpp',
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp
index 9c1be7e4fc2..f0082b28b0c 100644
--- a/src/mongo/db/clientcursor.cpp
+++ b/src/mongo/db/clientcursor.cpp
@@ -27,15 +27,12 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/clientcursor.h"
#include <string>
#include <time.h>
#include <vector>
-#include "mongo/base/counter.h"
#include "mongo/db/audit.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
@@ -62,24 +59,12 @@ namespace mongo {
using std::string;
using std::stringstream;
-static Counter64 cursorStatsOpen; // gauge
-static Counter64 cursorStatsOpenPinned; // gauge
-static Counter64 cursorStatsOpenNoTimeout; // gauge
-static Counter64 cursorStatsTimedOut;
-static Counter64 cursorStatsTotalOpened;
-static Counter64 cursorStatsMoreThanOneBatch;
-
-static ServerStatusMetricField<Counter64> dCursorStatsOpen("cursor.open.total", &cursorStatsOpen);
-static ServerStatusMetricField<Counter64> dCursorStatsOpenPinned("cursor.open.pinned",
- &cursorStatsOpenPinned);
-static ServerStatusMetricField<Counter64> dCursorStatsOpenNoTimeout("cursor.open.noTimeout",
- &cursorStatsOpenNoTimeout);
-static ServerStatusMetricField<Counter64> dCursorStatusTimedout("cursor.timedOut",
- &cursorStatsTimedOut);
-static ServerStatusMetricField<Counter64> dCursorStatsTotalOpened("cursor.totalOpened",
- &cursorStatsTotalOpened);
-static ServerStatusMetricField<Counter64> dCursorStatsMoreThanOneBatch(
- "cursor.moreThanOneBatch", &cursorStatsMoreThanOneBatch);
+static CounterMetric cursorStatsOpen{"cursor.open.total"};
+static CounterMetric cursorStatsOpenPinned{"cursor.open.pinned"};
+static CounterMetric cursorStatsOpenNoTimeout{"cursor.open.noTimeout"};
+static CounterMetric cursorStatsTimedOut{"cursor.timedOut"};
+static CounterMetric cursorStatsTotalOpened{"cursor.totalOpened"};
+static CounterMetric cursorStatsMoreThanOneBatch{"cursor.moreThanOneBatch"};
ClientCursor::ClientCursor(ClientCursorParams params,
CursorId cursorId,
diff --git a/src/mongo/db/collection_index_usage_tracker.cpp b/src/mongo/db/collection_index_usage_tracker.cpp
index a02f04cd89d..f0fc7873732 100644
--- a/src/mongo/db/collection_index_usage_tracker.cpp
+++ b/src/mongo/db/collection_index_usage_tracker.cpp
@@ -28,13 +28,10 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/collection_index_usage_tracker.h"
#include <atomic>
-#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/util/assert_util.h"
@@ -45,14 +42,8 @@
namespace mongo {
namespace {
-Counter64 collectionScansCounter;
-Counter64 collectionScansNonTailableCounter;
-
-ServerStatusMetricField<Counter64> displayCollectionScans("queryExecutor.collectionScans.total",
- &collectionScansCounter);
-ServerStatusMetricField<Counter64> displayCollectionScansNonTailable(
- "queryExecutor.collectionScans.nonTailable", &collectionScansNonTailableCounter);
-
+CounterMetric collectionScansCounter("queryExecutor.collectionScans.total");
+CounterMetric collectionScansNonTailableCounter("queryExecutor.collectionScans.nonTailable");
} // namespace
CollectionIndexUsageTracker::CollectionIndexUsageTracker(
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 6ebe905b732..988e3db8831 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/commands.h"
#include <string>
@@ -976,8 +974,8 @@ std::unique_ptr<CommandInvocation> BasicCommandWithReplyBuilderInterface::parse(
Command::Command(StringData name, std::vector<StringData> aliases)
: _name(name.toString()),
_aliases(std::move(aliases)),
- _commandsExecutedMetric("commands." + _name + ".total", &_commandsExecuted),
- _commandsFailedMetric("commands." + _name + ".failed", &_commandsFailed) {
+ _commandsExecuted("commands." + _name + ".total"),
+ _commandsFailed("commands." + _name + ".failed") {
globalCommandRegistry()->registerCommand(this, _name, _aliases);
}
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index 41d93c75a4c..15f80320e0f 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -35,7 +35,6 @@
#include <string>
#include <vector>
-#include "mongo/base/counter.h"
#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
@@ -640,11 +639,8 @@ private:
const std::vector<StringData> _aliases;
// Counters for how many times this command has been executed and failed
- mutable Counter64 _commandsExecuted;
- mutable Counter64 _commandsFailed;
- // Pointers to hold the metrics tree references
- ServerStatusMetricField<Counter64> _commandsExecutedMetric;
- ServerStatusMetricField<Counter64> _commandsFailedMetric;
+ CounterMetric _commandsExecuted;
+ CounterMetric _commandsFailed;
};
/**
@@ -1339,8 +1335,7 @@ class CommandRegistry {
public:
using CommandMap = Command::CommandMap;
- CommandRegistry() : _unknownsMetricField("commands.<UNKNOWN>", &_unknowns) {}
-
+ CommandRegistry() = default;
CommandRegistry(const CommandRegistry&) = delete;
CommandRegistry& operator=(const CommandRegistry&) = delete;
@@ -1357,9 +1352,7 @@ public:
}
private:
- Counter64 _unknowns;
- ServerStatusMetricField<Counter64> _unknownsMetricField;
-
+ CounterMetric _unknowns{"commands.<UNKNOWN>"};
CommandMap _commands;
};
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 1d9f194a151..3db1399d5eb 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -22,7 +22,6 @@ env.Library(
target='server_status_core',
source=[
'server_status.cpp',
- 'server_status_internal.cpp',
'server_status_metric.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index ddbe5b2b0f1..13dd0243a7d 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/commands/run_aggregate.h"
#include <boost/optional.hpp>
@@ -101,12 +99,9 @@ using std::string;
using std::stringstream;
using std::unique_ptr;
-Counter64 allowDiskUseFalseCounter;
+CounterMetric allowDiskUseFalseCounter("query.allowDiskUseFalse");
namespace {
-ServerStatusMetricField<Counter64> allowDiskUseMetric{"query.allowDiskUseFalse",
- &allowDiskUseFalseCounter};
-
/**
* If a pipeline is empty (assuming that a $cursor stage hasn't been created yet), it could mean
* that we were able to absorb all pipeline stages and pull them into a single PlanExecutor. So,
diff --git a/src/mongo/db/commands/run_aggregate.h b/src/mongo/db/commands/run_aggregate.h
index b61538fb93d..0bb86ac91b0 100644
--- a/src/mongo/db/commands/run_aggregate.h
+++ b/src/mongo/db/commands/run_aggregate.h
@@ -72,5 +72,5 @@ Status runAggregate(OperationContext* opCtx,
/**
* Tracks explicit use of allowDiskUse:false with find and aggregate commands.
*/
-extern Counter64 allowDiskUseFalseCounter;
+extern CounterMetric allowDiskUseFalseCounter;
} // namespace mongo
diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp
index b7e6c5d3a24..584726a56e0 100644
--- a/src/mongo/db/commands/server_status.cpp
+++ b/src/mongo/db/commands/server_status.cpp
@@ -31,7 +31,6 @@
#include "mongo/db/commands/server_status.h"
-#include "mongo/db/commands/server_status_internal.h"
#include "mongo/db/service_context.h"
#include "mongo/util/version.h"
diff --git a/src/mongo/db/commands/server_status_command.cpp b/src/mongo/db/commands/server_status_command.cpp
index dac1fe8c56f..eccd2c0174c 100644
--- a/src/mongo/db/commands/server_status_command.cpp
+++ b/src/mongo/db/commands/server_status_command.cpp
@@ -28,12 +28,9 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/server_status.h"
-#include "mongo/db/commands/server_status_internal.h"
#include "mongo/db/service_context.h"
#include "mongo/db/stats/counters.h"
#include "mongo/logv2/log.h"
@@ -140,17 +137,13 @@ public:
}
// --- counters
- bool includeMetricTree = MetricTree::theMetricTree != nullptr;
+ MetricTree* metricTree = globalMetricTree(/* create */ false);
auto metricsEl = cmdObj["metrics"_sd];
- if (metricsEl.type() && !metricsEl.trueValue())
- includeMetricTree = false;
-
- if (includeMetricTree) {
+ if (metricTree && (metricsEl.eoo() || metricsEl.trueValue())) {
if (metricsEl.type() == BSONType::Object) {
- MetricTree::theMetricTree->appendTo(BSON("metrics" << metricsEl.embeddedObject()),
- result);
+ metricTree->appendTo(BSON("metrics" << metricsEl.embeddedObject()), result);
} else {
- MetricTree::theMetricTree->appendTo(result);
+ metricTree->appendTo(result);
}
}
@@ -252,7 +245,8 @@ public:
class MemBase : public ServerStatusMetric {
public:
MemBase() : ServerStatusMetric(".mem.bits") {}
- virtual void appendAtLeaf(BSONObjBuilder& b) const {
+
+ void appendAtLeaf(BSONObjBuilder& b) const override {
b.append("bits", sizeof(int*) == 4 ? 32 : 64);
ProcessInfo p;
@@ -267,7 +261,9 @@ public:
b.appendBool("supported", false);
}
}
-} memBase;
+};
+
+MemBase& memBase = addMetricToTree(std::make_unique<MemBase>());
class HttpClientServerStatus : public ServerStatusSection {
public:
diff --git a/src/mongo/db/commands/server_status_internal.cpp b/src/mongo/db/commands/server_status_internal.cpp
deleted file mode 100644
index 9b87187aaa6..00000000000
--- a/src/mongo/db/commands/server_status_internal.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/db/commands/server_status_internal.h"
-
-#include <iostream>
-
-#include "mongo/bson/bsontypes.h"
-#include "mongo/db/commands/server_status_metric.h"
-#include "mongo/util/str.h"
-
-namespace mongo {
-
-using std::cerr;
-using std::endl;
-using std::map;
-using std::string;
-
-MetricTree* MetricTree::theMetricTree = nullptr;
-
-void MetricTree::add(ServerStatusMetric* metric) {
- string name = metric->getMetricName();
- if (name[0] == '.')
- _add(name.substr(1), metric);
- else
- _add(str::stream() << "metrics." << name, metric);
-}
-
-void MetricTree::_add(const string& path, ServerStatusMetric* metric) {
- size_t idx = path.find(".");
- if (idx == string::npos) {
- if (_subtrees.count(path) > 0) {
- cerr << "metric conflict on: " << path << endl;
- fassertFailed(6483100);
- }
- if (_metrics.count(path) > 0) {
- cerr << "duplicate metric: " << path << endl;
- fassertFailed(6483101);
- }
- _metrics[path] = metric;
- return;
- }
-
- string myLevel = path.substr(0, idx);
- if (_metrics.count(myLevel) > 0) {
- cerr << "metric conflict on: " << path << endl;
- fassertFailed(16461);
- }
-
- MetricTree*& sub = _subtrees[myLevel];
- if (!sub)
- sub = new MetricTree();
- sub->_add(path.substr(idx + 1), metric);
-}
-
-void MetricTree::appendTo(BSONObjBuilder& b) const {
- for (const auto& i : _metrics) {
- i.second->appendAtLeaf(b);
- }
-
- for (const auto& i : _subtrees) {
- BSONObjBuilder bb(b.subobjStart(i.first));
- i.second->appendTo(bb);
- bb.done();
- }
-}
-
-void MetricTree::appendTo(const BSONObj& excludePaths, BSONObjBuilder& b) const {
- auto fieldNamesInExclude = excludePaths.getFieldNames<stdx::unordered_set<std::string>>();
- for (const auto& i : _metrics) {
- auto key = i.first;
- auto el = fieldNamesInExclude.contains(key) ? excludePaths.getField(key) : BSONElement();
- if (el) {
- uassert(ErrorCodes::InvalidBSONType,
- "Exclusion value for a leaf must be a boolean.",
- el.type() == Bool);
- if (el.boolean() == false) {
- continue;
- }
- }
- i.second->appendAtLeaf(b);
- }
-
- for (const auto& i : _subtrees) {
- auto key = i.first;
- auto el = fieldNamesInExclude.contains(key) ? excludePaths.getField(key) : BSONElement();
- if (el) {
- uassert(ErrorCodes::InvalidBSONType,
- "Exclusion value must be a boolean or a nested object.",
- el.type() == Bool || el.type() == Object);
- if (el.isBoolean() && el.boolean() == false) {
- continue;
- }
- }
-
- BSONObjBuilder bb(b.subobjStart(key));
- if (el.type() == Object) {
- i.second->appendTo(el.embeddedObject(), bb);
- } else {
- i.second->appendTo(bb);
- }
- bb.done();
- }
-}
-
-} // namespace mongo
diff --git a/src/mongo/db/commands/server_status_internal.h b/src/mongo/db/commands/server_status_internal.h
deleted file mode 100644
index b59b0b36762..00000000000
--- a/src/mongo/db/commands/server_status_internal.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "mongo/db/jsobj.h"
-
-namespace mongo {
-
-class ServerStatusMetric;
-
-class MetricTree {
-public:
- void add(ServerStatusMetric* metric);
-
- /**
- * Append the metrics tree to the given BSON builder.
- */
- void appendTo(BSONObjBuilder& b) const;
-
- /**
- * Implementation of appendTo which allows tree of exclude paths. The alternative overload is
- * preferred to avoid overhead when no excludes are present.
- */
- void appendTo(const BSONObj& excludePaths, BSONObjBuilder& b) const;
-
- static MetricTree* theMetricTree;
-
-private:
- void _add(const std::string& path, ServerStatusMetric* metric);
-
- std::map<std::string, MetricTree*> _subtrees;
- std::map<std::string, ServerStatusMetric*> _metrics;
-};
-} // namespace mongo
diff --git a/src/mongo/db/commands/server_status_metric.cpp b/src/mongo/db/commands/server_status_metric.cpp
index 9cac3b3ecd4..347b514b45d 100644
--- a/src/mongo/db/commands/server_status_metric.cpp
+++ b/src/mongo/db/commands/server_status_metric.cpp
@@ -29,24 +29,122 @@
#include "mongo/db/commands/server_status_metric.h"
-#include "mongo/db/commands/server_status_internal.h"
+#include <fmt/format.h>
+
+#include "mongo/bson/bsontypes.h"
+#include "mongo/logv2/log.h"
+#include "mongo/util/str.h"
+
+#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kCommand
+
namespace mongo {
-using std::string;
+using namespace fmt::literals;
-ServerStatusMetric::ServerStatusMetric(const string& nameIn)
- : _name(nameIn), _leafName(_parseLeafName(nameIn)) {
- if (MetricTree::theMetricTree == nullptr)
- MetricTree::theMetricTree = new MetricTree();
- MetricTree::theMetricTree->add(this);
-}
+ServerStatusMetric::ServerStatusMetric(const std::string& nameIn)
+ : _name(nameIn), _leafName(_parseLeafName(nameIn)) {}
-string ServerStatusMetric::_parseLeafName(const string& name) {
+std::string ServerStatusMetric::_parseLeafName(const std::string& name) {
size_t idx = name.rfind(".");
- if (idx == string::npos)
+ if (idx == std::string::npos)
return name;
-
return name.substr(idx + 1);
}
+
+MetricTree* globalMetricTree(bool create) {
+ static struct {
+ stdx::mutex* mutex = new stdx::mutex(); // NOLINT
+ MetricTree* metricTree = nullptr;
+ } instance;
+ stdx::lock_guard lock(*instance.mutex);
+ if (create && !instance.metricTree)
+ instance.metricTree = new MetricTree();
+ return instance.metricTree;
+}
+
+void MetricTree::add(std::unique_ptr<ServerStatusMetric> metric) {
+ std::string name = metric->getMetricName();
+ if (!name.empty()) {
+ if (auto begin = name.begin(); *begin == '.')
+ name.erase(begin);
+ else
+ name = "metrics.{}"_format(name);
+ }
+
+ if (!name.empty())
+ _add(name, std::move(metric));
+}
+
+void MetricTree::_add(const std::string& path, std::unique_ptr<ServerStatusMetric> metric) {
+ size_t idx = path.find('.');
+ if (idx == std::string::npos) {
+ if (_subtrees.count(path) > 0)
+ LOGV2_FATAL(6483100, "metric conflict", "path"_attr = path);
+
+ if (!_metrics.try_emplace(path, std::move(metric)).second)
+ LOGV2_FATAL(6483102, "duplicate metric", "path"_attr = path);
+
+ return;
+ }
+
+ std::string myLevel = path.substr(0, idx);
+ if (_metrics.count(myLevel) > 0)
+ LOGV2_FATAL(16461, "metric conflict", "path"_attr = path);
+
+ auto& sub = _subtrees[myLevel];
+ if (!sub)
+ sub = std::make_unique<MetricTree>();
+ sub->_add(path.substr(idx + 1), std::move(metric));
+}
+
+void MetricTree::appendTo(BSONObjBuilder& b) const {
+ for (const auto& i : _metrics) {
+ i.second->appendAtLeaf(b);
+ }
+
+ for (const auto& i : _subtrees) {
+ BSONObjBuilder bb(b.subobjStart(i.first));
+ i.second->appendTo(bb);
+ bb.done();
+ }
+}
+
+void MetricTree::appendTo(const BSONObj& excludePaths, BSONObjBuilder& b) const {
+ auto fieldNamesInExclude = excludePaths.getFieldNames<stdx::unordered_set<std::string>>();
+ for (const auto& i : _metrics) {
+ auto key = i.first;
+ auto el = fieldNamesInExclude.contains(key) ? excludePaths.getField(key) : BSONElement();
+ if (el) {
+ uassert(ErrorCodes::InvalidBSONType,
+ "Exclusion value for a leaf must be a boolean.",
+ el.type() == Bool);
+ if (el.boolean() == false) {
+ continue;
+ }
+ }
+ i.second->appendAtLeaf(b);
+ }
+
+ for (const auto& i : _subtrees) {
+ auto key = i.first;
+ auto el = fieldNamesInExclude.contains(key) ? excludePaths.getField(key) : BSONElement();
+ if (el) {
+ uassert(ErrorCodes::InvalidBSONType,
+ "Exclusion value must be a boolean or a nested object.",
+ el.type() == Bool || el.type() == Object);
+ if (el.isBoolean() && el.boolean() == false) {
+ continue;
+ }
+ }
+
+ BSONObjBuilder bb(b.subobjStart(key));
+ if (el.type() == Object) {
+ i.second->appendTo(el.embeddedObject(), bb);
+ } else {
+ i.second->appendTo(bb);
+ }
+ }
+}
+
} // namespace mongo
diff --git a/src/mongo/db/commands/server_status_metric.h b/src/mongo/db/commands/server_status_metric.h
index ff546527a8d..dadb41ebfa2 100644
--- a/src/mongo/db/commands/server_status_metric.h
+++ b/src/mongo/db/commands/server_status_metric.h
@@ -29,6 +29,8 @@
#pragma once
+#include <map>
+#include <memory>
#include <string>
#include "mongo/db/jsobj.h"
@@ -37,14 +39,7 @@ namespace mongo {
class ServerStatusMetric {
public:
- /**
- * @param name is a dotted path of a counter name
- * if name starts with . its treated as a path from the serverStatus root
- * otherwise it will live under the "counters" namespace
- * so foo.bar would be serverStatus().counters.foo.bar
- */
- ServerStatusMetric(const std::string& name);
- virtual ~ServerStatusMetric() {}
+ virtual ~ServerStatusMetric() = default;
std::string getMetricName() const {
return _name;
@@ -55,33 +50,143 @@ public:
protected:
static std::string _parseLeafName(const std::string& name);
+ /**
+ * The parameter name is a string where periods have a special meaning.
+ * It represents the path where the metric can be found into the tree.
+ * If name starts with ".", it will be treated as a path from
+ * the serverStatus root otherwise it will live under the "counters"
+ * namespace so foo.bar would be serverStatus().counters.foo.bar
+ */
+ explicit ServerStatusMetric(const std::string& name);
+
const std::string _name;
const std::string _leafName;
};
/**
- * usage
+ * ServerStatusMetricField is the generic class for storing and reporting server
+ * status metrics.
+ * Its recommended usage is through the addMetricToTree helper function. Here is an
+ * example of a ServerStatusMetricField holding a Counter64.
+ *
+ * auto& metric =
+ * addMetricToTree(std::make_unique<ServerStatusMetricField<Counter64>>("path.to.counter"));
+ * ...
+ * metric.value().increment();
*
- * declared once
- * Counter counter;
- * ServerStatusMetricField myAwesomeCounterDisplay( "path.to.counter", &counter );
+ * Or with `makeServerStatusMetric`:
*
- * call
- * counter.hit();
+ * auto& counter = makeServerStatusMetric<Counter64>("path.to.counter");
+ * ...
+ * counter.increment();
*
- * will show up in db.serverStatus().metrics.path.to.counter
+ * To read the metric from JavaScript:
+ * db.serverStatus().metrics.path.to.counter
*/
template <typename T>
class ServerStatusMetricField : public ServerStatusMetric {
public:
- ServerStatusMetricField(const std::string& name, const T* t)
- : ServerStatusMetric(name), _t(t) {}
+ explicit ServerStatusMetricField(const std::string& name) : ServerStatusMetric(name) {}
- virtual void appendAtLeaf(BSONObjBuilder& b) const {
- b.append(_leafName, *_t);
+ void appendAtLeaf(BSONObjBuilder& b) const override {
+ b.append(_leafName, _t);
}
+ T& value() {
+ return _t;
+ }
+
+ T _t;
+};
+
+class MetricTree {
+public:
+ ~MetricTree() = default;
+
+ void add(std::unique_ptr<ServerStatusMetric> metric);
+
+ /**
+ * Append the metrics tree to the given BSON builder.
+ */
+ void appendTo(BSONObjBuilder& b) const;
+
+ /**
+ * Overload of appendTo which allows tree of exclude paths. The alternative overload is
+ * preferred to avoid overhead when no excludes are present.
+ */
+ void appendTo(const BSONObj& excludePaths, BSONObjBuilder& b) const;
+
private:
- const T* _t;
+ void _add(const std::string& path, std::unique_ptr<ServerStatusMetric> metric);
+
+ std::map<std::string, std::unique_ptr<MetricTree>> _subtrees;
+ std::map<std::string, std::unique_ptr<ServerStatusMetric>> _metrics;
};
+
+/**
+ * globalMetricTree is responsible for creating and returning a MetricTree instance
+ * statically stored inside. The create parameter bypasses its creation returning a
+ * null pointer for when it has not been created yet.
+ */
+MetricTree* globalMetricTree(bool create = true);
+
+template <typename T>
+T& addMetricToTree(std::unique_ptr<T> metric, MetricTree* metricTree = globalMetricTree()) {
+ invariant(metric);
+ invariant(metricTree);
+ T& reference = *metric;
+ metricTree->add(std::move(metric));
+ return reference;
+}
+
+template <typename TYPE>
+TYPE& makeServerStatusMetric(std::string path) {
+ return addMetricToTree(std::make_unique<ServerStatusMetricField<TYPE>>(std::move(path)))
+ .value();
+}
+
+class CounterMetric {
+public:
+ CounterMetric(std::string name)
+ : _counter{makeServerStatusMetric<Counter64>(std::move(name))} {}
+ CounterMetric(CounterMetric&) = delete;
+ CounterMetric& operator=(CounterMetric&) = delete;
+
+ operator Counter64&() {
+ return _counter;
+ }
+
+ /**
+ * replicates the same public interface found in Counter64.
+ */
+
+ /**
+ * Atomically increment.
+ */
+ void increment(uint64_t n = 1) const {
+ _counter.increment(n);
+ }
+
+ /**
+ * Atomically decrement.
+ */
+ void decrement(uint64_t n = 1) const {
+ _counter.decrement(n);
+ }
+
+ /**
+ * Return the current value.
+ */
+ long long get() const {
+ return _counter.get();
+ }
+
+ operator long long() const {
+ return get();
+ }
+
+private:
+ Counter64& _counter;
+};
+
} // namespace mongo
diff --git a/src/mongo/db/commands/update_metrics.cpp b/src/mongo/db/commands/update_metrics.cpp
index 357920aeb7e..a730e812c28 100644
--- a/src/mongo/db/commands/update_metrics.cpp
+++ b/src/mongo/db/commands/update_metrics.cpp
@@ -27,16 +27,12 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/commands/update_metrics.h"
namespace mongo {
UpdateMetrics::UpdateMetrics(StringData commandName)
- : _commandsWithAggregationPipelineMetric("commands." + commandName + ".pipeline",
- &_commandsWithAggregationPipeline),
- _commandsWithArrayFiltersMetric("commands." + commandName + ".arrayFilters",
- &_commandsWithArrayFilters) {}
+ : _commandsWithAggregationPipeline("commands." + commandName + ".pipeline"),
+ _commandsWithArrayFilters("commands." + commandName + ".arrayFilters") {}
void UpdateMetrics::incrementExecutedWithAggregationPipeline() {
_commandsWithAggregationPipeline.increment();
diff --git a/src/mongo/db/commands/update_metrics.h b/src/mongo/db/commands/update_metrics.h
index c6732762778..d485d723e81 100644
--- a/src/mongo/db/commands/update_metrics.h
+++ b/src/mongo/db/commands/update_metrics.h
@@ -29,7 +29,6 @@
#pragma once
-#include "mongo/base/counter.h"
#include "mongo/base/string_data.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/db/commands/server_status_metric.h"
@@ -73,16 +72,9 @@ public:
private:
// A counter for how many times this command has been executed with an aggregation
// pipeline-style update parameter.
- Counter64 _commandsWithAggregationPipeline;
+ CounterMetric _commandsWithAggregationPipeline;
// A counter for how many times this command has been executed with the arrayFilters option.
- Counter64 _commandsWithArrayFilters;
-
- // A server metric field for the command executions with an aggregation pipeline-style update
- // parameter counter.
- ServerStatusMetricField<Counter64> _commandsWithAggregationPipelineMetric;
-
- // A server metric field for the command executions with arrayFilters option counter.
- ServerStatusMetricField<Counter64> _commandsWithArrayFiltersMetric;
+ CounterMetric _commandsWithArrayFilters;
};
} // namespace mongo
diff --git a/src/mongo/db/concurrency/exception_util.cpp b/src/mongo/db/concurrency/exception_util.cpp
index 989cf54b320..3f9dec3441e 100644
--- a/src/mongo/db/concurrency/exception_util.cpp
+++ b/src/mongo/db/concurrency/exception_util.cpp
@@ -30,7 +30,6 @@
#include "mongo/db/concurrency/exception_util.h"
-#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/concurrency/exception_util_gen.h"
#include "mongo/db/namespace_string.h"
@@ -57,17 +56,10 @@ void logWriteConflictAndBackoff(int attempt, StringData operation, StringData ns
namespace {
-Counter64 temporarilyUnavailableErrors;
-Counter64 temporarilyUnavailableErrorsEscaped;
-Counter64 temporarilyUnavailableErrorsConvertedToWriteConflict;
-
-ServerStatusMetricField<Counter64> displayTemporarilyUnavailableErrors(
- "operation.temporarilyUnavailableErrors", &temporarilyUnavailableErrors);
-ServerStatusMetricField<Counter64> displayTemporarilyUnavailableErrorsEscaped(
- "operation.temporarilyUnavailableErrorsEscaped", &temporarilyUnavailableErrorsEscaped);
-ServerStatusMetricField<Counter64> displayTemporarilyUnavailableErrorsConverted(
- "operation.temporarilyUnavailableErrorsConvertedToWriteConflict",
- &temporarilyUnavailableErrorsConvertedToWriteConflict);
+CounterMetric temporarilyUnavailableErrors{"operation.temporarilyUnavailableErrors"};
+CounterMetric temporarilyUnavailableErrorsEscaped{"operation.temporarilyUnavailableErrorsEscaped"};
+CounterMetric temporarilyUnavailableErrorsConvertedToWriteConflict{
+ "operation.temporarilyUnavailableErrorsConvertedToWriteConflict"};
} // namespace
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 6fc209bd270..bd15b40232c 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -30,8 +30,6 @@
// CHECK_LOG_REDACTION
-#include "mongo/platform/basic.h"
-
#include "mongo/db/curop.h"
#include <iomanip>
@@ -69,9 +67,7 @@ using std::string;
namespace {
-TimerStats oplogGetMoreStats;
-ServerStatusMetricField<TimerStats> displayBatchesReceived("repl.network.oplogGetMoresProcessed",
- &oplogGetMoreStats);
+auto& oplogGetMoreStats = makeServerStatusMetric<TimerStats>("repl.network.oplogGetMoresProcessed");
} // namespace
diff --git a/src/mongo/db/curop_metrics.cpp b/src/mongo/db/curop_metrics.cpp
index 63537de8980..526f779efa2 100644
--- a/src/mongo/db/curop_metrics.cpp
+++ b/src/mongo/db/curop_metrics.cpp
@@ -27,9 +27,6 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
-#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/curop.h"
#include "mongo/db/operation_context.h"
@@ -37,28 +34,17 @@
namespace mongo {
namespace {
-Counter64 returnedCounter;
-Counter64 insertedCounter;
-Counter64 updatedCounter;
-Counter64 deletedCounter;
-Counter64 scannedCounter;
-Counter64 scannedObjectCounter;
-ServerStatusMetricField<Counter64> displayReturned("document.returned", &returnedCounter);
-ServerStatusMetricField<Counter64> displayUpdated("document.updated", &updatedCounter);
-ServerStatusMetricField<Counter64> displayInserted("document.inserted", &insertedCounter);
-ServerStatusMetricField<Counter64> displayDeleted("document.deleted", &deletedCounter);
-ServerStatusMetricField<Counter64> displayScanned("queryExecutor.scanned", &scannedCounter);
-ServerStatusMetricField<Counter64> displayScannedObjects("queryExecutor.scannedObjects",
- &scannedObjectCounter);
+CounterMetric deletedCounter("document.deleted");
+CounterMetric insertedCounter("document.inserted");
+CounterMetric returnedCounter("document.returned");
+CounterMetric updatedCounter("document.updated");
-Counter64 scanAndOrderCounter;
-Counter64 writeConflictsCounter;
+CounterMetric scannedCounter("queryExecutor.scanned");
+CounterMetric scannedObjectCounter("queryExecutor.scannedObjects");
-ServerStatusMetricField<Counter64> displayScanAndOrder("operation.scanAndOrder",
- &scanAndOrderCounter);
-ServerStatusMetricField<Counter64> displayWriteConflicts("operation.writeConflicts",
- &writeConflictsCounter);
+CounterMetric scanAndOrderCounter("operation.scanAndOrder");
+CounterMetric writeConflictsCounter("operation.writeConflicts");
} // namespace
diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp
index 8d09c6811fb..ce81235bdd0 100644
--- a/src/mongo/db/cursor_manager.cpp
+++ b/src/mongo/db/cursor_manager.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/cursor_manager.h"
#include <memory>
@@ -63,28 +61,14 @@
namespace mongo {
-static Counter64 cursorStatsLifespanLessThan1Second;
-static Counter64 cursorStatsLifespanLessThan5Seconds;
-static Counter64 cursorStatsLifespanLessThan15Seconds;
-static Counter64 cursorStatsLifespanLessThan30Seconds;
-static Counter64 cursorStatsLifespanLessThan1Minute;
-static Counter64 cursorStatsLifespanLessThan10Minutes;
-static Counter64 cursorStatsLifespanGreaterThanOrEqual10Minutes;
-
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan1Second(
- "cursor.lifespan.lessThan1Second", &cursorStatsLifespanLessThan1Second);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan5Seconds(
- "cursor.lifespan.lessThan5Seconds", &cursorStatsLifespanLessThan5Seconds);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan15Seconds(
- "cursor.lifespan.lessThan15Seconds", &cursorStatsLifespanLessThan15Seconds);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan30Seconds(
- "cursor.lifespan.lessThan30Seconds", &cursorStatsLifespanLessThan30Seconds);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan1Minute(
- "cursor.lifespan.lessThan1Minute", &cursorStatsLifespanLessThan1Minute);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanLessThan10Minutes(
- "cursor.lifespan.lessThan10Minutes", &cursorStatsLifespanLessThan10Minutes);
-static ServerStatusMetricField<Counter64> dCursorStatsLifespanGreaterThanOrEqual10Minutes(
- "cursor.lifespan.greaterThanOrEqual10Minutes", &cursorStatsLifespanGreaterThanOrEqual10Minutes);
+static CounterMetric cursorStatsLifespanLessThan1Second{"cursor.lifespan.lessThan1Second"};
+static CounterMetric cursorStatsLifespanLessThan5Seconds{"cursor.lifespan.lessThan5Seconds"};
+static CounterMetric cursorStatsLifespanLessThan15Seconds{"cursor.lifespan.lessThan15Seconds"};
+static CounterMetric cursorStatsLifespanLessThan30Seconds{"cursor.lifespan.lessThan30Seconds"};
+static CounterMetric cursorStatsLifespanLessThan1Minute{"cursor.lifespan.lessThan1Minute"};
+static CounterMetric cursorStatsLifespanLessThan10Minutes{"cursor.lifespan.lessThan10Minutes"};
+static CounterMetric cursorStatsLifespanGreaterThanOrEqual10Minutes{
+ "cursor.lifespan.greaterThanOrEqual10Minutes"};
constexpr int CursorManager::kNumPartitions;
diff --git a/src/mongo/db/exec/histogram_server_status_metric.h b/src/mongo/db/exec/histogram_server_status_metric.h
index 83a53f2999e..6d3656a8a68 100644
--- a/src/mongo/db/exec/histogram_server_status_metric.h
+++ b/src/mongo/db/exec/histogram_server_status_metric.h
@@ -53,7 +53,8 @@ namespace mongo {
class HistogramServerStatusMetric {
public:
HistogramServerStatusMetric(std::string name, std::vector<uint64_t> bounds)
- : _hist{std::move(bounds)}, _metric{std::move(name), this} {}
+ : _hist{std::move(bounds)},
+ _metric(addMetricToTree(std::make_unique<Metric>(std::move(name), this))) {}
void increment(uint64_t value) {
_hist.increment(value);
@@ -95,7 +96,7 @@ private:
}
Histogram<uint64_t> _hist;
- Metric _metric;
+ Metric& _metric;
};
} // namespace mongo
diff --git a/src/mongo/db/exec/multi_plan.cpp b/src/mongo/db/exec/multi_plan.cpp
index 0dbb0c4a405..52465c59c8a 100644
--- a/src/mongo/db/exec/multi_plan.cpp
+++ b/src/mongo/db/exec/multi_plan.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/exec/multi_plan.h"
#include <algorithm>
@@ -72,27 +70,20 @@ void markShouldCollectTimingInfoOnSubtree(PlanStage* root) {
}
}
-Counter64 classicMicrosTotal;
-Counter64 classicWorksTotal;
-Counter64 classicCount;
-
/**
* Aggregation of the total number of microseconds spent (in the classic multiplanner).
*/
-ServerStatusMetricField<Counter64> classicMicrosTotalDisplay("query.multiPlanner.classicMicros",
- &classicMicrosTotal);
+CounterMetric classicMicrosTotal("query.multiPlanner.classicMicros");
/**
* Aggregation of the total number of "works" performed (in the classic multiplanner).
*/
-ServerStatusMetricField<Counter64> classicWorksTotalDisplay("query.multiPlanner.classicWorks",
- &classicWorksTotal);
+CounterMetric classicWorksTotal("query.multiPlanner.classicWorks");
/**
* Aggregation of the total number of invocations (of the classic multiplanner).
*/
-ServerStatusMetricField<Counter64> classicCountDisplay("query.multiPlanner.classicCount",
- &classicCount);
+CounterMetric classicCount("query.multiPlanner.classicCount");
/**
* An element in this histogram is the number of microseconds spent in an invocation (of the
diff --git a/src/mongo/db/metric_tree_test.cpp b/src/mongo/db/metric_tree_test.cpp
new file mode 100644
index 00000000000..6de4042226b
--- /dev/null
+++ b/src/mongo/db/metric_tree_test.cpp
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2022-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/db/commands/server_status_metric.h"
+
+#include "mongo/bson/bsonelement.h"
+#include "mongo/bson/bsonobj.h"
+#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/unittest/unittest.h"
+
+namespace mongo {
+namespace {
+
+class MetricTreeTest : public unittest::Test {
+protected:
+ MetricTree* tree() const {
+ return _tree.get();
+ }
+
+ BSONObj metrics() {
+ BSONObjBuilder builder;
+ tree()->appendTo(builder);
+ return builder.obj();
+ }
+
+ std::unique_ptr<MetricTree> _tree = std::make_unique<MetricTree>();
+};
+
+TEST_F(MetricTreeTest, ValidateCounterMetric) {
+ auto& counter =
+ addMetricToTree(std::make_unique<ServerStatusMetricField<Counter64>>("tree.counter"),
+ tree())
+ .value();
+
+ counter.increment();
+ const auto firstMetrics = metrics();
+ BSONElement counterElement = firstMetrics["metrics"]["tree"]["counter"];
+ ASSERT(counterElement.isNumber());
+ ASSERT_EQ(counterElement.numberInt(), counter.get());
+
+ counter.increment(2);
+
+ const auto secondMetrics = metrics();
+ BSONElement anotherCounterElement = secondMetrics["metrics"]["tree"]["counter"];
+ ASSERT(anotherCounterElement.isNumber());
+ ASSERT_EQ(anotherCounterElement.numberInt(), counter.get());
+}
+
+TEST_F(MetricTreeTest, ValidateTextMetric) {
+ auto& text =
+ addMetricToTree(std::make_unique<ServerStatusMetricField<std::string>>("tree.text"), tree())
+ .value();
+
+ text = "hello";
+
+ auto firstMetrics = metrics();
+ BSONElement textElement = firstMetrics["metrics"]["tree"]["text"];
+ ASSERT_EQ(textElement.type(), BSONType::String);
+ ASSERT_EQ(textElement.String(), text);
+
+ text = "bye";
+
+ auto secondMetrics = metrics();
+ BSONElement anotherTextElement = secondMetrics["metrics"]["tree"]["text"];
+ ASSERT_EQ(anotherTextElement.type(), BSONType::String);
+ ASSERT_EQ(anotherTextElement.String(), text);
+}
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/db/query/classic_plan_cache.cpp b/src/mongo/db/query/classic_plan_cache.cpp
index 683b4b3660a..748d75cf238 100644
--- a/src/mongo/db/query/classic_plan_cache.cpp
+++ b/src/mongo/db/query/classic_plan_cache.cpp
@@ -32,12 +32,7 @@
#include "mongo/db/commands/server_status_metric.h"
namespace mongo {
-namespace {
-ServerStatusMetricField<Counter64> totalPlanCacheSizeEstimateBytesMetric(
- "query.planCacheTotalSizeEstimateBytes", &mongo::planCacheTotalSizeEstimateBytes);
-} // namespace
-
-Counter64 planCacheTotalSizeEstimateBytes;
+CounterMetric planCacheTotalSizeEstimateBytes("query.planCacheTotalSizeEstimateBytes");
std::ostream& operator<<(std::ostream& stream, const PlanCacheKey& key) {
stream << key.toString();
diff --git a/src/mongo/db/query/plan_cache.h b/src/mongo/db/query/plan_cache.h
index dc52b10c4f4..1201c0f197c 100644
--- a/src/mongo/db/query/plan_cache.h
+++ b/src/mongo/db/query/plan_cache.h
@@ -30,6 +30,7 @@
#pragma once
#include "mongo/db/catalog/util/partitioned.h"
+#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/query/lru_key_value.h"
#include "mongo/db/query/plan_cache_callbacks.h"
#include "mongo/db/query/plan_cache_debug_info.h"
@@ -46,7 +47,7 @@ class PlanCacheEntryBase;
/**
* Tracks the approximate cumulative size of the plan cache entries across all the collections.
*/
-extern Counter64 planCacheTotalSizeEstimateBytes;
+extern CounterMetric planCacheTotalSizeEstimateBytes;
/**
* Information returned from a get(...) query.
diff --git a/src/mongo/db/query/sbe_runtime_planner.cpp b/src/mongo/db/query/sbe_runtime_planner.cpp
index 5edf89539bf..de601c0d823 100644
--- a/src/mongo/db/query/sbe_runtime_planner.cpp
+++ b/src/mongo/db/query/sbe_runtime_planner.cpp
@@ -26,7 +26,6 @@
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
-#include "mongo/platform/basic.h"
#include "mongo/db/query/sbe_runtime_planner.h"
@@ -40,26 +39,20 @@
namespace mongo::sbe {
namespace {
-Counter64 sbeMicrosTotal;
-Counter64 sbeNumReadsTotal;
-Counter64 sbeCount;
-
/**
* Aggregation of the total number of microseconds spent (in SBE multiplanner).
*/
-ServerStatusMetricField<Counter64> sbeMicrosTotalDisplay("query.multiPlanner.sbeMicros",
- &sbeMicrosTotal);
+CounterMetric sbeMicrosTotal("query.multiPlanner.sbeMicros");
/**
* Aggregation of the total number of reads done (in SBE multiplanner).
*/
-ServerStatusMetricField<Counter64> sbeNumReadsTotalDisplay("query.multiPlanner.sbeNumReads",
- &sbeNumReadsTotal);
+CounterMetric sbeNumReadsTotal("query.multiPlanner.sbeNumReads");
/**
* Aggregation of the total number of invocations (of the SBE multiplanner).
*/
-ServerStatusMetricField<Counter64> sbeCountDisplay("query.multiPlanner.sbeCount", &sbeCount);
+CounterMetric sbeCount("query.multiPlanner.sbeCount");
/**
* An element in this histogram is the number of microseconds spent in an invocation (of the SBE
diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp
index 893ae8014e0..69d9868e1b0 100644
--- a/src/mongo/db/repl/bgsync.cpp
+++ b/src/mongo/db/repl/bgsync.cpp
@@ -28,13 +28,10 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/repl/bgsync.h"
#include <memory>
-#include "mongo/base/counter.h"
#include "mongo/base/string_data.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/client/connection_pool.h"
@@ -81,27 +78,19 @@ const Milliseconds kRollbackOplogSocketTimeout(10 * 60 * 1000);
// The number of times a node attempted to choose a node to sync from among the available sync
// source options. This occurs if we re-evaluate our sync source, receive an error from the source,
// or step down.
-Counter64 numSyncSourceSelections;
-ServerStatusMetricField<Counter64> displayNumSyncSourceSelections("repl.syncSource.numSelections",
- &numSyncSourceSelections);
+CounterMetric numSyncSourceSelections("repl.syncSource.numSelections");
// The number of times a node kept it's original sync source after re-evaluating if its current sync
// source was optimal.
-Counter64 numTimesChoseSameSyncSource;
-ServerStatusMetricField<Counter64> displayNumTimesChoseSameSyncSource(
- "repl.syncSource.numTimesChoseSame", &numTimesChoseSameSyncSource);
+CounterMetric numTimesChoseSameSyncSource("repl.syncSource.numTimesChoseSame");
// The number of times a node chose a new sync source after re-evaluating if its current sync source
// was optimal.
-Counter64 numTimesChoseDifferentSyncSource;
-ServerStatusMetricField<Counter64> displayNumTimesChoseDifferentSyncSource(
- "repl.syncSource.numTimesChoseDifferent", &numTimesChoseDifferentSyncSource);
+CounterMetric numTimesChoseDifferentSyncSource("repl.syncSource.numTimesChoseDifferent");
// The number of times a node could not find a sync source when choosing a node to sync from among
// the available options.
-Counter64 numTimesCouldNotFindSyncSource;
-ServerStatusMetricField<Counter64> displayNumTimesCouldNotFindSyncSource(
- "repl.syncSource.numTimesCouldNotFind", &numTimesCouldNotFindSyncSource);
+CounterMetric numTimesCouldNotFindSyncSource("repl.syncSource.numTimesCouldNotFind");
/**
* Extends DataReplicatorExternalStateImpl to be member state aware.
diff --git a/src/mongo/db/repl/initial_syncer_common_stats.cpp b/src/mongo/db/repl/initial_syncer_common_stats.cpp
index 34a4b7cad6f..cd5c943f56f 100644
--- a/src/mongo/db/repl/initial_syncer_common_stats.cpp
+++ b/src/mongo/db/repl/initial_syncer_common_stats.cpp
@@ -38,16 +38,9 @@ namespace mongo {
namespace repl {
namespace initial_sync_common_stats {
-Counter64 initialSyncFailedAttempts;
-Counter64 initialSyncFailures;
-Counter64 initialSyncCompletes;
-
-ServerStatusMetricField<Counter64> displaySSInitialSyncFailedAttempts(
- "repl.initialSync.failedAttempts", &initialSyncFailedAttempts);
-ServerStatusMetricField<Counter64> displaySSInitialSyncFailures("repl.initialSync.failures",
- &initialSyncFailures);
-ServerStatusMetricField<Counter64> displaySSInitialSyncCompleted("repl.initialSync.completed",
- &initialSyncCompletes);
+CounterMetric initialSyncFailedAttempts("repl.initialSync.failedAttempts");
+CounterMetric initialSyncFailures("repl.initialSync.failures");
+CounterMetric initialSyncCompletes("repl.initialSync.completed");
void LogInitialSyncAttemptStats(const StatusWith<OpTimeAndWallTime>& attemptResult,
bool hasRetries,
diff --git a/src/mongo/db/repl/initial_syncer_common_stats.h b/src/mongo/db/repl/initial_syncer_common_stats.h
index beb8a829bc5..4a0fd858f50 100644
--- a/src/mongo/db/repl/initial_syncer_common_stats.h
+++ b/src/mongo/db/repl/initial_syncer_common_stats.h
@@ -29,6 +29,7 @@
#pragma once
+#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/repl/optime.h"
namespace mongo {
@@ -38,17 +39,17 @@ namespace initial_sync_common_stats {
// The number of initial sync attempts that have failed since server startup. Each instance of
// InitialSyncer may run multiple attempts to fulfill an initial sync request that is triggered
// when InitialSyncer::startup() is called.
-extern Counter64 initialSyncFailedAttempts;
+extern CounterMetric initialSyncFailedAttempts;
// The number of initial sync requests that have been requested and failed. Each instance of
// InitialSyncer (upon successful startup()) corresponds to a single initial sync request.
// This value does not include the number of times where a InitialSyncer is created successfully
// but failed in startup().
-extern Counter64 initialSyncFailures;
+extern CounterMetric initialSyncFailures;
// The number of initial sync requests that have been requested and completed successfully. Each
// instance of InitialSyncer corresponds to a single initial sync request.
-extern Counter64 initialSyncCompletes;
+extern CounterMetric initialSyncCompletes;
void LogInitialSyncAttemptStats(const StatusWith<OpTimeAndWallTime>& attemptResult,
bool hasRetries,
diff --git a/src/mongo/db/repl/oplog_applier_impl.cpp b/src/mongo/db/repl/oplog_applier_impl.cpp
index 575035711e0..d897241134b 100644
--- a/src/mongo/db/repl/oplog_applier_impl.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl.cpp
@@ -63,16 +63,13 @@ MONGO_FAIL_POINT_DEFINE(pauseBatchApplicationAfterWritingOplogEntries);
MONGO_FAIL_POINT_DEFINE(hangAfterRecordingOpApplicationStartTime);
// The oplog entries applied
-Counter64 opsAppliedStats;
-ServerStatusMetricField<Counter64> displayOpsApplied("repl.apply.ops", &opsAppliedStats);
+CounterMetric opsAppliedStats("repl.apply.ops");
// Tracks the oplog application batch size.
-Counter64 oplogApplicationBatchSize;
-ServerStatusMetricField<Counter64> displayOplogApplicationBatchSize("repl.apply.batchSize",
- &oplogApplicationBatchSize);
+CounterMetric oplogApplicationBatchSize("repl.apply.batchSize");
+
// Number and time of each ApplyOps worker pool round
-TimerStats applyBatchStats;
-ServerStatusMetricField<TimerStats> displayOpBatchesApplied("repl.apply.batches", &applyBatchStats);
+auto& applyBatchStats = makeServerStatusMetric<TimerStats>("repl.apply.batches");
/**
* Used for logging a report of ops that take longer than "slowMS" to apply. This is called
diff --git a/src/mongo/db/repl/oplog_buffer.h b/src/mongo/db/repl/oplog_buffer.h
index 2e039cb1f91..f3b0fabb228 100644
--- a/src/mongo/db/repl/oplog_buffer.h
+++ b/src/mongo/db/repl/oplog_buffer.h
@@ -31,10 +31,11 @@
#include <boost/optional.hpp>
#include <cstddef>
+#include <string>
#include <vector>
-#include "mongo/base/counter.h"
#include "mongo/bson/bsonobj.h"
+#include "mongo/db/commands/server_status_metric.h"
#include "mongo/util/interruptible.h"
#include "mongo/util/time_support.h"
@@ -191,6 +192,11 @@ public:
class OplogBuffer::Counters {
public:
+ explicit Counters(const std::string& prefix)
+ : count(prefix + ".count"),
+ size(prefix + ".sizeBytes"),
+ maxSize(prefix + ".maxSizeBytes") {}
+
/**
* Sets maximum size of operations for this OplogBuffer.
* This function should only be called by a single thread.
@@ -219,13 +225,13 @@ public:
}
// Number of operations in this OplogBuffer.
- Counter64 count;
+ CounterMetric count;
// Total size of operations in this OplogBuffer. Measured in bytes.
- Counter64 size;
+ CounterMetric size;
// Maximum size of operations in this OplogBuffer. Measured in bytes.
- Counter64 maxSize;
+ CounterMetric maxSize;
};
/**
diff --git a/src/mongo/db/repl/oplog_fetcher.cpp b/src/mongo/db/repl/oplog_fetcher.cpp
index 6ec6c9778de..a08a241a2b9 100644
--- a/src/mongo/db/repl/oplog_fetcher.cpp
+++ b/src/mongo/db/repl/oplog_fetcher.cpp
@@ -30,7 +30,6 @@
#include "mongo/db/repl/oplog_fetcher.h"
-#include "mongo/base/counter.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/jsobj.h"
@@ -91,19 +90,13 @@ BSONObj OplogBatchStats::getReport() const {
}
// The number and time spent reading batches off the network
-OplogBatchStats oplogBatchStats;
-ServerStatusMetricField<OplogBatchStats> displayBatchesRecieved("repl.network.getmores",
- &oplogBatchStats);
+auto& oplogBatchStats = makeServerStatusMetric<OplogBatchStats>("repl.network.getmores");
// The oplog entries read via the oplog reader
-Counter64 opsReadStats;
-ServerStatusMetricField<Counter64> displayOpsRead("repl.network.ops", &opsReadStats);
+CounterMetric opsReadStats("repl.network.ops");
// The bytes read via the oplog reader
-Counter64 networkByteStats;
-ServerStatusMetricField<Counter64> displayBytesRead("repl.network.bytes", &networkByteStats);
+CounterMetric networkByteStats("repl.network.bytes");
-Counter64 readersCreatedStats;
-ServerStatusMetricField<Counter64> displayReadersCreated("repl.network.readersCreated",
- &readersCreatedStats);
+CounterMetric readersCreatedStats("repl.network.readersCreated");
const Milliseconds maximumAwaitDataTimeoutMS(30 * 1000);
diff --git a/src/mongo/db/repl/repl_set_commands.cpp b/src/mongo/db/repl/repl_set_commands.cpp
index af67f31e3c6..2411b496c7c 100644
--- a/src/mongo/db/repl/repl_set_commands.cpp
+++ b/src/mongo/db/repl/repl_set_commands.cpp
@@ -32,8 +32,6 @@
LOGV2_DEBUG_OPTIONS( \
ID, DLEVEL, {logv2::LogComponent::kReplicationHeartbeats}, MESSAGE, ##__VA_ARGS__)
-#include "mongo/platform/basic.h"
-
#include <boost/algorithm/string.hpp>
#include "mongo/db/repl/repl_set_command.h"
@@ -85,7 +83,9 @@ public:
virtual void appendAtLeaf(BSONObjBuilder& b) const {
ReplicationCoordinator::get(getGlobalServiceContext())->appendDiagnosticBSON(&b);
}
-} replExecutorSSM;
+};
+
+auto& replExecutorSSM = addMetricToTree(std::make_unique<ReplExecutorSSM>());
// Testing only, enabled via command-line.
class CmdReplSetTest : public ReplSetCommand {
@@ -533,12 +533,8 @@ public:
return false;
}
- CmdReplSetStepDown()
- : ReplSetCommand("replSetStepDown"),
- _stepDownCmdsWithForceExecutedMetric("commands.replSetStepDownWithForce.total",
- &_stepDownCmdsWithForceExecuted),
- _stepDownCmdsWithForceFailedMetric("commands.replSetStepDownWithForce.failed",
- &_stepDownCmdsWithForceFailed) {}
+ CmdReplSetStepDown() : ReplSetCommand("replSetStepDown") {}
+
virtual bool run(OperationContext* opCtx,
const string&,
const BSONObj& cmdObj,
@@ -604,10 +600,8 @@ public:
}
private:
- mutable Counter64 _stepDownCmdsWithForceExecuted;
- mutable Counter64 _stepDownCmdsWithForceFailed;
- ServerStatusMetricField<Counter64> _stepDownCmdsWithForceExecutedMetric;
- ServerStatusMetricField<Counter64> _stepDownCmdsWithForceFailedMetric;
+ CounterMetric _stepDownCmdsWithForceExecuted{"commands.replSetStepDownWithForce.total"};
+ CounterMetric _stepDownCmdsWithForceFailed{"commands.replSetStepDownWithForce.failed"};
ActionSet getAuthActionSet() const override {
return ActionSet{ActionType::replSetStateChange};
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
index 47e9bd7a29e..45480cd9020 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
@@ -28,8 +28,6 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/repl/replication_coordinator_external_state_impl.h"
#include <functional>
@@ -146,14 +144,7 @@ const NamespaceString configCollectionNS{"local", "system.replset"};
MONGO_FAIL_POINT_DEFINE(dropPendingCollectionReaperHang);
// The count of items in the buffer
-OplogBuffer::Counters bufferGauge;
-ServerStatusMetricField<Counter64> displayBufferCount("repl.buffer.count", &bufferGauge.count);
-// The size (bytes) of items in the buffer
-ServerStatusMetricField<Counter64> displayBufferSize("repl.buffer.sizeBytes", &bufferGauge.size);
-// The max size (bytes) of the buffer. If the buffer does not have a size constraint, this is
-// set to 0.
-ServerStatusMetricField<Counter64> displayBufferMaxSize("repl.buffer.maxSizeBytes",
- &bufferGauge.maxSize);
+OplogBuffer::Counters bufferGauge("repl.buffer");
/**
* Returns new thread pool for thread pool task executor.
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index fe769df7572..9e44ce2d034 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -32,8 +32,6 @@
LOGV2_DEBUG_OPTIONS( \
ID, DLEVEL, {logv2::LogComponent::kReplicationElection}, MESSAGE, ##__VA_ARGS__)
-#include "mongo/platform/basic.h"
-
#include "mongo/db/repl/replication_coordinator_impl.h"
#include <algorithm>
@@ -159,31 +157,22 @@ MONGO_FAIL_POINT_DEFINE(setCustomErrorInHelloResponseMongoD);
MONGO_FAIL_POINT_DEFINE(throwBeforeRecoveringTenantMigrationAccessBlockers);
// Number of times we tried to go live as a secondary.
-Counter64 attemptsToBecomeSecondary;
-ServerStatusMetricField<Counter64> displayAttemptsToBecomeSecondary(
- "repl.apply.attemptsToBecomeSecondary", &attemptsToBecomeSecondary);
+CounterMetric attemptsToBecomeSecondary("repl.apply.attemptsToBecomeSecondary");
// Tracks the last state transition performed in this replca set.
-std::string lastStateTransition;
-ServerStatusMetricField<std::string> displayLastStateTransition(
- "repl.stateTransition.lastStateTransition", &lastStateTransition);
+std::string& lastStateTransition =
+ makeServerStatusMetric<std::string>("repl.stateTransition.lastStateTransition");
// Tracks the number of operations killed on state transition.
-Counter64 userOpsKilled;
-ServerStatusMetricField<Counter64> displayUserOpsKilled("repl.stateTransition.userOperationsKilled",
- &userOpsKilled);
+CounterMetric userOpsKilled("repl.stateTransition.userOperationsKilled");
// Tracks the number of operations left running on state transition.
-Counter64 userOpsRunning;
-ServerStatusMetricField<Counter64> displayUserOpsRunning(
- "repl.stateTransition.userOperationsRunning", &userOpsRunning);
+CounterMetric userOpsRunning("repl.stateTransition.userOperationsRunning");
// Tracks the number of times we have successfully performed automatic reconfigs to remove
// 'newlyAdded' fields.
-Counter64 numAutoReconfigsForRemovalOfNewlyAddedFields;
-ServerStatusMetricField<Counter64> displayNumAutoReconfigs(
- "repl.reconfig.numAutoReconfigsForRemovalOfNewlyAddedFields",
- &numAutoReconfigsForRemovalOfNewlyAddedFields);
+CounterMetric numAutoReconfigsForRemovalOfNewlyAddedFields(
+ "repl.reconfig.numAutoReconfigsForRemovalOfNewlyAddedFields");
using namespace fmt::literals;
diff --git a/src/mongo/db/repl/reporter.cpp b/src/mongo/db/repl/reporter.cpp
index 138d16c54f9..c135c179877 100644
--- a/src/mongo/db/repl/reporter.cpp
+++ b/src/mongo/db/repl/reporter.cpp
@@ -28,11 +28,8 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/repl/reporter.h"
-#include "mongo/base/counter.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/repl/update_position_args.h"
@@ -50,9 +47,7 @@ namespace repl {
namespace {
// The number of replSetUpdatePosition commands a node sent to its sync source.
-Counter64 numUpdatePosition;
-ServerStatusMetricField<Counter64> displayNumUpdatePosition(
- "repl.network.replSetUpdatePosition.num", &numUpdatePosition);
+CounterMetric numUpdatePosition("repl.network.replSetUpdatePosition.num");
} // namespace
diff --git a/src/mongo/db/repl/topology_coordinator.cpp b/src/mongo/db/repl/topology_coordinator.cpp
index c72bb2ddfb3..e8044d24af6 100644
--- a/src/mongo/db/repl/topology_coordinator.cpp
+++ b/src/mongo/db/repl/topology_coordinator.cpp
@@ -35,8 +35,6 @@
LOGV2_DEBUG_OPTIONS( \
ID, DLEVEL, {logv2::LogComponent::kReplicationHeartbeats}, MESSAGE, ##__VA_ARGS__)
-#include "mongo/platform/basic.h"
-
#include "mongo/db/repl/topology_coordinator.h"
#include "mongo/db/repl/topology_coordinator_gen.h"
@@ -84,10 +82,8 @@ constexpr Milliseconds TopologyCoordinator::PingStats::UninitializedPingTime;
// Tracks the number of times we decide to change sync sources in order to sync from a significantly
// closer node.
-Counter64 numSyncSourceChangesDueToSignificantlyCloserNode;
-ServerStatusMetricField<Counter64> displayNumSyncSourceChangesDueToSignificantlyCloserNode(
- "repl.syncSource.numSyncSourceChangesDueToSignificantlyCloserNode",
- &numSyncSourceChangesDueToSignificantlyCloserNode);
+CounterMetric numSyncSourceChangesDueToSignificantlyCloserNode(
+ "repl.syncSource.numSyncSourceChangesDueToSignificantlyCloserNode");
using namespace fmt::literals;
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index bc167fba693..10b0097a0b9 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -131,15 +131,11 @@ MONGO_FAIL_POINT_DEFINE(hangAfterCheckingWritabilityForMultiDocumentTransactions
// Tracks the number of times a legacy unacknowledged write failed due to
// not primary error resulted in network disconnection.
-Counter64 notPrimaryLegacyUnackWrites;
-ServerStatusMetricField<Counter64> displayNotPrimaryLegacyUnackWrites(
- "repl.network.notPrimaryLegacyUnacknowledgedWrites", &notPrimaryLegacyUnackWrites);
+CounterMetric notPrimaryLegacyUnackWrites("repl.network.notPrimaryLegacyUnacknowledgedWrites");
// Tracks the number of times an unacknowledged write failed due to not primary error
// resulted in network disconnection.
-Counter64 notPrimaryUnackWrites;
-ServerStatusMetricField<Counter64> displayNotPrimaryUnackWrites(
- "repl.network.notPrimaryUnacknowledgedWrites", &notPrimaryUnackWrites);
+CounterMetric notPrimaryUnackWrites("repl.network.notPrimaryUnacknowledgedWrites");
namespace {
diff --git a/src/mongo/db/stats/api_version_metrics.cpp b/src/mongo/db/stats/api_version_metrics.cpp
index 959e5b9e3f6..bbcd3f24f37 100644
--- a/src/mongo/db/stats/api_version_metrics.cpp
+++ b/src/mongo/db/stats/api_version_metrics.cpp
@@ -27,10 +27,8 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/commands/server_status.h"
#include "mongo/db/stats/api_version_metrics.h"
+#include "mongo/db/commands/server_status.h"
#include "mongo/util/duration.h"
namespace mongo {
@@ -122,6 +120,9 @@ public:
.appendAPIVersionMetricsInfo(&apiVersionBob);
apiVersionBob.done();
}
-} apiVersionMetricsSSM;
+};
+
+auto& apiVersionMetricsSSM =
+ addMetricToTree(std::make_unique<APIVersionMetrics::APIVersionMetricsSSM>());
} // namespace mongo
diff --git a/src/mongo/db/stats/api_version_metrics.h b/src/mongo/db/stats/api_version_metrics.h
index 6a57e0953fa..edc3d95f9e7 100644
--- a/src/mongo/db/stats/api_version_metrics.h
+++ b/src/mongo/db/stats/api_version_metrics.h
@@ -58,9 +58,9 @@ public:
APIVersionMetricsMap getAPIVersionMetrics_forTest();
-private:
class APIVersionMetricsSSM;
+private:
void _removeStaleTimestamps(WithLock lk, Date_t now);
mutable Mutex _mutex = MONGO_MAKE_LATCH("APIVersionMetrics::_mutex");
diff --git a/src/mongo/db/stats/counters.h b/src/mongo/db/stats/counters.h
index cbf429127f6..815a6856772 100644
--- a/src/mongo/db/stats/counters.h
+++ b/src/mongo/db/stats/counters.h
@@ -302,10 +302,8 @@ class AggStageCounters {
public:
// Container for a stage count metric along with its corresponding counter.
struct StageCounter {
- StageCounter(StringData name) : metric("aggStageCounters." + name, &counter) {}
-
- Counter64 counter;
- ServerStatusMetricField<Counter64> metric;
+ StageCounter(StringData name) : counter("aggStageCounters." + name) {}
+ CounterMetric counter;
};
// Map of aggregation stages to the number of occurrences.
@@ -316,10 +314,6 @@ extern AggStageCounters aggStageCounters;
class DotsAndDollarsFieldsCounters {
public:
- DotsAndDollarsFieldsCounters()
- : insertMetric("dotsAndDollarsFields.inserts", &inserts),
- updateMetric("dotsAndDollarsFields.updates", &updates) {}
-
void incrementForUpsert(bool didInsert) {
if (didInsert) {
inserts.increment();
@@ -328,28 +322,15 @@ public:
}
}
- Counter64 inserts;
- Counter64 updates;
- ServerStatusMetricField<Counter64> insertMetric;
- ServerStatusMetricField<Counter64> updateMetric;
+ CounterMetric inserts{"dotsAndDollarsFields.inserts"};
+ CounterMetric updates{"dotsAndDollarsFields.updates"};
};
extern DotsAndDollarsFieldsCounters dotsAndDollarsFieldsCounters;
class QueryEngineCounters {
public:
- QueryEngineCounters()
- : sbeFindQueryMetric("query.queryExecutionEngine.find.sbe", &sbeFindQueryCounter),
- classicFindQueryMetric("query.queryExecutionEngine.find.classic",
- &classicFindQueryCounter),
- sbeOnlyAggregationMetric("query.queryExecutionEngine.aggregate.sbeOnly",
- &sbeOnlyAggregationCounter),
- classicOnlyAggregationMetric("query.queryExecutionEngine.aggregate.classicOnly",
- &classicOnlyAggregationCounter),
- sbeHybridAggregationMetric("query.queryExecutionEngine.aggregate.sbeHybrid",
- &sbeHybridAggregationCounter),
- classicHybridAggregationMetric("query.queryExecutionEngine.aggregate.classicHybrid",
- &classicHybridAggregationCounter) {}
+ QueryEngineCounters() = default;
void incrementQueryEngineCounters(CurOp* curop) {
auto& debug = curop->debug();
@@ -381,21 +362,17 @@ public:
// Query counters that record whether a find query was fully or partially executed in SBE, or
// fully executed using the classic engine. One or the other will always be incremented during a
// query.
- Counter64 sbeFindQueryCounter;
- Counter64 classicFindQueryCounter;
- ServerStatusMetricField<Counter64> sbeFindQueryMetric;
- ServerStatusMetricField<Counter64> classicFindQueryMetric;
+ CounterMetric sbeFindQueryCounter{"query.queryExecutionEngine.find.sbe"};
+ CounterMetric classicFindQueryCounter{"query.queryExecutionEngine.find.classic"};
+
// Aggregation query counters that record whether an aggregation was fully or partially executed
// in DocumentSource (an sbe/classic hybrid plan), or fully pushed down to the sbe/classic
// layer. Only incremented during aggregations.
- Counter64 sbeOnlyAggregationCounter;
- Counter64 classicOnlyAggregationCounter;
- Counter64 sbeHybridAggregationCounter;
- Counter64 classicHybridAggregationCounter;
- ServerStatusMetricField<Counter64> sbeOnlyAggregationMetric;
- ServerStatusMetricField<Counter64> classicOnlyAggregationMetric;
- ServerStatusMetricField<Counter64> sbeHybridAggregationMetric;
- ServerStatusMetricField<Counter64> classicHybridAggregationMetric;
+ CounterMetric sbeOnlyAggregationCounter{"query.queryExecutionEngine.aggregate.sbeOnly"};
+ CounterMetric classicOnlyAggregationCounter{"query.queryExecutionEngine.aggregate.classicOnly"};
+ CounterMetric sbeHybridAggregationCounter{"query.queryExecutionEngine.aggregate.sbeHybrid"};
+ CounterMetric classicHybridAggregationCounter{
+ "query.queryExecutionEngine.aggregate.classicHybrid"};
};
extern QueryEngineCounters queryEngineCounters;
@@ -405,9 +382,8 @@ extern QueryEngineCounters queryEngineCounters;
class OperatorCounters {
private:
struct ExprCounter {
- ExprCounter(const std::string name) : metric(name, &counter) {}
- Counter64 counter;
- ServerStatusMetricField<Counter64> metric;
+ ExprCounter(const std::string& name) : counter(name) {}
+ CounterMetric counter;
};
public:
diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp
index 1bd928185b8..73f3727776a 100644
--- a/src/mongo/db/ttl.cpp
+++ b/src/mongo/db/ttl.cpp
@@ -28,11 +28,8 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/ttl.h"
-#include "mongo/base/counter.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/catalog/collection.h"
@@ -197,14 +194,10 @@ MONGO_FAIL_POINT_DEFINE(hangTTLMonitorBetweenPasses);
// consist of multiple sub-passes. Each sub-pass deletes all the expired documents it can up to
// 'ttlSubPassTargetSecs'. It is possible for a sub-pass to complete before all expired documents
// have been removed.
-Counter64 ttlPasses;
-Counter64 ttlSubPasses;
-Counter64 ttlDeletedDocuments;
-
-ServerStatusMetricField<Counter64> ttlPassesDisplay("ttl.passes", &ttlPasses);
-ServerStatusMetricField<Counter64> ttlSubPassesDisplay("ttl.subPasses", &ttlSubPasses);
-ServerStatusMetricField<Counter64> ttlDeletedDocumentsDisplay("ttl.deletedDocuments",
- &ttlDeletedDocuments);
+CounterMetric ttlPasses("ttl.passes");
+CounterMetric ttlSubPasses("ttl.subPasses");
+CounterMetric ttlDeletedDocuments("ttl.deletedDocuments");
+
using MtabType = TenantMigrationAccessBlocker::BlockerType;
TTLMonitor* TTLMonitor::get(ServiceContext* serviceCtx) {
diff --git a/src/mongo/db/write_concern.cpp b/src/mongo/db/write_concern.cpp
index 352deaad024..a0255dc5aa6 100644
--- a/src/mongo/db/write_concern.cpp
+++ b/src/mongo/db/write_concern.cpp
@@ -28,11 +28,8 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/write_concern.h"
-#include "mongo/base/counter.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/db/client.h"
#include "mongo/db/commands/server_status_metric.h"
@@ -60,20 +57,10 @@ namespace mongo {
using repl::OpTime;
using std::string;
-static TimerStats gleWtimeStats;
-static ServerStatusMetricField<TimerStats> displayGleLatency("getLastError.wtime", &gleWtimeStats);
-
-static Counter64 gleWtimeouts;
-static ServerStatusMetricField<Counter64> gleWtimeoutsDisplay("getLastError.wtimeouts",
- &gleWtimeouts);
-
-static Counter64 gleDefaultWtimeouts;
-static ServerStatusMetricField<Counter64> gleDefaultWtimeoutsDisplay(
- "getLastError.default.wtimeouts", &gleDefaultWtimeouts);
-
-static Counter64 gleDefaultUnsatisfiable;
-static ServerStatusMetricField<Counter64> gleDefaultUnsatisfiableDisplay(
- "getLastError.default.unsatisfiable", &gleDefaultUnsatisfiable);
+static TimerStats& gleWtimeStats = makeServerStatusMetric<TimerStats>("getLastError.wtime");
+static CounterMetric gleWtimeouts("getLastError.wtimeouts");
+static CounterMetric gleDefaultWtimeouts("getLastError.default.wtimeouts");
+static CounterMetric gleDefaultUnsatisfiable("getLastError.default.unsatisfiable");
MONGO_FAIL_POINT_DEFINE(hangBeforeWaitingForWriteConcern);
diff --git a/src/mongo/s/chunk_manager_targeter.cpp b/src/mongo/s/chunk_manager_targeter.cpp
index 6e6a6bf79e3..bec32dfd8c4 100644
--- a/src/mongo/s/chunk_manager_targeter.cpp
+++ b/src/mongo/s/chunk_manager_targeter.cpp
@@ -28,11 +28,8 @@
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/s/chunk_manager_targeter.h"
-#include "mongo/base/counter.h"
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/db/curop.h"
#include "mongo/db/matcher/extensions_callback_noop.h"
@@ -75,9 +72,8 @@ using UpdateType = write_ops::UpdateModification::Type;
// Tracks the number of {multi:false} updates with an exact match on _id that are broadcasted to
// multiple shards.
-Counter64 updateOneOpStyleBroadcastWithExactIDCount;
-ServerStatusMetricField<Counter64> updateOneOpStyleBroadcastWithExactIDStats(
- "query.updateOneOpStyleBroadcastWithExactIDCount", &updateOneOpStyleBroadcastWithExactIDCount);
+CounterMetric updateOneOpStyleBroadcastWithExactIDCount(
+ "query.updateOneOpStyleBroadcastWithExactIDCount");
/**
* Update expressions are bucketed into one of two types for the purposes of shard targeting:
diff --git a/src/mongo/s/cluster_cursor_stats.cpp b/src/mongo/s/cluster_cursor_stats.cpp
index bb61b9647da..46ae32f88cd 100644
--- a/src/mongo/s/cluster_cursor_stats.cpp
+++ b/src/mongo/s/cluster_cursor_stats.cpp
@@ -27,8 +27,6 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/db/commands/server_status_metric.h"
#include "mongo/s/grid.h"
#include "mongo/s/query/cluster_cursor_manager.h"
@@ -62,8 +60,9 @@ public:
}
cursorBob.done();
}
+};
-} clusterCursorStats;
+ClusterCursorStats& clusterCursorStats = addMetricToTree(std::make_unique<ClusterCursorStats>());
} // namespace
} // namespace mongo
diff --git a/src/mongo/s/query/cluster_client_cursor_impl.cpp b/src/mongo/s/query/cluster_client_cursor_impl.cpp
index 73be5a7512a..b08a807788c 100644
--- a/src/mongo/s/query/cluster_client_cursor_impl.cpp
+++ b/src/mongo/s/query/cluster_client_cursor_impl.cpp
@@ -27,8 +27,6 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/s/query/cluster_client_cursor_impl.h"
#include <memory>
@@ -41,12 +39,8 @@
namespace mongo {
-static Counter64 mongosCursorStatsTotalOpened;
-static Counter64 mongosCursorStatsMoreThanOneBatch;
-static ServerStatusMetricField<Counter64> displayMongosCursorStatsTotalOpened(
- "mongos.cursor.totalOpened", &mongosCursorStatsTotalOpened);
-static ServerStatusMetricField<Counter64> displayMongosCursorStatsMoreThanOneBatch(
- "mongos.cursor.moreThanOneBatch", &mongosCursorStatsMoreThanOneBatch);
+static CounterMetric mongosCursorStatsTotalOpened("mongos.cursor.totalOpened");
+static CounterMetric mongosCursorStatsMoreThanOneBatch("mongos.cursor.moreThanOneBatch");
ClusterClientCursorGuard ClusterClientCursorImpl::make(
OperationContext* opCtx,