summaryrefslogtreecommitdiff
path: root/src/mongo/db/stats/top.cpp
diff options
context:
space:
mode:
authorKevin Albertson <kevin.albertson@10gen.com>2016-06-23 11:49:38 -0400
committerKyle Suarez <kyle.suarez@mongodb.com>2016-06-23 17:47:06 -0400
commitc7794350b056cdea85e1c6185a7dda4579936179 (patch)
treee310fe6e872390cdfe18ab756c51aab1e34a064c /src/mongo/db/stats/top.cpp
parentacb5215fd12e5d018bfec9207d9a18dd35df65a6 (diff)
downloadmongo-c7794350b056cdea85e1c6185a7dda4579936179.tar.gz
SERVER-5905 Add operation latency histogram
Signed-off-by: Kyle Suarez <kyle.suarez@mongodb.com>
Diffstat (limited to 'src/mongo/db/stats/top.cpp')
-rw-r--r--src/mongo/db/stats/top.cpp79
1 files changed, 76 insertions, 3 deletions
diff --git a/src/mongo/db/stats/top.cpp b/src/mongo/db/stats/top.cpp
index be251870d94..3cfb01fd386 100644
--- a/src/mongo/db/stats/top.cpp
+++ b/src/mongo/db/stats/top.cpp
@@ -33,6 +33,8 @@
#include "mongo/db/stats/top.h"
+#include "mongo/db/commands/server_status_metric.h"
+#include "mongo/db/curop.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/service_context.h"
#include "mongo/util/log.h"
@@ -72,7 +74,12 @@ Top& Top::get(ServiceContext* service) {
return getTop(service);
}
-void Top::record(StringData ns, LogicalOp logicalOp, int lockType, long long micros, bool command) {
+void Top::record(OperationContext* txn,
+ StringData ns,
+ LogicalOp logicalOp,
+ int lockType,
+ long long micros,
+ bool command) {
if (ns[0] == '?')
return;
@@ -87,10 +94,14 @@ void Top::record(StringData ns, LogicalOp logicalOp, int lockType, long long mic
}
CollectionData& coll = _usage[hashedNs];
- _record(coll, logicalOp, lockType, micros);
+ _record(txn, coll, logicalOp, lockType, micros);
}
-void Top::_record(CollectionData& c, LogicalOp logicalOp, int lockType, long long micros) {
+void Top::_record(
+ OperationContext* txn, CollectionData& c, LogicalOp logicalOp, int lockType, long long micros) {
+
+ _incrementHistogram(txn, micros, &c.opLatencyHistogram);
+
c.total.inc(micros);
if (lockType > 0)
@@ -180,4 +191,66 @@ void Top::_appendStatsEntry(BSONObjBuilder& b, const char* statsName, const Usag
bb.appendNumber("count", map.count);
bb.done();
}
+
+void Top::appendLatencyStats(StringData ns, BSONObjBuilder* builder) {
+ auto hashedNs = UsageMap::HashedKey(ns);
+ stdx::lock_guard<SimpleMutex> lk(_lock);
+ BSONObjBuilder latencyStatsBuilder;
+ _usage[hashedNs].opLatencyHistogram.append(&latencyStatsBuilder);
+ builder->append("latencyStats", latencyStatsBuilder.obj());
+}
+
+void Top::incrementGlobalLatencyStats(OperationContext* txn, uint64_t latency) {
+ stdx::lock_guard<SimpleMutex> guard(_lock);
+ _incrementHistogram(txn, latency, &_globalHistogramStats);
+}
+
+void Top::appendGlobalLatencyStats(BSONObjBuilder* builder) {
+ stdx::lock_guard<SimpleMutex> guard(_lock);
+ _globalHistogramStats.append(builder);
+}
+
+Command::ReadWriteType Top::_getReadWriteType(Command* cmd, LogicalOp logicalOp) {
+ // For legacy operations, cmd may be a nullptr.
+ if (cmd) {
+ return cmd->getReadWriteType();
+ }
+ switch (logicalOp) {
+ case LogicalOp::opGetMore:
+ case LogicalOp::opQuery:
+ return Command::ReadWriteType::kRead;
+ case LogicalOp::opUpdate:
+ case LogicalOp::opInsert:
+ case LogicalOp::opDelete:
+ return Command::ReadWriteType::kWrite;
+ default:
+ return Command::ReadWriteType::kCommand;
+ }
+}
+
+void Top::_incrementHistogram(OperationContext* txn,
+ long long latency,
+ OperationLatencyHistogram* histogram) {
+ // Only update histogram if operation came from a user.
+ Client* client = txn->getClient();
+ if (client->isFromUserConnection() && !client->isInDirectClient()) {
+ CurOp* curOp = CurOp::get(txn);
+ Command* cmd = curOp->getCommand();
+ Command::ReadWriteType readWriteType = _getReadWriteType(cmd, curOp->getLogicalOp());
+ histogram->increment(latency, readWriteType);
+ }
}
+
+/**
+ * Appends the global histogram to the server status.
+ */
+class GlobalHistogramServerStatusMetric : public ServerStatusMetric {
+public:
+ GlobalHistogramServerStatusMetric() : ServerStatusMetric(".metrics.latency") {}
+ virtual void appendAtLeaf(BSONObjBuilder& builder) const {
+ BSONObjBuilder latencyBuilder;
+ Top::get(getGlobalServiceContext()).appendGlobalLatencyStats(&latencyBuilder);
+ builder.append("latency", latencyBuilder.obj());
+ }
+} globalHistogramServerStatusMetric;
+} // namespace mongo