|
BDE 4.14.0 Production release
|
Provide a manager for recording and publishing metric data.
This component provides a balm::MetricsManager class for managing the recording and publishing of metric data. The metrics manager retrieves balm::MetricRecords from both the collector repository it owns as well as any RecordsCollectionCallbacks registered with it. The metrics manager also provides methods to register balm::Publisher objects. The publish method collects metrics for a category (or set of categories) and then sends the collected metrics to the publishers associated with that category (or set of categories).
Note that a metric in this context is an event associated with a measured value. This component does not define what constitutes an event or what the associated value represents. A collected metric contains the count of event occurrences along with the total, minimum, and maximum aggregates of the measured values.
Bloomberg software may alternatively use the GUTS telemetry API, which is integrated into Bloomberg infrastructure.
balm::MetricsManager is fully thread-safe, meaning that all non-creator operations on a given instance can be safely invoked simultaneously from multiple threads. To avoid synchronization problems with user functions invoked by balm::MetricsManager, special consideration must be taken when implementing these functions as specified below.
Concrete implementations of the balm::Publisher protocol (pure abstract base-class) registered with a balm::MetricsManager object must not call (either directly or indirectly) the publish method on the balm::MetricsManager object with which they are registered.
Implementations of balm::MetricsManager::RecordsCollectionCallback registered with a balm::MetricsManager will be invoked by a function holding mutex locks that provide synchronized access to data in that balm::MetricsManager. Therefore registered implementations of RecordsCollectionCallback must not make any re-entrant calls (either directly or indirectly) to member functions of the balm::MetricManager object with which they are registered.
This section illustrates intended use of this component.
This example demonstrates how to create and configure a balm::MetricsManager that we will use to record and publish metric values. We first create a balm::MetricsManager object and a SimpleStreamPublisher object. Note that SimpleStreamPublisher is an example implementation of the balm::Publisher protocol defined in the balm_publisher component. In practice, clients typically use a standard publisher class (e.g., balm::StreamPublisher).
This second example demonstrates using balm::Collector objects (obtained from a metrics manager's collector repository) to collect metrics related to a hypothetical EventHandler class. On construction, the event handler obtains references to balm::Collector objects from the metrics manager's collector repository. On each handled event, the EventHandler, updates its collectors with the appropriate metric values.
Note that the balm_metric component provides both classes and macros to reduce the code required for collecting metric values.
We obtain the addresses of the respective balm::Collector objects that we will use to collect metrics values from the metrics managers' collector repository. Note that, in practice, clients can use the balm::DefaultMetricManager (see balm_defaultmetricsmanager and balm_metric ) rather than explicitly pass the address of a metrics manager.
Then, when processing an "event", we update the balm::Collector objects with the appropriate metric values for the event.
The metrics manager provides a facility to register a callback that will report metric values. A callback should be used if clients want to customize how a metric, or group of metrics, are recorded. In the following example, the EventHandlerWithCallback class maintains a metric for the average number of events per second that it reports through a balm::MetricsManager::MetricsCollectionCallback.
In the implementation of EventHandlerWithCallback below, we ensure that the callback is registered on construction and removed before the object is destroyed.
The callback creates metric records and populates them with data collected by the event handler.
In the constructor, we initialize a metric id from the specified manager object's metric registry. We will also register the collection callback (collectMetricsCb) with the supplied manager.
We now register the callback function collectMetricsCb with the metrics manager. We use bdlf::BindUtil to bind the member function to a bsl::function matching the balm::MetricsManager::RecordsCollectionCallback function prototype. The private data member d_callbackHandle is used to store the balm::MetricsManager::CallbackHandle returned for the registered callback; we will use this handle later to remove the callback from the metrics manager.
In the destructor we use the balm::MetricsManager::CallbackHandle, stored in d_callbackHandle, to remove the callback from the metrics manager. This prevents the metrics manager from invoking the callback method on an object that has already been destroyed.
We increment the atomic integer d_numEvents to keep track of the number events handled by the handleEvent method. If collecting a metric is expensive (e.g., metrics requiring a system call to collect), clients should test whether the metric is enabled before performing the collection operation.
The metrics manager provides a publish operation to publish metrics for a category or set of categories. In this example we will use the metrics manager's publishAll operation to publish all the metrics managed by the metrics manager. We will record metrics for "MyCategory" using instances of the EventHandler and EventHandlerWithCallback classes (defined above). This example assumes that an instance, manager, of the balm::MetricsManager class has been initialized as in example 1. Note that, in practice the publish operation is normally tied to a scheduling mechanism (e.g., see balm_publicationscheduler ).
Executing the example should result in two samples being published to standard output. Each sample should contain 3 metrics belonging to the metric category "MyCategory". The metric "eventsPerSecond" is collected by the EventHandlerWithCallback, while "messageSizes", and "eventFailures" (both collected by EventHandler).