summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsergey.galtsev <sergey.galtsev@mongodb.com>2021-09-14 15:44:07 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-09-14 16:25:02 +0000
commit5d4ed76399c76889886384c3258173a1b7ed96e2 (patch)
tree2325ee12e92e7505d8f6474af28955b6b7a73695
parent85cf0f4bdb5763514df90653a677cf8fa0100305 (diff)
downloadmongo-5d4ed76399c76889886384c3258173a1b7ed96e2.tar.gz
SERVER-59046 Track LDAP Duration in FTDC
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/auth/SConscript2
-rw-r--r--src/mongo/db/auth/ldap_cumulative_operation_stats.cpp126
-rw-r--r--src/mongo/db/auth/ldap_cumulative_operation_stats.h110
-rw-r--r--src/mongo/db/auth/ldap_operation_stats.cpp2
-rw-r--r--src/mongo/db/auth/ldap_operation_stats.h2
-rw-r--r--src/mongo/db/auth/user_acquisition_stats.h8
-rw-r--r--src/mongo/db/service_entry_point_common.cpp10
8 files changed, 260 insertions, 1 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index a6dc31a38df..eeb86acd25e 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -920,6 +920,7 @@ env.Library(
'$BUILD_DIR/mongo/db/stats/top',
'$BUILD_DIR/mongo/db/storage/storage_engine_lock_file',
'$BUILD_DIR/mongo/db/storage/storage_engine_metadata',
+ "auth/user_acquisition_stats",
'commands/server_status_core',
'initialize_api_parameters',
'introspect',
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 6e49b285a07..f83622f3075 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -199,6 +199,7 @@ env.Library(
'builtin_roles',
'sasl_options',
'user',
+ 'user_acquisition_stats',
'user_document_parser',
],
LIBDEPS_PRIVATE=[
@@ -506,6 +507,7 @@ env.Library(
target='user_acquisition_stats',
source=[
'ldap_operation_stats.cpp',
+ 'ldap_cumulative_operation_stats.cpp',
'user_cache_acquisition_stats.cpp'
],
LIBDEPS_PRIVATE=[
diff --git a/src/mongo/db/auth/ldap_cumulative_operation_stats.cpp b/src/mongo/db/auth/ldap_cumulative_operation_stats.cpp
new file mode 100644
index 00000000000..d135e9e9a9a
--- /dev/null
+++ b/src/mongo/db/auth/ldap_cumulative_operation_stats.cpp
@@ -0,0 +1,126 @@
+/**
+ * Copyright (C) 2021-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/platform/basic.h"
+
+#include "mongo/base/error_extra_info.h"
+#include "mongo/db/auth/ldap_cumulative_operation_stats.h"
+#include "mongo/db/auth/ldap_operation_stats.h"
+#include "mongo/db/curop_metrics.h"
+#include "mongo/db/service_context.h"
+
+namespace mongo {
+namespace {
+/**
+ * LDAPOperationStats members
+ */
+constexpr auto kNumberOfReferrals = "LDAPNumberOfReferrals"_sd;
+constexpr auto kBindStats = "bindStats"_sd;
+constexpr auto kSearchStats = "searchStats"_sd;
+constexpr auto kUnbindStats = "unbindStats"_sd;
+
+/**
+ * Fields of the Stats struct
+ */
+constexpr auto kLDAPMetricNumOp = "numOp"_sd;
+constexpr auto kLDAPMetricDuration = "opDurationMicros"_sd;
+
+const auto getLDAPCumulativeOperationStats =
+ ServiceContext::declareDecoration<std::unique_ptr<LDAPCumulativeOperationStats>>();
+
+ServiceContext::ConstructorActionRegisterer setLDAPCumulativeOperationStats{
+ "SetLDAPCumulativeOperationStats", [](ServiceContext* service) {
+ auto s = std::make_unique<LDAPCumulativeOperationStats>();
+ getLDAPCumulativeOperationStats(service) = std::move(s);
+ }};
+
+} // namespace
+
+void LDAPCumulativeOperationStats::report(BSONObjBuilder* builder) const {
+ auto reportHelper = [=](const Stats& stats, StringData statsName) {
+ BSONObjBuilder subObjBuildr(builder->subobjStart(statsName));
+ subObjBuildr.append(kLDAPMetricNumOp, stats.numOps);
+ subObjBuildr.append(kLDAPMetricDuration, durationCount<Microseconds>(stats.totalTime));
+ };
+
+ stdx::lock_guard<Latch> lock(_memberAccessMutex);
+
+ builder->append(kNumberOfReferrals, _numReferrals);
+ reportHelper(_bindStats, kBindStats);
+ reportHelper(_searchStats, kSearchStats);
+ reportHelper(_unbindStats, kUnbindStats);
+}
+
+void LDAPCumulativeOperationStats::toString(StringBuilder* sb) const {
+ auto toStringHelper = [=](const Stats& stats, StringData statsName) {
+ *sb << statsName << "{" << kLDAPMetricNumOp << ":" << stats.numOps << ","
+ << kLDAPMetricDuration << ":" << durationCount<Microseconds>(stats.totalTime) << "}";
+ };
+
+ stdx::lock_guard<Latch> lock(_memberAccessMutex);
+
+ *sb << "{" << kNumberOfReferrals << ":" << _numReferrals << ",";
+ toStringHelper(_bindStats, kBindStats);
+ toStringHelper(_searchStats, kSearchStats);
+ toStringHelper(_unbindStats, kUnbindStats);
+ *sb << "}";
+}
+
+bool LDAPCumulativeOperationStats::hasData() const {
+ stdx::lock_guard<Latch> lock(_memberAccessMutex);
+ return _numReferrals > 0 || _bindStats.numOps > 0 || _searchStats.numOps > 0 ||
+ _unbindStats.numOps > 0;
+}
+
+void LDAPCumulativeOperationStats::recordOpStats(const LDAPOperationStats& stats, bool isUnbind) {
+ auto recordHelper = [](Stats& stats, const LDAPOperationStats::Stats& ldapOpStats) {
+ stats.numOps += ldapOpStats.numOps;
+ stats.totalTime += ldapOpStats.endTime - ldapOpStats.startTime;
+ };
+
+ stdx::lock_guard<Latch> lock(_memberAccessMutex);
+
+ if (isUnbind) {
+ recordHelper(_unbindStats, stats._unbindStats);
+ } else {
+ _numReferrals += stats._numReferrals;
+ recordHelper(_bindStats, stats._bindStats);
+ recordHelper(_searchStats, stats._searchStats);
+ }
+}
+
+LDAPCumulativeOperationStats* LDAPCumulativeOperationStats::get() {
+ if (hasGlobalServiceContext()) {
+ return getLDAPCumulativeOperationStats(getGlobalServiceContext()).get();
+ } else {
+ return nullptr;
+ }
+}
+
+} // namespace mongo
diff --git a/src/mongo/db/auth/ldap_cumulative_operation_stats.h b/src/mongo/db/auth/ldap_cumulative_operation_stats.h
new file mode 100644
index 00000000000..c24bce49c47
--- /dev/null
+++ b/src/mongo/db/auth/ldap_cumulative_operation_stats.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (C) 2021-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 <cstdint>
+#include <memory>
+
+#include "mongo/base/string_data.h"
+#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/platform/mutex.h"
+#include "mongo/util/duration.h"
+#include "mongo/util/tick_source.h"
+
+namespace mongo {
+
+class LDAPOperationStats;
+
+/**
+ * Class used to track statistics associated with LDAP operations for a specfic
+ * UserAcquisitionStats object.
+ */
+class LDAPCumulativeOperationStats {
+public:
+ LDAPCumulativeOperationStats() = default;
+ ~LDAPCumulativeOperationStats() = default;
+ LDAPCumulativeOperationStats(const LDAPCumulativeOperationStats&) = delete;
+ LDAPCumulativeOperationStats& operator=(const LDAPCumulativeOperationStats&) = delete;
+
+ /**
+ * Marshals all statistics into BSON for reporting.
+ */
+ void report(BSONObjBuilder* builder) const;
+
+ /**
+ * Marshals all statistics into a string for reporting.
+ */
+ void toString(StringBuilder* sb) const;
+
+ /**
+ * Indicates whether any data was recorded
+ */
+ bool hasData() const;
+
+ /**
+ * Record stats for an LDAP operation.
+ * Parameter "isUnbind" is true when we record disconnection, false otherwise
+ */
+ void recordOpStats(const LDAPOperationStats& stats, bool isUnbind);
+
+ /**
+ * Gets pointer to a global instance or nullptr if not initialized.
+ */
+ static LDAPCumulativeOperationStats* get();
+
+private:
+ /**
+ * Struct Stats is used to contain information about the bind, search, and unbind stats
+ * of the LDAP Operations.
+ */
+ struct Stats {
+ int64_t numOps{0};
+ Microseconds totalTime{Microseconds{0}};
+ };
+
+ /**
+ * Number of referrals to other LDAP servers
+ */
+ int64_t _numReferrals{0};
+
+ /**
+ * Metrics associated with binding, search/query, and unbinding from an LDAP server.
+ */
+ Stats _bindStats;
+ Stats _searchStats;
+ Stats _unbindStats;
+
+ /**
+ * Protects access to member variables.
+ */
+ mutable Mutex _memberAccessMutex =
+ MONGO_MAKE_LATCH("LDAPCumulativeOperationStats::_memberAccessMutex");
+};
+} // namespace mongo
diff --git a/src/mongo/db/auth/ldap_operation_stats.cpp b/src/mongo/db/auth/ldap_operation_stats.cpp
index 259e88ffec9..a103c308a8f 100644
--- a/src/mongo/db/auth/ldap_operation_stats.cpp
+++ b/src/mongo/db/auth/ldap_operation_stats.cpp
@@ -50,7 +50,7 @@ constexpr auto kUnbindStats = "unbindStats"_sd;
* Fields of the Stats struct
*/
constexpr auto kLDAPMetricNumOp = "numOp"_sd;
-constexpr auto kLDAPMetricDuration = "opDuration"_sd;
+constexpr auto kLDAPMetricDuration = "opDurationMicros"_sd;
} // namespace
diff --git a/src/mongo/db/auth/ldap_operation_stats.h b/src/mongo/db/auth/ldap_operation_stats.h
index c9a141c6581..3ef49bf9ae1 100644
--- a/src/mongo/db/auth/ldap_operation_stats.h
+++ b/src/mongo/db/auth/ldap_operation_stats.h
@@ -120,6 +120,8 @@ public:
}
private:
+ friend class LDAPCumulativeOperationStats;
+
/**
* Struct Stats is used to contain information about the bind, search, and unbind stats
* of the LDAP Operations.
diff --git a/src/mongo/db/auth/user_acquisition_stats.h b/src/mongo/db/auth/user_acquisition_stats.h
index aae69275639..a3973ccd7a1 100644
--- a/src/mongo/db/auth/user_acquisition_stats.h
+++ b/src/mongo/db/auth/user_acquisition_stats.h
@@ -32,6 +32,7 @@
#include <memory>
#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/db/auth/ldap_cumulative_operation_stats.h"
#include "mongo/db/auth/ldap_operation_stats.h"
#include "mongo/db/client.h"
#include "mongo/platform/mutex.h"
@@ -97,6 +98,9 @@ public:
_ldapOperationStats.toString(sb, tickSource);
}
+ const LDAPOperationStats& getLdapOperationStats() const {
+ return _ldapOperationStats;
+ }
private:
/**
@@ -152,6 +156,10 @@ private:
void _recordUnbindEnd(TickSource* tickSource) {
stdx::lock_guard<Latch> lk(_mutex);
_ldapOperationStats.setUnbindStatsEndTime(_getTime(tickSource));
+ auto ldapCumulativeOperationsStats = LDAPCumulativeOperationStats::get();
+ if (nullptr != ldapCumulativeOperationsStats) {
+ ldapCumulativeOperationsStats->recordOpStats(_ldapOperationStats, true);
+ }
}
/**
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index aec93184463..b0b2a905864 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -43,6 +43,7 @@
#include "mongo/db/auth/authorization_checks.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/impersonation_session.h"
+#include "mongo/db/auth/ldap_cumulative_operation_stats.h"
#include "mongo/db/client.h"
#include "mongo/db/command_can_run_here.h"
#include "mongo/db/commands.h"
@@ -2081,6 +2082,15 @@ void HandleRequest::completeOperation(DbResponse& response) {
}
recordCurOpMetrics(opCtx);
+
+ const auto& stats =
+ CurOp::get(opCtx)->getReadOnlyUserAcquisitionStats()->getLdapOperationStats();
+ if (stats.shouldReport()) {
+ auto ldapCumulativeOperationsStats = LDAPCumulativeOperationStats::get();
+ if (nullptr != ldapCumulativeOperationsStats) {
+ ldapCumulativeOperationsStats->recordOpStats(stats, false);
+ }
+ }
}
} // namespace