Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component balm_configurationutil
[Package balm]

Provide a namespace for metrics configuration utilities. More...

Namespaces

namespace  balm

Detailed Description

Outline
Purpose:
Provide a namespace for metrics configuration utilities.
Classes:
balm::ConfigurationUtil namespace for metrics configuration utilities
See also:
Component balm_metricsmanager, Component balm_defaultmetricsmanager
Description:
This component provides a set of utility functions for configuring metrics. The balm::ConfigurationUtil struct provides short-cuts for common configuration operations that are performed on other components in the balm package.
Alternative Systems for Telemetry:
Bloomberg software may alternatively use the GUTS telemetry API, which is integrated into Bloomberg infrastructure.
Thread Safety:
balm::ConfigurationUtil is fully thread-safe, meaning that all the methods can be safely invoked simultaneously from multiple threads.
Usage:
The following examples demonstrate how to use balm::ConfigurationUtil.
Configuring the Output of a Metric:
This example uses balm::ConfigurationUtil to configure the output for a metric.
We start by initializing a default metrics manager by creating a balm::DefaultMetricsManagerScopedGuard, which manages the lifetime of the default metrics manager object. At construction, we provide the scoped guard an output stream (stdout) to which the default metrics manager will publish metrics. Note that the default metrics manager is intended to be created and destroyed by the owner of main. A metrics manager 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, char *argv[])
  {
      // ...

      balm::DefaultMetricsManagerScopedGuard managerGuard(bsl::cout);
Next we create a metric, "avgElapsedTimeMs", that will output the average time, in milliseconds, spent in a section of code. We set the preferred publication type for the metric to be average: Next, because we will record the elapsed time in seconds, we configure a format to scale the elapsed time by 1000.0:
     balm::ConfigurationUtil::setFormatSpec(
                                   "myCategory",
                                   "avgElapsedTimeMs",
                                   balm::PublicationType::e_AVG,
                                   balm::MetricFormatSpec(1000.0, "%.2f ms");
We now collect an example value of .005:
     BALM_METRIC_UPDATE("myCategory", "avgElapsedTimeMs", .005);
Finally, we publish the metric. Note that in practice, clients of the balm package can use the balm::PublicationScheduler to schedule the periodic publication of metrics: The output for the publication will look like:
  06AUG2009_20:27:51.982+0000 1 Records
          Elapsed Time: 0.000816s
                  myCategory.avgElapsedTimeMs[ avg (total/count) = 5.00 ms ]
Using a Metric's User Data:
In the following example we configure, using balm::ConfigurationUtil, application-specific publication thresholds for a series of metrics. We will create an application-specific publisher that will use the configured thresholds to determine whether a metric should be written to the console. For simplicity, the metric thresholds in this example will be a single unsigned integer value that will be compared with the metric's total.
We start by defining an application-specific publisher implementation. This implementation is supplied a user data key on construction, which it uses to look up the threshold for a particular metric. If a metric's total value is greater than its threshold, it will log the metric to the console.
  // thresholdpublisher.h
  class ThresholdPublisher : public balm::Publisher {
      // A simple implementation of the 'balm::Publisher' protocol that
      // writes metric records to the console when their value is greater
      // than an application-specific threshold.

      // DATA
      balm::MetricDescription::UserDataKey d_thresholdKey;  // key for a
                                                            // metric's
                                                            // threshold

      // NOT IMPLEMENTED
      ThresholdPublisher(const ThresholdPublisher&);
      ThresholdPublisher& operator=(const ThresholdPublisher&);

    public:
      // CREATORS
      ThresholdPublisher(balm::MetricDescription::UserDataKey thresholdKey);
          // Create a publisher that will publish metrics to the console if
          // their total value is greater than their associated threshold,
          // accessed via the specified 'thresholdKey'.

      virtual ~ThresholdPublisher();
           // Destroy this publisher.

      // MANIPULATORS
      virtual void publish(const balm::MetricSample& metricValues);
          // Publish the specified 'metricValues' to the console if they are
          // greater than their associated threshold.
  };

  // thresholdpublisher.cpp

  // CREATORS
  ThresholdPublisher::ThresholdPublisher(
                           balm::MetricDescription::UserDataKey thresholdKey)
  : d_thresholdKey(thresholdKey)
  {
  }

  ThresholdPublisher::~ThresholdPublisher()
  {
  }

  // MANIPULATORS
  void ThresholdPublisher::publish(const balm::MetricSample& metricValues)
  {
      if (0 >= metricValues.numRecords()) {
          return;                                                   // RETURN
      }
      balm::MetricSample::const_iterator sIt = metricValues.begin();
      for (; sIt != metricValues.end(); ++sIt) {
          balm::MetricSampleGroup::const_iterator gIt = sIt->begin();
          for (; gIt != sIt->end(); ++gIt) {
We now use the user data key to lookup the address of the threshold value. If this address is 0, no threshold is specified for the metric.
              const balm::MetricDescription& description =
                                              *gIt->metricId().description();
              unsigned int *thresholdPtr =
                       (unsigned int *)description.userData(d_thresholdKey);
              if (thresholdPtr && gIt->total() > *thresholdPtr) {
                  bsl::cout << "WARNING: " << gIt->metricId()
                            << " = "       << gIt->total()
                            << bsl::endl;
              }
          }
      }
  }
Now we examine how to configure a metrics manager with a ThresholdPublisher, and set the thresholds for a couple of metrics. We start by defining a couple of threshold constants for our metrics:
  static const unsigned int ELAPSED_TIME_THRESHOLD = 10;
  static const unsigned int NUM_REQUESTS_THRESHOLD = 100;
Now, we configure a default metrics manager and publish a couple of example metrics. We start by initializing a default metrics manager by creating a balm::DefaultMetricsManagerScopedGuard, which manages the lifetime of the default metrics manager:
  int main(int argc, char *argv[])
  {
      // ...
      bslma::Allocator *allocator = bslma::Default::allocator(0);
      balm::DefaultMetricsManagerScopedGuard managerGuard;
Now we create a user data key for our threshold information: Next we create an object of our application-specific publisher type, ThresholdPublisher, and configure the default metrics manager to publish metrics using this publisher:
      bsl::shared_ptr<balm::Publisher> publisher(
            new (*allocator) ThresholdPublisher(thresholdKey),
            allocator);
     balm::DefaultMetricsManager::instance()->addGeneralPublisher(publisher);
Next we configure two metric thresholds:
      balm::ConfigurationUtil::setUserData("myCategory",
                                          "elapsedTime",
                                          thresholdKey,
                                          &ELAPSED_TIME_THRESHOLD);
      balm::ConfigurationUtil::setUserData("myCategory",
                                          "numRequests",
                                          thresholdKey,
                                          &NUM_REQUESTS_THRESHOLD);
Now we update the value of a couple of metrics. Note that the recorded number of requests is greater than the metric's configured threshold:
      BALM_METRICS_UPDATE("myCategory", "elapsedTime", 2);
      BALM_METRICS_UPDATE("myCategory", "numRequests", 150);
Finally, we publish the collected metrics. Note that in practice, clients of the balm package can use the balm::PublicationScheduler to schedule the periodic publication of metrics: The console output of the call to publishAll will look like:
  WARNING: myCategory.numRequests = 150