Skip to content

Commit

Permalink
Update MetricRegistry to avoid singleton lifetime issues (DRQS 174980…
Browse files Browse the repository at this point in the history
…848) (#4707)

* Update MetricRegistry to avoid singleton lifetime issues
  • Loading branch information
Victor Dyachenko authored and GitHub Enterprise committed May 8, 2024
1 parent c3b937e commit e5ec57f
Show file tree
Hide file tree
Showing 16 changed files with 842 additions and 761 deletions.
522 changes: 481 additions & 41 deletions groups/bdl/bdlm/bdlm_metricsregistry.cpp

Large diffs are not rendered by default.

479 changes: 190 additions & 289 deletions groups/bdl/bdlm/bdlm_metricsregistry.h

Large diffs are not rendered by default.

99 changes: 69 additions & 30 deletions groups/bdl/bdlm/bdlm_metricsregistry.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <bdlm_metricdescriptor.h>

#include <bdlf_bind.h>

#include <bsla_maybeunused.h>

#include <bslim_testutil.h>
Expand Down Expand Up @@ -244,20 +246,61 @@ bool TestMetricsAdapter::verify(const bdlm::MetricDescriptor& descriptor) const
// This section illustrates intended use of this component.
//
///Example 1: Using 'bdlm::MetricsRegistry'
///- - - - - - - - - - - - - - - - - - - - - - -
///- - - - - - - - - - - - - - - - - - - -
// This example demonstrates the initialization and usage of the
// 'bdlm::MetricsRegistry' object, allowing for registering metric callback
// functions with the 'bdlm' monitoring system.
//
// First, we provide a metric function to be used during callback registration
// with the 'bdlm' monitoring system:
// First, we declare a class that provides some metric for the 'bdlm'
// monitoring system:
//..
class LowLevelFacility {
// PRIVATE DATA
bdlm::MetricsRegistryRegistrationHandle d_metricHandle;
public:
// CREATORS
explicit LowLevelFacility(bdlm::MetricsRegistry& metricsRegistry =
bdlm::MetricsRegistry::defaultInstance());

// ACCESSORS
int someMetric() const
{
return 0; // just a stub
}
};
//..
// Next, we provide a metric function to be used during callback registration:
//..
void metricCallback(bdlm::Metric *value, const LowLevelFacility *object)
{
*value = bdlm::Metric::Gauge(object->someMetric());
}
//..
// Here is the constructor definition that registers the collection callback:
//..
void elidedMetric(BloombergLP::bdlm::Metric *value)
LowLevelFacility::LowLevelFacility(bdlm::MetricsRegistry& metricsRegistry)
{
(void)value;
// ...
// Construct a 'bdlm::MetricsDescriptor' object to be used when
// registering the callback function:
bdlm::MetricDescriptor descriptor("bdlm",
"example",
1,
"bdlmmetricsregistry",
"bmr",
"identifier");

// Register the collection callback:
metricsRegistry.registerCollectionCallback(
&d_metricHandle,
descriptor,
bdlf::BindUtil::bind(&metricCallback,
bdlf::PlaceHolders::_1,
this));
ASSERT(d_metricHandle.isRegistered());
}
//..
// Notice that the compiler-supplied destructor is sufficient because the
// 'd_metricHandle' will deregister the metric on destruction.

// ============================================================================
// MAIN PROGRAM
Expand Down Expand Up @@ -327,8 +370,8 @@ int main(int argc, char *argv[])

typedef bsl::function<void(BloombergLP::bdlm::Metric*)> Callback;
Callback fn(bsl::allocator_arg, &oa, LargeCallback());
BloombergLP::bdlm::MetricsRegistryRegistrationHandle handle =
mX.registerCollectionCallback(md, fn);
BloombergLP::bdlm::MetricsRegistryRegistrationHandle handle;
mX.registerCollectionCallback(&handle, md, fn);

ASSERTV(da.numBytesInUse(),
da.numBlocksInUse(),
Expand Down Expand Up @@ -357,31 +400,27 @@ int main(int argc, char *argv[])
<< "USAGE EXAMPLE" << endl
<< "=============" << endl;

// Then, we construct a 'bdlm::MetricsDescriptor' object to be used when
// registering the callback function:
//..
bdlm::MetricDescriptor descriptor("bdlm",
"example",
1,
"bdlmmetricsregistry",
"bmr",
"identifier");
// Now, we construct a 'bdlm::MetricsRegistry' object with a test allocator:
//..
// Next, we construct a 'bdlm::MetricsRegistry' object with a test allocator:
bslma::TestAllocator ta;
bdlm::MetricsRegistry registry(&ta);
ASSERT(registry.numRegisteredCollectionCallbacks() == 0);
//..
bslma::TestAllocator ta;
bdlm::MetricsRegistry registry(&ta);
// Then, we create the object and pass the constructed 'bdlm::MetricsRegistry'
// object there:
//..
// Now, we register the collection callback:
//..
bdlm::MetricsRegistryRegistrationHandle handle =
registry.registerCollectionCallback(descriptor,
&elidedMetric);
{
LowLevelFacility facility(registry);
ASSERT(registry.numRegisteredCollectionCallbacks() == 1);
//..
// Finally, we remove the callback from the monitoring system, and verify the
// callback was successfully removed:
// If we don't provide a 'bdlm::MetricsRegistry' object explicitly, the default
// global instance will be used.
//
// Finally, the callback is removed the monitoring system by the destructor of
// 'facility' object:
//..
ASSERT(0 == handle.unregister());
} // 'facility.d_metricHandle.unregister()' is called here
ASSERT(registry.numRegisteredCollectionCallbacks() == 0);
//..
} break;
case 1: {
Expand Down Expand Up @@ -413,8 +452,8 @@ int main(int argc, char *argv[])

ASSERT(0 == adapter.size());

ObjHandle handle = mX.registerCollectionCallback(descriptor,
&testMetric);
ObjHandle handle;
mX.registerCollectionCallback(&handle, descriptor, &testMetric);

ASSERT(0 == adapter.size());

Expand Down
20 changes: 16 additions & 4 deletions groups/bdl/bdlm/doc/bdlm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@

@MNEMONIC: Basic Development Library Metrics (bdlm)

@DESCRIPTION: The 'bdlm' package provides a metrics registrar protocol (i.e., a
pure abstract interface). In addition, 'bdlm' also provides a singleton
"default metrics registry" that will then be visible to all BDE and
BDE-compliant code throughout that process.
@DESCRIPTION: The 'bdlm' package provides a means for low-level library
software to collect and publish metrics through a metric publishing framework,
without a library depending on the metrics publishing framework. The 'bdlm'
package provides a protocol (i.e., a pure abstract interface),
'bdlm::MetricsAdapter', that can be implemented for (higher level) metrics
facilities. In addition, it also provides a registry of metrics,
'bdlm::MetricRegistry', that allows low-level users of 'bdlm' to register
metrics at any time, serving as an intermediary with concrete
'bdlm::MetricsAdapter' implementations (which may be configured before or
after the creation of any particular metric).

As a low-level metrics facility, this package does not directly manage
schedulers to collect metrics values or publishers to publish collected
values. Instead it is designed to allow applications to plug in different
high-level feature-rich metrics collection and publication frameworks (without
requiring a library dependency on those frameworks).

/Hierarchical Synopsis
/---------------------
Expand Down
Loading

0 comments on commit e5ec57f

Please sign in to comment.