diff options
author | Maddie Zechar <mez2113@columbia.edu> | 2023-03-16 15:00:33 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-03-16 16:41:57 +0000 |
commit | 6874e02c337a73f20ebb883c0a8e98d491768c89 (patch) | |
tree | 26d6aff14a09691bb8f5fa6ceb16e80783a8e2bb | |
parent | c3de8f409c1ff691f676b9baa3929ae17dccecc3 (diff) | |
download | mongo-6874e02c337a73f20ebb883c0a8e98d491768c89.tar.gz |
SERVER-73863 allow cluster admin to reset telemetry store to 0 bytes
7 files changed, 67 insertions, 17 deletions
diff --git a/jstests/noPassthrough/telemetry/clear_telemetry_store.js b/jstests/noPassthrough/telemetry/clear_telemetry_store.js new file mode 100644 index 00000000000..3682b16ce66 --- /dev/null +++ b/jstests/noPassthrough/telemetry/clear_telemetry_store.js @@ -0,0 +1,46 @@ +/** + * Test that the telemetry store can be cleared when the cache size is reset to 0. + * @tags: [featureFlagTelemetry] + */ +load("jstests/libs/telemetry_utils.js"); // For verifyMetrics. + +(function() { +"use strict"; + +// Turn on the collecting of telemetry metrics. +let options = { + setParameter: { + internalQueryConfigureTelemetrySamplingRate: 2147483647, + internalQueryConfigureTelemetryCacheSize: "10MB" + }, +}; + +const conn = MongoRunner.runMongod(options); +const testDB = conn.getDB('test'); +var coll = testDB[jsTestName()]; +coll.drop(); + +let query = {}; +for (var j = 0; j < 10; ++j) { + query["foo.field.xyz." + j] = 1; + query["bar.field.xyz." + j] = 2; + query["baz.field.xyz." + j] = 3; + coll.aggregate([{$match: query}]).itcount(); +} + +// Confirm number of entries in the store and that none have been evicted. +let telemetryResults = testDB.getSiblingDB("admin").aggregate([{$telemetry: {}}]).toArray(); +assert.eq(telemetryResults.length, 10, telemetryResults); +assert.eq(testDB.serverStatus().metrics.telemetry.numEvicted, 0); + +// Command to clear the cache. +assert.commandWorked( + testDB.adminCommand({setParameter: 1, internalQueryConfigureTelemetryCacheSize: "0MB"})); + +// 10 regular queries plus the $telemetry query, means 11 entries evicted when the cache is cleared. +assert.eq(testDB.serverStatus().metrics.telemetry.numEvicted, 11); + +// Calling $telemetry should fail when the telemetry store size is 0 bytes. +assert.throwsWithCode(() => testDB.getSiblingDB("admin").aggregate([{$telemetry: {}}]), 6579000); +MongoRunner.stopMongod(conn); +}()); diff --git a/jstests/noPassthrough/telemetry/redactFieldnames_parameter.js b/jstests/noPassthrough/telemetry/redactFieldnames_parameter.js index 7c4ee35ce27..5efbbf07529 100644 --- a/jstests/noPassthrough/telemetry/redactFieldnames_parameter.js +++ b/jstests/noPassthrough/telemetry/redactFieldnames_parameter.js @@ -6,7 +6,6 @@ (function() { "use strict"; -load("jstests/libs/feature_flag_util.js"); // For FeatureFlagUtil. load("jstests/aggregation/extras/utils.js"); // For assertAdminDBErrCodeAndErrMsgContains. // Turn on the collecting of telemetry metrics. diff --git a/jstests/noPassthrough/telemetry/redact_queries_with_nonobject_fields.js b/jstests/noPassthrough/telemetry/redact_queries_with_nonobject_fields.js index 0606ce3d27b..9ef3cabbb54 100644 --- a/jstests/noPassthrough/telemetry/redact_queries_with_nonobject_fields.js +++ b/jstests/noPassthrough/telemetry/redact_queries_with_nonobject_fields.js @@ -3,7 +3,6 @@ * @tags: [featureFlagTelemetry] */ load('jstests/libs/analyze_plan.js'); -load("jstests/libs/feature_flag_util.js"); (function() { "use strict"; diff --git a/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js b/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js index b87c2039362..27fdfb7d1d2 100644 --- a/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js +++ b/jstests/noPassthrough/telemetry/telemetry_metrics_across_getMore_calls.js @@ -3,8 +3,7 @@ * calls. * @tags: [featureFlagTelemetry] */ -load("jstests/libs/feature_flag_util.js"); // For FeatureFlagUtil. -load("jstests/libs/telemetry_utils.js"); // For verifyMetrics. +load("jstests/libs/telemetry_utils.js"); // For verifyMetrics. (function() { "use strict"; diff --git a/jstests/noPassthrough/telemetry/telemetry_sampling_rate.js b/jstests/noPassthrough/telemetry/telemetry_sampling_rate.js index fd3b4105529..823991d652b 100644 --- a/jstests/noPassthrough/telemetry/telemetry_sampling_rate.js +++ b/jstests/noPassthrough/telemetry/telemetry_sampling_rate.js @@ -4,7 +4,6 @@ * @tags: [featureFlagTelemetry] */ load('jstests/libs/analyze_plan.js'); -load("jstests/libs/feature_flag_util.js"); (function() { "use strict"; diff --git a/jstests/noPassthrough/telemetry/telemetry_server_status_metrics.js b/jstests/noPassthrough/telemetry/telemetry_server_status_metrics.js index 0f8bf224e58..cafb42fa3dc 100644 --- a/jstests/noPassthrough/telemetry/telemetry_server_status_metrics.js +++ b/jstests/noPassthrough/telemetry/telemetry_server_status_metrics.js @@ -3,7 +3,6 @@ * @tags: [featureFlagTelemetry] */ load('jstests/libs/analyze_plan.js'); -load("jstests/libs/feature_flag_util.js"); (function() { "use strict"; diff --git a/src/mongo/db/query/telemetry.cpp b/src/mongo/db/query/telemetry.cpp index 89a95f19989..c0c5bd5be8e 100644 --- a/src/mongo/db/query/telemetry.cpp +++ b/src/mongo/db/query/telemetry.cpp @@ -64,13 +64,6 @@ namespace telemetry { // files/libraries here. Instead define here as well. static const std::string kTelemetryKeyInShardedCommand = "hashedTelemetryKey"; -bool isTelemetryEnabled() { - // During initialization FCV may not yet be setup but queries could be run. We can't - // check whether telemetry should be enabled without FCV, so default to not recording - // those queries. - return serverGlobalParams.featureCompatibility.isVersionInitialized() && - feature_flags::gFeatureFlagTelemetry.isEnabled(serverGlobalParams.featureCompatibility); -} ShardedTelemetryStoreKey telemetryKeyToShardedStoreId(const BSONObj& key, std::string hostAndPort) { md5digest finishedMD5; @@ -367,7 +360,7 @@ size_t capTelemetryStoreSize(size_t requestedSize) { size_t getTelemetryStoreSize() { auto status = memory_util::MemorySize::parse(queryTelemetryStoreSize.get()); uassertStatusOK(status); - size_t requestedSize = memory_util::getRequestedMemSizeInBytes(status.getValue()); + size_t requestedSize = memory_util::convertToSizeInBytes(status.getValue()); return capTelemetryStoreSize(requestedSize); } @@ -408,9 +401,8 @@ const auto telemetryRateLimiter = class TelemetryOnParamChangeUpdaterImpl final : public telemetry_util::OnParamChangeUpdater { public: void updateCacheSize(ServiceContext* serviceCtx, memory_util::MemorySize memSize) final { - auto requestedSize = memory_util::getRequestedMemSizeInBytes(memSize); + auto requestedSize = memory_util::convertToSizeInBytes(memSize); auto cappedSize = capTelemetryStoreSize(requestedSize); - auto& telemetryStoreManager = telemetryStoreDecoration(serviceCtx); auto&& telemetryStore = telemetryStoreManager->getTelemetryStore(); size_t numEvicted = telemetryStore.reset(cappedSize); @@ -556,6 +548,7 @@ void appendWithRedactedLiterals(BSONObjBuilder& builder, const BSONElement& el) } // namespace + const BSONObj& TelemetryMetrics::redactKey(const BSONObj& key, bool redactFieldNames) const { // The redacted key for each entry is cached on first computation. However, if the redaction // straegy has flipped (from no redaction to SHA256, vice versa), we just return the key passed @@ -615,6 +608,19 @@ const BSONObj& TelemetryMetrics::redactKey(const BSONObj& key, bool redactFieldN return *_redactedKey; } +/** + * Top-level checks for whether telemetry collection is enabled. If this returns false, we must go + * no further. + */ +bool isTelemetryEnabled() { + // During initialization FCV may not yet be setup but queries could be run. We can't + // check whether telemetry should be enabled without FCV, so default to not recording + // those queries. + return serverGlobalParams.featureCompatibility.isVersionInitialized() && + feature_flags::gFeatureFlagTelemetry.isEnabled(serverGlobalParams.featureCompatibility) && + getTelemetryStoreSize() != 0; +} + // The originating command/query does not persist through the end of query execution. In order to // pair the telemetry metrics that are collected at the end of execution with the original query, it // is necessary to register the original query during planning and persist it after @@ -717,7 +723,10 @@ void registerFindRequest(const FindCommandRequest& request, } TelemetryStore& getTelemetryStore(OperationContext* opCtx) { - uassert(6579000, "Telemetry is not enabled without the feature flag on", isTelemetryEnabled()); + uassert(6579000, + "Telemetry is not enabled without the feature flag on and a cache size greater than 0 " + "bytes", + isTelemetryEnabled()); return telemetryStoreDecoration(opCtx->getServiceContext())->getTelemetryStore(); } |