BDE 4.14.0 Production release
Loading...
Searching...
No Matches
Package balm

Modules

 balm_bdlmmetricsadapter
 Provide a concrete instance of the bdlm metrics adapter.
 
 balm_category
 Provide a representation of a metric category.
 
 balm_collector
 Provide a container for collecting and aggregating metric values.
 
 balm_collectorrepository
 Provide a repository for collectors.
 
 balm_configurationutil
 Provide a namespace for metrics configuration utilities.
 
 balm_defaultmetricsmanager
 Provide for a default instance of the metrics manager.
 
 balm_integercollector
 Provide a container for collecting integral metric values.
 
 balm_integermetric
 Provide helper classes for recording int metric values.
 
 balm_metric
 Provide helper classes for recording metric values.
 
 balm_metricdescription
 Provide a description for a metric.
 
 balm_metricformat
 Provide a formatting specification for a metric.
 
 balm_metricid
 Provide an identifier for a metric.
 
 balm_metricrecord
 Provide an aggregated record of the value of a metric.
 
 balm_metricregistry
 Provide a registry for metrics.
 
 balm_metrics
 Provide a suite of operations for recording metric values.
 
 balm_metricsample
 Provide a container for a sample of collected metric records.
 
 balm_metricsmanager
 Provide a manager for recording and publishing metric data.
 
 balm_publicationscheduler
 Provide a scheduler for publishing metrics.
 
 balm_publicationtype
 Provide an enumeration of aggregate types used to publish metrics.
 
 balm_publisher
 Provide a protocol to publish recorded metric values.
 
 balm_stopwatchscopedguard
 Provide a scoped guard for recording elapsed time.
 
 balm_streampublisher
 Provide a balm::Publisher implementation that writes to a stream.
 

Detailed Description

Purpose

Provide thread-safe collection and publishing of metrics.

Mnemonic

Basic Application Library Metrics (balm)

Description

The 'balm' package provides facilities for recording and publishing metric data.

Bloomberg internal software should also consider the GUTS telemetry API, which is integrated into Bloomberg infrastructure.

A "metric", in the context of this package, is a measured event. This package does not define what constitutes an event or what the associated measurement represents. For example, a metric could record the elapsed time of a function call (in which case the event is the function call, and the measured value is the elapsed time), or a metric could record the number of requests received by a service (in which case the event is the reception of a request, and the measured value is 1).

