80
80
#include " mongo/transport/service_executor.h"
81
81
#include " mongo/util/assert_util.h"
82
82
#include " mongo/util/clock_source.h"
83
+ #include " mongo/util/concurrency/ticketholder_queue_stats.h"
83
84
#include " mongo/util/database_name_util.h"
84
85
#include " mongo/util/decorable.h"
85
86
#include " mongo/util/duration.h"
97
98
namespace mongo {
98
99
99
100
namespace {
100
- StringMap<std::function<AdmissionContext*(OperationContext*)>> gQueueMetricsRegistry ;
101
101
102
102
auto & oplogGetMoreStats = *MetricBuilder<TimerStats>(" repl.network.oplogGetMoresProcessed" );
103
103
@@ -115,15 +115,6 @@ BSONObj serializeDollarDbInOpDescription(boost::optional<TenantId> tenantId,
115
115
.firstElement ());
116
116
return newCmdObj;
117
117
}
118
-
119
- MONGO_INITIALIZER (InitGlobalQueueLookupTable)(InitializerContext*) {
120
- gQueueMetricsRegistry [" ingress" ] = [](OperationContext* opCtx) {
121
- return &IngressAdmissionContext::get (opCtx);
122
- };
123
- gQueueMetricsRegistry [" execution" ] = [](OperationContext* opCtx) {
124
- return &ExecutionAdmissionContext::get (opCtx);
125
- };
126
- }
127
118
} // namespace
128
119
129
120
/* *
@@ -827,6 +818,47 @@ void appendObjectTruncatingAsNecessary(StringData fieldName,
827
818
buildTruncatedObject (obj, *maxSize, builder);
828
819
truncatedBuilder.doneFast ();
829
820
}
821
+
822
+ /* *
823
+ * Populates the BSONObjBuilder with the queueing statistics of the current operation. Calculates
824
+ * overall queue stats and records the current queue if the operation is presently queued.
825
+ */
826
+ void populateCurrentOpQueueStats (OperationContext* opCtx,
827
+ TickSource* tickSource,
828
+ BSONObjBuilder* currOpStats) {
829
+ boost::optional<std::tuple<TicketHolderQueueStats::QueueType, Microseconds >> currentQueue;
830
+ BSONObjBuilder queuesBuilder (currOpStats->subobjStart (" queues" ));
831
+
832
+ for (auto && [queueType, lookup] : TicketHolderQueueStats::getQueueMetricsRegistry ()) {
833
+ AdmissionContext* admCtx = lookup (opCtx);
834
+ Microseconds totalTimeQueuedMicros = admCtx->totalTimeQueuedMicros ();
835
+
836
+ if (auto startQueueingTime = admCtx->startQueueingTime ()) {
837
+ Microseconds currentQueueTimeQueuedMicros = tickSource->ticksTo <Microseconds >(
838
+ opCtx->getServiceContext ()->getTickSource ()->getTicks () - *startQueueingTime);
839
+ totalTimeQueuedMicros += currentQueueTimeQueuedMicros;
840
+ currentQueue = std::make_tuple (queueType, currentQueueTimeQueuedMicros);
841
+ }
842
+ BSONObjBuilder queueMetricsBuilder (
843
+ queuesBuilder.subobjStart (TicketHolderQueueStats::queueTypeToString (queueType)));
844
+ queueMetricsBuilder.append (" admissions" , admCtx->getAdmissions ());
845
+ queueMetricsBuilder.append (" totalTimeQueuedMicros" ,
846
+ durationCount<Microseconds >(totalTimeQueuedMicros));
847
+ queueMetricsBuilder.append (" isHoldingTicket" , admCtx->isHoldingTicket ());
848
+ queueMetricsBuilder.done ();
849
+ }
850
+ queuesBuilder.done ();
851
+ if (currentQueue) {
852
+ BSONObjBuilder currentQueueBuilder (currOpStats->subobjStart (" currentQueue" ));
853
+ currentQueueBuilder.append (
854
+ " name" , TicketHolderQueueStats::queueTypeToString (std::get<0 >(*currentQueue)));
855
+ currentQueueBuilder.append (" timeQueuedMicros" ,
856
+ durationCount<Microseconds >(std::get<1 >(*currentQueue)));
857
+ currentQueueBuilder.done ();
858
+ } else {
859
+ currOpStats->appendNull (" currentQueue" );
860
+ }
861
+ };
830
862
} // namespace
831
863
832
864
BSONObj CurOp::truncateAndSerializeGenericCursor (GenericCursor cursor,
@@ -972,38 +1004,7 @@ void CurOp::reportState(BSONObjBuilder* builder,
972
1004
builder->append (" waitForWriteConcernDurationMillis" ,
973
1005
durationCount<Milliseconds>(elapsedTimeTotal));
974
1006
}
975
-
976
- boost::optional<std::tuple<std::string, Microseconds >> currentQueue;
977
- BSONObjBuilder queuesBuilder (builder->subobjStart (" queues" ));
978
- for (auto && [queueName, lookup] : gQueueMetricsRegistry ) {
979
- AdmissionContext* admCtx = lookup (opCtx);
980
- Microseconds totalTimeQueuedMicros = admCtx->totalTimeQueuedMicros ();
981
-
982
- if (auto startQueueingTime = admCtx->startQueueingTime ()) {
983
- Microseconds currentQueueTimeQueuedMicros = computeElapsedTimeTotal (
984
- *startQueueingTime, opCtx->getServiceContext ()->getTickSource ()->getTicks ());
985
- totalTimeQueuedMicros += currentQueueTimeQueuedMicros;
986
- currentQueue = std::make_tuple (queueName, currentQueueTimeQueuedMicros);
987
- }
988
-
989
- BSONObjBuilder queueMetricsBuilder (queuesBuilder.subobjStart (queueName));
990
- queueMetricsBuilder.append (" admissions" , admCtx->getAdmissions ());
991
- queueMetricsBuilder.append (" totalTimeQueuedMicros" ,
992
- durationCount<Microseconds >(totalTimeQueuedMicros));
993
- queueMetricsBuilder.append (" isHoldingTicket" , admCtx->isHoldingTicket ());
994
- queueMetricsBuilder.done ();
995
- }
996
- queuesBuilder.done ();
997
-
998
- if (currentQueue) {
999
- BSONObjBuilder currentQueueBuilder (builder->subobjStart (" currentQueue" ));
1000
- currentQueueBuilder.append (" name" , std::get<0 >(*currentQueue));
1001
- currentQueueBuilder.append (" timeQueuedMicros" ,
1002
- durationCount<Microseconds >(std::get<1 >(*currentQueue)));
1003
- currentQueueBuilder.done ();
1004
- } else {
1005
- builder->appendNull (" currentQueue" );
1006
- }
1007
+ populateCurrentOpQueueStats (opCtx, _tickSource, builder);
1007
1008
}
1008
1009
1009
1010
CurOp::AdditiveResourceStats CurOp::getAdditiveResourceStats (
@@ -1329,21 +1330,9 @@ void OpDebug::report(OperationContext* opCtx,
1329
1330
pAttrs->add (" remoteOpWaitMillis" , durationCount<Milliseconds>(*remoteOpWaitTime));
1330
1331
}
1331
1332
1332
- BSONObjBuilder queuesBuilder;
1333
- for (auto && [queueName, lookup] : gQueueMetricsRegistry ) {
1334
- AdmissionContext* admCtx = lookup (opCtx);
1335
- BSONObjBuilder bb;
1336
- if (auto admissions = admCtx->getAdmissions (); admissions > 0 ) {
1337
- bb.append (" admissions" , admissions);
1338
- }
1339
- if (auto queued = durationCount<Microseconds >(admCtx->totalTimeQueuedMicros ());
1340
- queued > 0 ) {
1341
- bb.append (" totalTimeQueuedMicros" , queued);
1342
- }
1343
- queuesBuilder.append (queueName, bb.obj ());
1344
- }
1345
-
1346
- pAttrs->add (" queues" , queuesBuilder.obj ());
1333
+ // Extract admisson and execution control queueing stats from AdmissionContext stored on opCtx
1334
+ TicketHolderQueueStats queueingStats (opCtx);
1335
+ pAttrs->add (" queues" , queueingStats.toBson ());
1347
1336
1348
1337
// workingMillis should always be present for any operation
1349
1338
pAttrs->add (" workingMillis" , workingTimeMillis.count ());
0 commit comments