BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balm_configurationutil.h
Go to the documentation of this file.
1/// @file balm_configurationutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balm_configurationutil.h -*-C++-*-
8#ifndef INCLUDED_BALM_CONFIGURATIONUTIL
9#define INCLUDED_BALM_CONFIGURATIONUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balm_configurationutil balm_configurationutil
15/// @brief Provide a namespace for metrics configuration utilities.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balm
19/// @{
20/// @addtogroup balm_configurationutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balm_configurationutil-purpose"> Purpose</a>
25/// * <a href="#balm_configurationutil-classes"> Classes </a>
26/// * <a href="#balm_configurationutil-description"> Description </a>
27/// * <a href="#balm_configurationutil-alternative-systems-for-telemetry"> Alternative Systems for Telemetry </a>
28/// * <a href="#balm_configurationutil-thread-safety"> Thread Safety </a>
29/// * <a href="#balm_configurationutil-usage"> Usage </a>
30/// * <a href="#balm_configurationutil-example-1-configuring-the-output-of-a-metric"> Example 1: Configuring the Output of a Metric </a>
31/// * <a href="#balm_configurationutil-using-a-metric-s-user-data"> Using a Metric's User Data </a>
32///
33/// # Purpose {#balm_configurationutil-purpose}
34/// Provide a namespace for metrics configuration utilities.
35///
36/// # Classes {#balm_configurationutil-classes}
37///
38/// - balm::ConfigurationUtil: namespace for metrics configuration utilities
39///
40/// @see balm_metricsmanager, balm_defaultmetricsmanager
41///
42/// # Description {#balm_configurationutil-description}
43/// This component provides a set of utility functions for
44/// configuring metrics. The `balm::ConfigurationUtil` `struct` provides
45/// short-cuts for common configuration operations that are performed on other
46/// components in the `balm` package.
47///
48/// ## Alternative Systems for Telemetry {#balm_configurationutil-alternative-systems-for-telemetry}
49///
50///
51/// Bloomberg software may alternatively use the GUTS telemetry API, which is
52/// integrated into Bloomberg infrastructure.
53///
54/// ## Thread Safety {#balm_configurationutil-thread-safety}
55///
56///
57/// `balm::ConfigurationUtil` is fully *thread-safe*, meaning that all the
58/// methods can be safely invoked simultaneously from multiple threads.
59///
60/// ## Usage {#balm_configurationutil-usage}
61///
62///
63/// This section illustrates intended use of this component.
64///
65/// ### Example 1: Configuring the Output of a Metric {#balm_configurationutil-example-1-configuring-the-output-of-a-metric}
66///
67///
68/// This example uses `balm::ConfigurationUtil` to configure the output for a
69/// metric.
70///
71/// We start by initializing a default metrics manager by creating a
72/// `balm::DefaultMetricsManagerScopedGuard`, which manages the lifetime of the
73/// default metrics manager object. At construction, we provide the scoped
74/// guard an output stream (`stdout`) to which the default metrics manager will
75/// publish metrics. Note that the default metrics manager is intended to be
76/// created and destroyed by the *owner* of `main`. A metrics manager should
77/// be created during the initialization of an application (while the task has
78/// a single thread) and destroyed just prior to termination (when there is
79/// similarly a single thread).
80/// @code
81/// int main(int argc, char *argv[])
82/// {
83/// // ...
84///
85/// balm::DefaultMetricsManagerScopedGuard managerGuard(bsl::cout);
86/// @endcode
87/// Next we create a metric, "avgElapsedTimeMs", that will output the average
88/// time, in milliseconds, spent in a section of code. We set the preferred
89/// publication type for the metric to be average:
90/// @code
91/// balm::ConfigurationUtil::setPreferredPublicationType(
92/// "myCategory",
93/// "avgElapsedTimeMs",
94/// balm::PublicationType::e_AVG);
95/// @endcode
96/// Next, because we will record the elapsed time in seconds, we configure a
97/// format to scale the elapsed time by 1000.0:
98/// @code
99/// balm::ConfigurationUtil::setFormatSpec(
100/// "myCategory",
101/// "avgElapsedTimeMs",
102/// balm::PublicationType::e_AVG,
103/// balm::MetricFormatSpec(1000.0, "%.2f ms");
104/// @endcode
105/// We now collect an example value of .005:
106/// @code
107/// BALM_METRIC_UPDATE("myCategory", "avgElapsedTimeMs", .005);
108/// @endcode
109/// Finally, we publish the metric. Note that in practice, clients of the
110/// `balm` package can use the `balm::PublicationScheduler` to schedule the
111/// periodic publication of metrics:
112/// @code
113/// balm::DefaultMetricsManager::instance()->publishAll();
114/// @endcode
115/// The output for the publication will look like:
116/// @code
117/// 06AUG2009_20:27:51.982+0000 1 Records
118/// Elapsed Time: 0.000816s
119/// myCategory.avgElapsedTimeMs[ avg (total/count) = 5.00 ms ]
120/// @endcode
121///
122/// ### Using a Metric's User Data {#balm_configurationutil-using-a-metric-s-user-data}
123///
124///
125/// In the following example we configure, using `balm::ConfigurationUtil`,
126/// application-specific publication thresholds for a series of metrics. We
127/// will create an application-specific publisher that will use the configured
128/// thresholds to determine whether a metric should be written to the console.
129/// For simplicity, the metric thresholds in this example will be a single
130/// unsigned integer value that will be compared with the metric's total.
131///
132/// We start by defining an application-specific publisher implementation.
133/// This implementation is supplied a user data key on construction, which it
134/// uses to look up the threshold for a particular metric. If a metric's total
135/// value is greater than its threshold, it will log the metric to the console.
136/// @code
137/// // thresholdpublisher.h
138/// class ThresholdPublisher : public balm::Publisher {
139/// // A simple implementation of the 'balm::Publisher' protocol that
140/// // writes metric records to the console when their value is greater
141/// // than an application-specific threshold.
142///
143/// // DATA
144/// balm::MetricDescription::UserDataKey d_thresholdKey; // key for a
145/// // metric's
146/// // threshold
147///
148/// // NOT IMPLEMENTED
149/// ThresholdPublisher(const ThresholdPublisher&);
150/// ThresholdPublisher& operator=(const ThresholdPublisher&);
151///
152/// public:
153/// // CREATORS
154/// ThresholdPublisher(balm::MetricDescription::UserDataKey thresholdKey);
155/// // Create a publisher that will publish metrics to the console if
156/// // their total value is greater than their associated threshold,
157/// // accessed via the specified 'thresholdKey'.
158///
159/// ~ThresholdPublisher() BSLS_KEYWORD_OVERRIDE;
160/// // Destroy this publisher.
161///
162/// // MANIPULATORS
163/// virtual void publish(const balm::MetricSample& metricValues)
164/// BSLS_KEYWORD_OVERRIDE;
165/// // Publish the specified 'metricValues' to the console if they are
166/// // greater than their associated threshold.
167/// };
168///
169/// // thresholdpublisher.cpp
170///
171/// // CREATORS
172/// ThresholdPublisher::ThresholdPublisher(
173/// balm::MetricDescription::UserDataKey thresholdKey)
174/// : d_thresholdKey(thresholdKey)
175/// {
176/// }
177///
178/// ThresholdPublisher::~ThresholdPublisher()
179/// {
180/// }
181///
182/// // MANIPULATORS
183/// void ThresholdPublisher::publish(const balm::MetricSample& metricValues)
184/// {
185/// if (0 >= metricValues.numRecords()) {
186/// return; // RETURN
187/// }
188/// balm::MetricSample::const_iterator sIt = metricValues.begin();
189/// for (; sIt != metricValues.end(); ++sIt) {
190/// balm::MetricSampleGroup::const_iterator gIt = sIt->begin();
191/// for (; gIt != sIt->end(); ++gIt) {
192/// @endcode
193/// We now use the user data key to lookup the address of the threshold value.
194/// If this address is 0, no threshold is specified for the metric.
195/// @code
196/// const balm::MetricDescription& description =
197/// *gIt->metricId().description();
198/// unsigned int *thresholdPtr =
199/// (unsigned int *)description.userData(d_thresholdKey);
200/// if (thresholdPtr && gIt->total() > *thresholdPtr) {
201/// bsl::cout << "WARNING: " << gIt->metricId()
202/// << " = " << gIt->total()
203/// << bsl::endl;
204/// }
205/// }
206/// }
207/// }
208/// @endcode
209/// Now we examine how to configure a metrics manager with a
210/// `ThresholdPublisher`, and set the thresholds for a couple of metrics. We
211/// start by defining a couple of threshold constants for our metrics:
212/// @code
213/// static const unsigned int ELAPSED_TIME_THRESHOLD = 10;
214/// static const unsigned int NUM_REQUESTS_THRESHOLD = 100;
215/// @endcode
216/// Now, we configure a default metrics manager and publish a couple of example
217/// metrics. We start by initializing a default metrics manager by creating a
218/// `balm::DefaultMetricsManagerScopedGuard`, which manages the lifetime of the
219/// default metrics manager:
220/// @code
221/// int main(int argc, char *argv[])
222/// {
223/// // ...
224/// bslma::Allocator *allocator = bslma::Default::allocator(0);
225/// balm::DefaultMetricsManagerScopedGuard managerGuard;
226/// @endcode
227/// Now we create a user data key for our threshold information:
228/// @code
229/// balm::MetricDescription::UserDataKey thresholdKey =
230/// balm::ConfigurationUtil::createUserDataKey();
231/// @endcode
232/// Next we create an object of our application-specific publisher type,
233/// `ThresholdPublisher`, and configure the default metrics manager to publish
234/// metrics using this publisher:
235/// @code
236/// bsl::shared_ptr<balm::Publisher> publisher(
237/// new (*allocator) ThresholdPublisher(thresholdKey),
238/// allocator);
239/// balm::DefaultMetricsManager::instance()->addGeneralPublisher(publisher);
240/// @endcode
241/// Next we configure two metric thresholds:
242/// @code
243/// balm::ConfigurationUtil::setUserData("myCategory",
244/// "elapsedTime",
245/// thresholdKey,
246/// &ELAPSED_TIME_THRESHOLD);
247/// balm::ConfigurationUtil::setUserData("myCategory",
248/// "numRequests",
249/// thresholdKey,
250/// &NUM_REQUESTS_THRESHOLD);
251/// @endcode
252/// Now we update the value of a couple of metrics. Note that the recorded
253/// number of requests is greater than the metric's configured threshold:
254/// @code
255/// BALM_METRICS_UPDATE("myCategory", "elapsedTime", 2);
256/// BALM_METRICS_UPDATE("myCategory", "numRequests", 150);
257/// @endcode
258/// Finally, we publish the collected metrics. Note that in practice, clients
259/// of the `balm` package can use the `balm::PublicationScheduler` to schedule
260/// the periodic publication of metrics:
261/// @code
262/// balm::DefaultMetricsManager::instance()->publishAll();
263/// @endcode
264/// The console output of the call to `publishAll` will look like:
265/// @code
266/// WARNING: myCategory.numRequests = 150
267/// @endcode
268/// @}
269/** @} */
270/** @} */
271
272/** @addtogroup bal
273 * @{
274 */
275/** @addtogroup balm
276 * @{
277 */
278/** @addtogroup balm_configurationutil
279 * @{
280 */
281
282#include <balscm_version.h>
283
285#include <balm_publicationtype.h>
286
287
288namespace balm {
289
290class MetricFormat;
291class MetricFormatSpec;
292class MetricsManager;
293
294 // ========================
295 // struct ConfigurationUtil
296 // ========================
297
298/// This `struct` provides utilities for configuring metrics.
300
301 // CLASS METHODS
302
303 /// Set the format specification for the metric indicated by the
304 /// specified `category` and `metricName` to the specified `format`.
305 /// Optionally specify a metrics `manager` to configure. If `manager`
306 /// is 0, configure the default metrics manager; if `manager` is 0 and
307 /// the default metrics manager has not been initialized, this method
308 /// has no effect. Return 0 on success, or a non-zero value if
309 /// `manager` is 0 and the default metrics manager has not been
310 /// initialized. If a `MetricId` does not exist for `category` and
311 /// `metricName`, create one and add it to the metric registry of the
312 /// indicated metrics manager.
313 static int setFormat(const char *category,
314 const char *metricName,
315 const MetricFormat& format,
316 MetricsManager *manager = 0);
317
318 /// Set the format specification for the metric aggregate indicated by
319 /// the specified `category`, `metricName`, and `publicationType` to
320 /// the specified `formatSpec`. Optionally specify a metrics `manager`
321 /// to configure. If `manager` is 0, configure the default metrics
322 /// manager; if `manager` is 0 and the default metrics manager has not
323 /// been initialized, this method has no effect. Return 0 on success,
324 /// or a non-zero value if `manager` is 0 and the default metrics
325 /// manager has not been initialized. If a `MetricId` does not exist
326 /// for `category` and `metricName`, create one and add it to the metric
327 /// registry of the indicated metrics manager. For example a
328 /// publication type of `e_AVG`, and a format spec with a scale of
329 /// 1000.0 and a format of "%.2f ms", indicates that the average value
330 /// of the indicated metric should be formatted by scaling the value by
331 /// 1000 and then rounding the value to the second decimal place and
332 /// appending " ms".
333 static int setFormatSpec(const char *category,
334 const char *metricName,
335 PublicationType::Value publicationType,
336 const MetricFormatSpec& formatSpec,
337 MetricsManager *manager = 0);
338
339 /// Set the preferred publication type of the metric identified by the
340 /// specified `category` and `metricName` to the specified
341 /// `publicationType`. Optionally specify a metrics `manager` to
342 /// configure. If `manager` is 0, configure the default metrics
343 /// manager; if `manager` is 0 and the default metrics manager has not
344 /// been initialized, this method has no effect. Return 0 on success,
345 /// or a non-zero value if `manager` is 0 and the default metrics
346 /// manager has not been initialized. The preferred publication type of
347 /// a metric indicates the preferred aggregate to publish for that
348 /// metric, or `PublicationType::e_UNSPECIFIED` if there is no
349 /// preference. For example, specifying `e_AVG` indicates that the
350 /// average value of the collected metric should be reported. If a
351 /// `MetricId` does not exist for `category` and `metricName`, create
352 /// one and add it to the metric registry of the indicated metrics
353 /// manager. Note that there is no uniform definition for how
354 /// publishers will interpret this value.
356 const char *category,
357 const char *metricName,
358 PublicationType::Value publicationType,
359 MetricsManager *manager = 0);
360
361 /// Return a new unique key that can be used to associate (via
362 /// `setUserData`) a value with a metric (or group of metrics).
363 /// Optionally specify a metrics `manager` to configure. If `manager`
364 /// is 0, configure the default metrics manager; if `manager` is 0 and
365 /// the default metrics manager has not been initialized, then an
366 /// unspecified integer value is returned. Note that the returned key
367 /// can be used by clients of `balm` to associate additional
368 /// information with a metric.
370 MetricsManager *manager = 0);
371
372 /// Associate the specified `value` with the specified data `key` in the
373 /// description of the metric having the specified `category` and
374 /// `metricName`. Optionally specify a metrics `manager` to configure.
375 /// If `manager` is 0, configure the default metrics manager; if
376 /// `manager` is 0 and the default metrics manager has not been
377 /// initialized, this method has no effect. If a `MetricId` does not
378 /// exist for the `category` and `metricName`, create one and add it to
379 /// the metric registry of the indicated metrics manager. The behavior
380 /// is undefined unless `key` was previously created for the indicated
381 /// metrics manager's metrics registry (e.g., by calling
382 /// `createUserDataKey`). Note that this method allows clients of
383 /// `balm` to associate (opaque) application-specific information with a
384 /// metric.
385 static void setUserData(const char *category,
386 const char *metricName,
388 const void *value,
389 MetricsManager *manager = 0);
390
391 /// Associate the specified `value` with the specified data `key` in
392 /// any metric belonging to a category having the specified
393 /// `categoryName`, or, if `categoryName` ends with an asterisk (`*`),
394 /// any metric belonging to a category whose name begins with
395 /// `categoryName` (without the asterisk). Optionally specify a
396 /// metrics `manager` to configure. If `manager` is 0, configure the
397 /// default metrics manager; if `manager` is 0 and the default metrics
398 /// manager has not been initialized, this method has no effect. This
399 /// association applies to existing metrics as well as any subsequently
400 /// created ones. When a metric is created that matches more than one
401 /// registered category prefix, it is not specified which supplied
402 /// value will be associated with `key`, unless only one of those values
403 /// is non-null, in which case the unique non-null value is used. The
404 /// behavior is undefined unless `key` was previously created for the
405 /// indicated metrics manager's metrics registry (e.g., by calling
406 /// `createUserDataKey`).
407 static void setUserData(const char *categoryName,
409 const void *value,
410 MetricsManager *manager = 0);
411};
412} // close package namespace
413
414// ============================================================================
415// INLINE DEFINITIONS
416// ============================================================================
417
418
419
420#endif
421
422// ----------------------------------------------------------------------------
423// Copyright 2015 Bloomberg Finance L.P.
424//
425// Licensed under the Apache License, Version 2.0 (the "License");
426// you may not use this file except in compliance with the License.
427// You may obtain a copy of the License at
428//
429// http://www.apache.org/licenses/LICENSE-2.0
430//
431// Unless required by applicable law or agreed to in writing, software
432// distributed under the License is distributed on an "AS IS" BASIS,
433// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
434// See the License for the specific language governing permissions and
435// limitations under the License.
436// ----------------------------- END-OF-FILE ----------------------------------
437
438/** @} */
439/** @} */
440/** @} */
int UserDataKey
Definition balm_metricdescription.h:190
Definition balm_metricformat.h:183
Definition balm_metricformat.h:317
Definition balm_metricsmanager.h:490
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balm_bdlmmetricsadapter.h:141
This struct provides utilities for configuring metrics.
Definition balm_configurationutil.h:299
static MetricDescription::UserDataKey createUserDataKey(MetricsManager *manager=0)
static int setPreferredPublicationType(const char *category, const char *metricName, PublicationType::Value publicationType, MetricsManager *manager=0)
static void setUserData(const char *categoryName, MetricDescription::UserDataKey key, const void *value, MetricsManager *manager=0)
static void setUserData(const char *category, const char *metricName, MetricDescription::UserDataKey key, const void *value, MetricsManager *manager=0)
static int setFormatSpec(const char *category, const char *metricName, PublicationType::Value publicationType, const MetricFormatSpec &formatSpec, MetricsManager *manager=0)
static int setFormat(const char *category, const char *metricName, const MetricFormat &format, MetricsManager *manager=0)
Value
Definition balm_publicationtype.h:81