This package provides components for collecting and aggregating measurement values (see balm_metric and balm_metrics ). Those aggregated metric measurements are described by a metric record (see balm_metricrecord ), which contains the identifier for the recorded metric, the number of times the event occurred, as well as the minimum, maximum, and total of the measured values. This package provides a protocol for publishing metric records (see balm_publisher ) and an implementation of that protocol for publishing records to a stream (see 'balm_streampublisher). Finally this package provides a balm_metricsmanager component to coordinate the collection and publication of metrics.

Hierarchical Synopsis

The 'balm' package currently has 22 components having 13 levels of physical dependency. The list below shows the hierarchical ordering of the components. The order of components within each level is not architecturally significant, just alphabetical.

13. balm_configurationutil
12. balm_metrics
11. balm_stopwatchscopedguard
10. balm_bdlmmetricsadapter
balm_integermetric
balm_metric
9. balm_defaultmetricsmanager
balm_publicationscheduler
8. balm_metricsmanager
balm_streampublisher
7. balm_collectorrepository
balm_publisher
6. balm_collector
balm_integercollector
balm_metricsample
5. balm_metricrecord
balm_metricregistry
4. balm_metricid
3. balm_metricdescription
2. balm_metricformat
1. balm_category
balm_publicationtype

Component Synopsis

balm_bdlmmetricsadapter : Provide a concrete instance of the bdlm metrics adapter.

balm_category : Provide a representation of a metric category.

balm_collector : Provide a container for collecting and aggregating metric values.

balm_collectorrepository : Provide a repository for collectors.

balm_configurationutil : Provide a namespace for metrics configuration utilities.

balm_defaultmetricsmanager : Provide for a default instance of the metrics manager.

balm_integercollector : Provide a container for collecting integral metric values.

balm_integermetric : Provide helper classes for recording int metric values.

balm_metric : Provide helper classes for recording metric values.

balm_metricdescription : Provide a description for a metric.

balm_metricformat : Provide a formatting specification for a metric.

balm_metricid : Provide an identifier for a metric.

balm_metricrecord : Provide an aggregated record of the value of a metric.

balm_metricregistry : Provide a registry for metrics.

balm_metrics : Provide a suite of operations for recording metric values.

balm_metricsample : Provide a container for a sample of collected metric records.

balm_metricsmanager : Provide a manager for recording and publishing metric data.

balm_publicationscheduler : Provide a scheduler for publishing metrics.

balm_publicationtype : Provide an enumeration of aggregate types used to publish metrics.

balm_publisher : Provide a protocol to publish recorded metric values.

balm_stopwatchscopedguard : Provide a scoped guard for recording elapsed time.

balm_streampublisher : Provide a balm::Publisher implementation that writes to a stream.

Getting Started

The following section presents a simple example of collecting metrics. We create a trivial application that reads lines of text from standard input and counts the number of letters, words, and unique words in each line. The function 'processLine()' processes each line of text and records metrics for the number of times 'processLine()' has been called, the elapsed time for the calls to 'processLine()', the total character count, and the total word count.

Before we can collect metrics we must first create a 'balm_MetricsManager' object to manage their collection (and publication). We use the 'balm_DefaultMetricsManager', which is a singleton instance of the 'balm_MetricsManager' class. The default metrics manager is used by the collection macros that we will use to collect metrics (see balm_metrics ). Note that the default metrics manager is intended to be created and destroyed by the owner of 'main'. A default metrics manager instance should be created during the initialization of an application (while the task has a single thread) and destroyed just prior to termination (when there is, similarly, a single thread).

int main(int argc, const char *argv[])
{

We create a 'balm_DefaultMetricsManagerScopedGuard', which manages the lifetime of the default metrics manager (singleton) instance. At construction, we provide the scoped guard an output stream ('stdout') to which the balm_publisher (created by the default metrics manager) will publish metrics.

balm_DefaultMetricsManagerScopedGuard managerGuard(bdl::cout);

We create a 'balm_PublicationScheduler' to periodically publish the metrics we have collected. A 'balm_PublicationScheduler' invokes 'publish()' on the supplied 'balm_MetricsManager' object according to the provided schedule.

bcep_TimerEventScheduler eventScheduler;
balm_PublicationScheduler publicationScheduler(
balm_DefaultMetricsManager::instance(),
&eventScheduler);

To begin periodically publishing metrics we 'start' the event scheduler supplied to the 'balm_PublicationScheduler', and then set a simple schedule to publish all collected metrics every 30 seconds.

eventScheduler.start();
publicationScheduler.setDefaultSchedule(bsls::TimeInterval(30, 0));
Definition bsls_timeinterval.h:301

Finally we have our main "application" loop, which reads lines of text from the standard input (until "exit" is provided as input) and calls 'processLine()' for each line of input.

while (true) {
enum { BUFFER_SIZE = 1024 };
char buffer[BUFFER_SIZE];
if (!bdl::cin.getline(buffer, BUFFER_SIZE)) {
break;
}
if (0 == bdl::strcmp(buffer, "exit")) {
break;
}
processLine(buffer);
}

At the end of this lexical scope 'managerGuard' is destroyed, releasing the default 'balm_MetricsManager' instance.

}

Next we define the 'processLine()' function. The 'processLine()' function "processes" a line of text, and collects several metrics related to the function invocation.

void processLine(const bdl::string& line)
// Process the specified 'line' of text and write to standard output the
// number of characters, words, and unique words in 'line'.
{

Increment the count of the number of calls to 'processLine()' and use the 'BALM_METRICS_TIME_BLOCK' macro (see balm_metrics ) to collect the elapsed time of this function call. Note that all the metrics recorded by this function belong to the (arbitrarily chosen) category "Example".

BALM_METRICS_INCREMENT("Example", "processLineCount");
"processLineElapsedTime",
balm_StopwatchScopedGuard::BALM_SECONDS);
int wordCount = 0;
bdl::set<bdl::string> words;
bdl::string word;
bdl::istringstream istream(line);
while (istream >> word) {
words.insert(word);
++wordCount;
}
bdl::cout << "Characters: count: " << line.size()
<< "\tWord count: " << wordCount
<< "\tUnique word count: " << words.size() << bdl::endl;
#define BALM_METRICS_INCREMENT(CATEGORY, METRIC)
Definition balm_metrics.h:1033
#define BALM_METRICS_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS)
Definition balm_metrics.h:1046

Once we've "processed" the 'line', update the character count and word count metrics.

BALM_METRICS_UPDATE("Example", "characterCount", line.size());
BALM_METRICS_UPDATE("Example", "wordCount", wordCount);
}
#define BALM_METRICS_UPDATE(CATEGORY, METRIC1, VALUE1)
Definition balm_metrics.h:575

