diff --git a/src/groups/mqb/mqbstat/mqbstat_jsonprinter.cpp b/src/groups/mqb/mqbstat/mqbstat_jsonprinter.cpp index 717e1cebe1..0a4bd591bd 100644 --- a/src/groups/mqb/mqbstat/mqbstat_jsonprinter.cpp +++ b/src/groups/mqb/mqbstat/mqbstat_jsonprinter.cpp @@ -35,9 +35,112 @@ namespace mqbstat { namespace { -// --------------------- -// class JsonPrinterImpl -// --------------------- +struct ConversionUtils { + // PUBLIC CLASS METHODS + + /// "domainQueues" stat context: + /// Populate the specified `bdljsn::JsonObject*` with the values + /// from the specified `ctx`. + + inline static void + populateMetric(bdljsn::JsonObject* metricsObject, + const mwcst::StatContext& ctx, + mqbstat::QueueStatsDomain::Stat::Enum metric) + { + // PRECONDITIONS + BSLS_ASSERT_SAFE(metricsObject); + + const bsls::Types::Int64 value = + mqbstat::QueueStatsDomain::getValue(ctx, -1, metric); + + (*metricsObject)[mqbstat::QueueStatsDomain::Stat::toString(metric)] + .makeNumber() = value; + } + + inline static void populateQueueStats(bdljsn::JsonObject* queueObject, + const mwcst::StatContext& ctx) + { + // PRECONDITIONS + BSLS_ASSERT_SAFE(queueObject); + + if (ctx.numValues() == 0) { + // Prefer to omit an empty "values" object + return; // RETURN + } + + bdljsn::JsonObject& values = (*queueObject)["values"].makeObject(); + + typedef mqbstat::QueueStatsDomain::Stat Stat; + + populateMetric(&values, ctx, Stat::e_NB_PRODUCER); + populateMetric(&values, ctx, Stat::e_NB_CONSUMER); + populateMetric(&values, ctx, Stat::e_PUT_MESSAGES_DELTA); + populateMetric(&values, ctx, Stat::e_PUT_BYTES_DELTA); + populateMetric(&values, ctx, Stat::e_PUSH_MESSAGES_DELTA); + populateMetric(&values, ctx, Stat::e_PUSH_BYTES_DELTA); + populateMetric(&values, ctx, Stat::e_ACK_DELTA); + populateMetric(&values, ctx, Stat::e_ACK_TIME_AVG); + populateMetric(&values, ctx, Stat::e_ACK_TIME_MAX); + populateMetric(&values, ctx, Stat::e_NACK_DELTA); + populateMetric(&values, ctx, Stat::e_CONFIRM_DELTA); + populateMetric(&values, ctx, Stat::e_CONFIRM_TIME_AVG); + populateMetric(&values, ctx, Stat::e_CONFIRM_TIME_MAX); + } + + inline static void populateOneDomainStats(bdljsn::JsonObject* domainObject, + const mwcst::StatContext& ctx) + { + // PRECONDITIONS + BSLS_ASSERT_SAFE(domainObject); + + for (mwcst::StatContextIterator queueIt = ctx.subcontextIterator(); + queueIt; + ++queueIt) { + bdljsn::JsonObject& queueObj = + (*domainObject)[queueIt->name()].makeObject(); + populateQueueStats(&queueObj, *queueIt); + + if (queueIt->numSubcontexts() > 0) { + bdljsn::JsonObject& appIdsObject = + queueObj["appIds"].makeObject(); + + // Add metrics per appId, if any + for (mwcst::StatContextIterator appIdIt = + queueIt->subcontextIterator(); + appIdIt; + ++appIdIt) { + // Do not expect another nested StatContext within appId + BSLS_ASSERT_SAFE(0 == appIdIt->numSubcontexts()); + + populateQueueStats( + &appIdsObject[appIdIt->name()].makeObject(), + *appIdIt); + } + } + } + } + + inline static void populateAllDomainsStats(bdljsn::JsonObject* parent, + const mwcst::StatContext& ctx) + { + // PRECONDITIONS + BSLS_ASSERT_SAFE(parent); + + bdljsn::JsonObject& nodes = (*parent)["domains"].makeObject(); + for (mwcst::StatContextIterator domainIt = ctx.subcontextIterator(); + domainIt; + ++domainIt) { + populateOneDomainStats(&nodes[domainIt->name()].makeObject(), + *domainIt); + } + } +}; + +} // close unnamed namespace + +// ---------------------------------- +// class JsonPrinter::JsonPrinterImpl +// ---------------------------------- /// The implementation class for JsonPrinter, containing all the cached options /// for printing statistics as JSON. This implementation exists and is hidden @@ -45,7 +148,7 @@ namespace { /// - Don't want to expose `bdljsn` names and symbols to the outer scope. /// - Member fields and functions defined for this implementation are used only /// locally, so there is no reason to make it visible. -class JsonPrinterImpl { +class JsonPrinter::JsonPrinterImpl { private: // CLASS-SCOPE CATEGORY BALL_LOG_SET_CLASS_CATEGORY("MQBSTAT.JSONPRINTERIMPL"); @@ -71,21 +174,6 @@ class JsonPrinterImpl { JsonPrinterImpl& operator=(const JsonPrinterImpl& other) BSLS_CPP11_DELETED; - // ACCESSORS - - /// "domainQueues" stat context: - /// Populate the specified `bdljsn::JsonObject*` with the values - /// from the specified `ctx`. - static void populateAllDomainsStats(bdljsn::JsonObject* parent, - const mwcst::StatContext& ctx); - static void populateOneDomainStats(bdljsn::JsonObject* domainObject, - const mwcst::StatContext& ctx); - static void populateQueueStats(bdljsn::JsonObject* queueObject, - const mwcst::StatContext& ctx); - static void populateMetric(bdljsn::JsonObject* metricsObject, - const mwcst::StatContext& ctx, - mqbstat::QueueStatsDomain::Stat::Enum metric); - public: // CREATORS @@ -105,8 +193,9 @@ class JsonPrinterImpl { int printStats(bsl::string* out, bool compact) const; }; -inline JsonPrinterImpl::JsonPrinterImpl(const StatContextsMap& statContextsMap, - bslma::Allocator* allocator) +inline JsonPrinter::JsonPrinterImpl::JsonPrinterImpl( + const StatContextsMap& statContextsMap, + bslma::Allocator* allocator) : d_opsCompact(bdljsn::WriteOptions().setSpacesPerLevel(0).setStyle( bdljsn::WriteStyle::e_COMPACT)) , d_opsPretty(bdljsn::WriteOptions().setSpacesPerLevel(4).setStyle( @@ -116,101 +205,8 @@ inline JsonPrinterImpl::JsonPrinterImpl(const StatContextsMap& statContextsMap, // NOTHING } -inline void -JsonPrinterImpl::populateMetric(bdljsn::JsonObject* metricsObject, - const mwcst::StatContext& ctx, - mqbstat::QueueStatsDomain::Stat::Enum metric) -{ - // PRECONDITIONS - BSLS_ASSERT_SAFE(metricsObject); - - const bsls::Types::Int64 value = - mqbstat::QueueStatsDomain::getValue(ctx, -1, metric); - - (*metricsObject)[mqbstat::QueueStatsDomain::Stat::toString(metric)] - .makeNumber() = value; -} - -inline void -JsonPrinterImpl::populateQueueStats(bdljsn::JsonObject* queueObject, - const mwcst::StatContext& ctx) -{ - // PRECONDITIONS - BSLS_ASSERT_SAFE(queueObject); - - if (ctx.numValues() == 0) { - // Prefer to omit an empty "values" object - return; // RETURN - } - - bdljsn::JsonObject& values = (*queueObject)["values"].makeObject(); - - typedef mqbstat::QueueStatsDomain::Stat Stat; - - populateMetric(&values, ctx, Stat::e_NB_PRODUCER); - populateMetric(&values, ctx, Stat::e_NB_CONSUMER); - populateMetric(&values, ctx, Stat::e_PUT_MESSAGES_DELTA); - populateMetric(&values, ctx, Stat::e_PUT_BYTES_DELTA); - populateMetric(&values, ctx, Stat::e_PUSH_MESSAGES_DELTA); - populateMetric(&values, ctx, Stat::e_PUSH_BYTES_DELTA); - populateMetric(&values, ctx, Stat::e_ACK_DELTA); - populateMetric(&values, ctx, Stat::e_ACK_TIME_AVG); - populateMetric(&values, ctx, Stat::e_ACK_TIME_MAX); - populateMetric(&values, ctx, Stat::e_NACK_DELTA); - populateMetric(&values, ctx, Stat::e_CONFIRM_DELTA); - populateMetric(&values, ctx, Stat::e_CONFIRM_TIME_AVG); - populateMetric(&values, ctx, Stat::e_CONFIRM_TIME_MAX); -} - -inline void -JsonPrinterImpl::populateOneDomainStats(bdljsn::JsonObject* domainObject, - const mwcst::StatContext& ctx) -{ - // PRECONDITIONS - BSLS_ASSERT_SAFE(domainObject); - - for (mwcst::StatContextIterator queueIt = ctx.subcontextIterator(); - queueIt; - ++queueIt) { - bdljsn::JsonObject& queueObj = - (*domainObject)[queueIt->name()].makeObject(); - populateQueueStats(&queueObj, *queueIt); - - if (queueIt->numSubcontexts() > 0) { - bdljsn::JsonObject& appIdsObject = queueObj["appIds"].makeObject(); - - // Add metrics per appId, if any - for (mwcst::StatContextIterator appIdIt = - queueIt->subcontextIterator(); - appIdIt; - ++appIdIt) { - // Do not expect another nested StatContext within appId - BSLS_ASSERT_SAFE(0 == appIdIt->numSubcontexts()); - - populateQueueStats(&appIdsObject[appIdIt->name()].makeObject(), - *appIdIt); - } - } - } -} - -inline void -JsonPrinterImpl::populateAllDomainsStats(bdljsn::JsonObject* parent, - const mwcst::StatContext& ctx) -{ - // PRECONDITIONS - BSLS_ASSERT_SAFE(parent); - - bdljsn::JsonObject& nodes = (*parent)["domains"].makeObject(); - for (mwcst::StatContextIterator domainIt = ctx.subcontextIterator(); - domainIt; - ++domainIt) { - populateOneDomainStats(&nodes[domainIt->name()].makeObject(), - *domainIt); - } -} - -inline int JsonPrinterImpl::printStats(bsl::string* out, bool compact) const +inline int JsonPrinter::JsonPrinterImpl::printStats(bsl::string* out, + bool compact) const { // executed by *StatController scheduler* thread @@ -225,7 +221,7 @@ inline int JsonPrinterImpl::printStats(bsl::string* out, bool compact) const *d_contexts.find("domainQueues")->second; bdljsn::JsonObject& domainQueuesObj = obj["domainQueues"].makeObject(); - populateAllDomainsStats(&domainQueuesObj, ctx); + ConversionUtils::populateAllDomainsStats(&domainQueuesObj, ctx); } const bdljsn::WriteOptions& ops = compact ? d_opsCompact : d_opsPretty; @@ -240,8 +236,6 @@ inline int JsonPrinterImpl::printStats(bsl::string* out, bool compact) const return 0; } -} // close unnamed namespace - // ----------------- // class JsonPrinter // ----------------- diff --git a/src/groups/mqb/mqbstat/mqbstat_jsonprinter.h b/src/groups/mqb/mqbstat/mqbstat_jsonprinter.h index 0089eee51c..2d7a56715b 100644 --- a/src/groups/mqb/mqbstat/mqbstat_jsonprinter.h +++ b/src/groups/mqb/mqbstat/mqbstat_jsonprinter.h @@ -39,17 +39,16 @@ namespace BloombergLP { namespace mqbstat { -// FORWARD DECLARATIONS -namespace { -class JsonPrinterImpl; -} // close unnamed namespace - // ================= // class JsonPrinter // ================= class JsonPrinter { private: + // PRIVATE TYPES + /// Forward declaration of the printer implementation type. + class JsonPrinterImpl; + // DATA /// Managed pointer to the printer implementation. bslma::ManagedPtr d_impl_mp;