diff options
author | Kevin Albertson <kevin.albertson@10gen.com> | 2016-06-23 11:49:38 -0400 |
---|---|---|
committer | Kyle Suarez <kyle.suarez@mongodb.com> | 2016-06-23 17:47:06 -0400 |
commit | c7794350b056cdea85e1c6185a7dda4579936179 (patch) | |
tree | e310fe6e872390cdfe18ab756c51aab1e34a064c /src/mongo/db/stats/top.cpp | |
parent | acb5215fd12e5d018bfec9207d9a18dd35df65a6 (diff) | |
download | mongo-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.cpp | 79 |
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 |