We've now created our example application. A typical session with this application might look like (note that '>' indicates user input):

>this contains 4 words
Characters: count: 21 Word count: 4 Unique word count: 4
>this sentence contains 5 words
Characters: count: 30 Word count: 5 Unique word count: 5

Every 30 seconds metrics will be reported to standard output. A typical publication of metrics would look like:

17FEB2009_15:29:20.792+0000 4 Records
Elapsed Time: 30.0092s
Example.processLineCount [ count = 2, total = 2, min = 1, max = 1 ]
Example.processLineElapsedTime [ count = 2, total = 0.0007656,
min = 0.00022736, max = 0.00053824 ]
Example.characterCount [ count = 2, total = 51, min = 21, max = 30 ]
Example.wordCount [ count = 2, total = 9, min = 4, max = 5 ]

Features Overview

This section provides a brief summary of the features of the 'balm' package - details can be found in the indicated components and later in this document.

Multi-Threading

The components provided by the 'balm' package were designed for use in multi-threaded applications. Metrics can be safely collected and published simultaneously from multiple threads. Nevertheless, not every individual component in the 'balm' package is thread-safe. See the individual component documentation for more information.

Collecting Metrics

The 'balm' package defines several ways to collect metrics, as well as allowing users to define their own collection mechanisms.

Choosing Between @ref balm_metric and @ref balm_integermetric

The balm_metric and balm_integermetric components both define macros and helper classes for recording metrics. The mechanisms in balm_integermetric are slightly more efficient for collecting integral metric values, but are otherwise identical.

Choosing Between Metric Collection Macros and Metric Collection Classes

The macros and classes defined by the balm_metric , balm_integermetric and balm_metrics components provide the same basic functionality. Clients may find the 'balm_Metric' or 'balm_IntegerMetric' classes better suited to collecting metrics associated with a particular instance of a stateful object, while the 'BALM_METRICS_*' macros are better suited to collecting metrics associated with a particular code path (rather than an object instance). In most instances, however, choosing between the two is a matter of taste.

Creating a User Defined Collection Mechanism

The 'balm' package allows users to define their own metric collection mechanisms by registering a callback with a 'balm_MetricsManager' object. User defined callbacks must match the 'balm_MetricsManager::MetricsCollectionCallback' function signature and collect metrics for a single category. Every time 'publish' is invoked for a category, the metrics manager will invoke the registered collection callbacks for that category, and publish the collected metrics. See balm_metricsmanager for more information.

Publishing Metrics

The balm_publisher component defines a protocol for publishing metric records. Users can register publisher objects with a metrics manager. Invoking 'publish()' on a metrics manager will collect metrics for the set of categories supplied with the function call, and then publish the metrics for each supplied category to publishers registered for that category.

The 'balm_StreamPublisher' class implements the 'balm_Publisher' protocol to provide a default publisher for publishing metrics to a stream.

Periodically Publishing Metrics

Users can schedule the periodic publication of metrics using the balm_publicationscheduler component. In the example presented above, under "Getting Started", a 'balm_PublicationScheduler' object was configured to publish all categories of metrics metrics every 30 seconds.

At construction, a 'balm_PublicationScheduler' object is provided the addresses of a 'balm_MetricsManager' and a 'bcep_TimerEventScheduler'. Users can call 'scheduleCategory()' to schedule an individual metric category to be published repeatedly at a given interval, or call 'setDefaultSchedule()' to schedule the publication of any category not given an individual schedule. At the end of a scheduled time interval, the publication scheduler invokes the metrics manager's 'publish()' operation with the set of categories to publish. Note that, the publication scheduler will combine categories that occur at the same frequency into a single invocation of the metrics manager's 'publish' operation.

Disabling Metric Categories

Users can disable (and re-enable) a category of metrics by calling 'balm_MetricsManager::setCategoryEnabled' method. A disabled category will not be published by the metrics manager. In addition, the balm_metric , balm_integermetric , balm_metrics , and balm_stopwatchscopedguard components will not collect metrics for disabled categories (minimizing the performance cost of collecting metric for disabled categories). Note that when 'balm_MetricsManager::publish()' is called on a disabled category, the metrics manager will invoke any user defined collection callbacks registered for the disable category, but will not publish the collected metrics. Users defining their own metrics collection mechanism (using a 'balm_MetricsManager::MetricsCollectionCallback') must (manually) test whether a category is disabled if they wish to avoid collecting metrics for a disabled category.