diff options
author | Louis Williams <louis.williams@mongodb.com> | 2020-12-15 17:09:46 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-15 22:48:51 +0000 |
commit | e9ba0db9a0b5f4e7116670118cf10184a14f2e40 (patch) | |
tree | b28b5ebe86c72d59ca0e73c1f7cbd548ee77235c | |
parent | 843390351dc7cd2e30df9f823b3b37ccff6ae274 (diff) | |
download | mongo-e9ba0db9a0b5f4e7116670118cf10184a14f2e40.tar.gz |
SERVER-53216 Report number of databases in resource consumption serverStatus section
-rw-r--r-- | jstests/noPassthrough/aggregate_operation_metrics.js | 28 | ||||
-rw-r--r-- | src/mongo/db/stats/resource_consumption_metrics.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/stats/resource_consumption_metrics.h | 5 |
3 files changed, 51 insertions, 21 deletions
diff --git a/jstests/noPassthrough/aggregate_operation_metrics.js b/jstests/noPassthrough/aggregate_operation_metrics.js index a1b1ff7a2cc..62533397cf7 100644 --- a/jstests/noPassthrough/aggregate_operation_metrics.js +++ b/jstests/noPassthrough/aggregate_operation_metrics.js @@ -57,10 +57,10 @@ let getDBMetrics = (adminDB) => { return allMetrics; }; -let getGlobalCpuTime = (db) => { - let ss = db.serverStatus({resourceConsumption: true}); +let getServerStatusMetrics = (db) => { + let ss = db.serverStatus(); assert(ss.hasOwnProperty('resourceConsumption'), ss); - return ss.resourceConsumption.cpuNanos; + return ss.resourceConsumption; }; // Perform very basic reads and writes on two different databases. @@ -75,10 +75,6 @@ const db2 = primary.getDB(db2Name); assert.commandWorked(db2.coll1.insert({a: 1})); assert.commandWorked(db2.coll2.insert({a: 1})); -// The 'resourceConsumption' field should not be included in serverStatus by default. -let ss = db1.serverStatus(); -assert(!ss.hasOwnProperty('resourceConsumption'), ss); - const secondary = rst.getSecondary(); [primary, secondary].forEach(function(node) { jsTestLog("Testing node: " + node); @@ -88,7 +84,7 @@ const secondary = rst.getSecondary(); rst.awaitReplication(); const adminDB = node.getDB('admin'); - let initialCpuTime = getGlobalCpuTime(adminDB); + let initialCpuTime = getServerStatusMetrics(adminDB).cpuNanos; adminDB.aggregate([{$operationMetrics: {clearMetrics: true}}]); @@ -117,6 +113,10 @@ const secondary = rst.getSecondary(); assertMetricsExist(allMetrics[db1Name]); assertMetricsExist(allMetrics[db2Name]); + let ssMetrics = getServerStatusMetrics(adminDB); + assert.eq(ssMetrics.numMetrics, 2); + assert.gt(ssMetrics.memUsage, 0); + // Ensure read metrics are attributed to the correct replication state. let lastDocBytesRead; if (node === primary) { @@ -148,7 +148,7 @@ const secondary = rst.getSecondary(); // CPU time aggregation is only supported on Linux. if (isLinux) { // Ensure the CPU time is increasing. - let lastCpuTime = getGlobalCpuTime(adminDB); + let lastCpuTime = getServerStatusMetrics(adminDB).cpuNanos; assert.gt(lastCpuTime, initialCpuTime); // Ensure the global CPU time matches the aggregated time for both databases. @@ -207,6 +207,16 @@ const secondary = rst.getSecondary(); cursor = adminDB.aggregate([{$operationMetrics: {}}]); assert.eq(cursor.itcount(), 0); + // Ensure the serverStatus metrics are cleared except for cpuNanos. + ssMetrics = getServerStatusMetrics(adminDB); + assert.eq(0, ssMetrics.numMetrics); + assert.eq(0, ssMetrics.memUsage); + if (isLinux) { + assert.neq(0, ssMetrics.cpuNanos); + } else { + assert.eq(0, ssMetrics.cpuNanos); + } + // Insert something and ensure metrics are still reporting. assert.commandWorked(db1.coll3.insert({a: 1})); rst.awaitReplication(); diff --git a/src/mongo/db/stats/resource_consumption_metrics.cpp b/src/mongo/db/stats/resource_consumption_metrics.cpp index 49c879cb272..fbc53138f3c 100644 --- a/src/mongo/db/stats/resource_consumption_metrics.cpp +++ b/src/mongo/db/stats/resource_consumption_metrics.cpp @@ -45,21 +45,23 @@ const OperationContext::Decoration<ResourceConsumption::MetricsCollector> getMet const ServiceContext::Decoration<ResourceConsumption> getGlobalResourceConsumption = ServiceContext::declareDecoration<ResourceConsumption>(); -static const char kPrimaryMetrics[] = "primaryMetrics"; -static const char kSecondaryMetrics[] = "secondaryMetrics"; +static const char kCpuNanos[] = "cpuNanos"; +static const char kCursorSeeks[] = "cursorSeeks"; static const char kDocBytesRead[] = "docBytesRead"; +static const char kDocBytesWritten[] = "docBytesWritten"; static const char kDocUnitsRead[] = "docUnitsRead"; +static const char kDocUnitsReturned[] = "docUnitsReturned"; +static const char kDocUnitsWritten[] = "docUnitsWritten"; static const char kIdxEntryBytesRead[] = "idxEntryBytesRead"; +static const char kIdxEntryBytesWritten[] = "idxEntryBytesWritten"; static const char kIdxEntryUnitsRead[] = "idxEntryUnitsRead"; +static const char kIdxEntryUnitsWritten[] = "idxEntryUnitsWritten"; static const char kKeysSorted[] = "keysSorted"; +static const char kMemUsage[] = "memUsage"; +static const char kNumMetrics[] = "numMetrics"; +static const char kPrimaryMetrics[] = "primaryMetrics"; +static const char kSecondaryMetrics[] = "secondaryMetrics"; static const char kSorterSpills[] = "sorterSpills"; -static const char kCpuNanos[] = "cpuNanos"; -static const char kDocBytesWritten[] = "docBytesWritten"; -static const char kDocUnitsWritten[] = "docUnitsWritten"; -static const char kIdxEntryBytesWritten[] = "idxEntryBytesWritten"; -static const char kIdxEntryUnitsWritten[] = "idxEntryUnitsWritten"; -static const char kDocUnitsReturned[] = "docUnitsReturned"; -static const char kCursorSeeks[] = "cursorSeeks"; inline void appendNonZeroMetric(BSONObjBuilder* builder, const char* name, long long value) { if (value != 0) { @@ -74,10 +76,10 @@ class ResourceConsumptionSSS : public ServerStatusSection { public: ResourceConsumptionSSS() : ServerStatusSection("resourceConsumption") {} - // Do not include this metric by default. It is likely to be misleading for diagnostic purposes - // because it does not include the CPU time for every operation or every command. + // Do not include this section unless metrics aggregation is enabled. It will not have populated + // data otherwise. bool includeByDefault() const override { - return false; + return ResourceConsumption::isMetricsAggregationEnabled(); } BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElem) const override { @@ -87,6 +89,14 @@ public: } BSONObjBuilder builder; builder.append(kCpuNanos, durationCount<Nanoseconds>(resourceConsumption.getCpuTime())); + + // The memory usage we report only estimates the amount of memory from the metrics + // themselves, and does not include the overhead of the map container or its keys. + auto numMetrics = resourceConsumption.getNumDbMetrics(); + builder.append( + kMemUsage, + static_cast<long long>(numMetrics * sizeof(ResourceConsumption::AggregatedMetrics))); + builder.append(kNumMetrics, static_cast<long long>(numMetrics)); return builder.obj(); } } resourceConsumptionMetricSSM; @@ -334,6 +344,11 @@ ResourceConsumption::MetricsMap ResourceConsumption::getDbMetrics() const { return _dbMetrics; } +size_t ResourceConsumption::getNumDbMetrics() const { + stdx::lock_guard<Mutex> lk(_mutex); + return _dbMetrics.size(); +} + ResourceConsumption::MetricsMap ResourceConsumption::getAndClearDbMetrics() { stdx::lock_guard<Mutex> lk(_mutex); MetricsMap newMap; diff --git a/src/mongo/db/stats/resource_consumption_metrics.h b/src/mongo/db/stats/resource_consumption_metrics.h index 1dc401aef88..5e098b5c730 100644 --- a/src/mongo/db/stats/resource_consumption_metrics.h +++ b/src/mongo/db/stats/resource_consumption_metrics.h @@ -450,6 +450,11 @@ public: MetricsMap getDbMetrics() const; /** + * Returns the number of databases with aggregated metrics. + */ + size_t getNumDbMetrics() const; + + /** * Returns the per-database metrics map and then clears the contents. This attempts to swap and * return the metrics map rather than making a full copy like getDbMetrics. */ |