BDE 4.39.x 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/// private:
149/// // NOT IMPLEMENTED
150/// ThresholdPublisher(const ThresholdPublisher&);
151/// ThresholdPublisher& operator=(const ThresholdPublisher&);
152///
153/// public:
154/// // CREATORS
155/// ThresholdPublisher(balm::MetricDescription::UserDataKey thresholdKey);
156/// // Create a publisher that will publish metrics to the console if
157/// // their total value is greater than their associated threshold,
158/// // accessed via the specified 'thresholdKey'.
159///
160/// ~ThresholdPublisher() BSLS_KEYWORD_OVERRIDE;
161/// // Destroy this publisher.
162///
163/// // MANIPULATORS
164/// virtual void publish(const balm::MetricSample& metricValues)
165/// BSLS_KEYWORD_OVERRIDE;
166/// // Publish the specified 'metricValues' to the console if they are
167/// // greater than their associated threshold.
168/// };
169///
170/// // thresholdpublisher.cpp
171///
172/// // CREATORS
173/// ThresholdPublisher::ThresholdPublisher(
174/// balm::MetricDescription::UserDataKey thresholdKey)
175/// : d_thresholdKey(thresholdKey)
176/// {
177/// }
178///
179/// ThresholdPublisher::~ThresholdPublisher()
180/// {
181/// }
182///
183/// // MANIPULATORS
184/// void ThresholdPublisher::publish(const balm::MetricSample& metricValues)
185/// {
186/// if (0 >= metricValues.numRecords()) {
187/// return; // RETURN
188/// }
189/// balm::MetricSample::const_iterator sIt = metricValues.begin();
190/// for (; sIt != metricValues.end(); ++sIt) {
191/// balm::MetricSampleGroup::const_iterator gIt = sIt->begin();
192/// for (; gIt != sIt->end(); ++gIt) {
193/// @endcode
194/// We now use the user data key to lookup the address of the threshold value.
195/// If this address is 0, no threshold is specified for the metric.
196/// @code
197/// const balm::MetricDescription& description =
198/// *gIt->metricId().description();
199/// unsigned int *thresholdPtr =
200/// (unsigned int *)description.userData(d_thresholdKey);
201/// if (thresholdPtr && gIt->total() > *thresholdPtr) {
202/// bsl::cout << "WARNING: " << gIt->metricId()
203/// << " = " << gIt->total()
204/// << bsl::endl;
205/// }
206/// }
207/// }
208/// }
209/// @endcode
210/// Now we examine how to configure a metrics manager with a
211/// `ThresholdPublisher`, and set the thresholds for a couple of metrics. We
212/// start by defining a couple of threshold constants for our metrics:
213/// @code
214/// static const unsigned int ELAPSED_TIME_THRESHOLD = 10;
215/// static const unsigned int NUM_REQUESTS_THRESHOLD = 100;
216/// @endcode
217/// Now, we configure a default metrics manager and publish a couple of example
218/// metrics. We start by initializing a default metrics manager by creating a
219/// `balm::DefaultMetricsManagerScopedGuard`, which manages the lifetime of the
220/// default metrics manager:
221/// @code
222/// int main(int argc, char *argv[])
223/// {
224/// // ...
225/// bslma::Allocator *allocator = bslma::Default::allocator(0);
226/// balm::DefaultMetricsManagerScopedGuard managerGuard;
227/// @endcode
228/// Now we create a user data key for our threshold information:
229/// @code
230/// balm::MetricDescription::UserDataKey thresholdKey =
231/// balm::ConfigurationUtil::createUserDataKey();
232/// @endcode
233/// Next we create an object of our application-specific publisher type,
234/// `ThresholdPublisher`, and configure the default metrics manager to publish
235/// metrics using this publisher:
236/// @code
237/// bsl::shared_ptr<balm::Publisher> publisher(
238/// new (*allocator) ThresholdPublisher(thresholdKey),
239/// allocator);
240/// balm::DefaultMetricsManager::instance()->addGeneralPublisher(publisher);
241/// @endcode
242/// Next we configure two metric thresholds:
243/// @code
244/// balm::ConfigurationUtil::setUserData("myCategory",
245/// "elapsedTime",
246/// thresholdKey,
247/// &ELAPSED_TIME_THRESHOLD);
248/// balm::ConfigurationUtil::setUserData("myCategory",
249/// "numRequests",
250/// thresholdKey,
251/// &NUM_REQUESTS_THRESHOLD);
252/// @endcode
253/// Now we update the value of a couple of metrics. Note that the recorded
254/// number of requests is greater than the metric's configured threshold:
255/// @code
256/// BALM_METRICS_UPDATE("myCategory", "elapsedTime", 2);
257/// BALM_METRICS_UPDATE("myCategory", "numRequests", 150);
258/// @endcode
259/// Finally, we publish the collected metrics. Note that in practice, clients
260/// of the `balm` package can use the `balm::PublicationScheduler` to schedule
261/// the periodic publication of metrics:
262/// @code
263/// balm::DefaultMetricsManager::instance()->publishAll();
264/// @endcode
265/// The console output of the call to `publishAll` will look like:
266/// @code
267/// WARNING: myCategory.numRequests = 150
268/// @endcode
269/// @}
270/** @} */
271/** @} */
272
273/** @addtogroup bal
274 * @{
275 */
276/** @addtogroup balm
277 * @{
278 */
279/** @addtogroup balm_configurationutil
280 * @{
281 */
282
283#include <balscm_version.h>
284
286#include <balm_publicationtype.h>
287
288
289namespace balm {
290
291class MetricFormat;
292class MetricFormatSpec;
293class MetricsManager;
294
295 // ========================
296 // struct ConfigurationUtil
297 // ========================
298
299/// This `struct` provides utilities for configuring metrics.
300///
301/// See @ref balm_configurationutil
303
304 // CLASS METHODS
305
306 /// Set the format specification for the metric indicated by the
307 /// specified `category` and `metricName` to the specified `format`.
308 /// Optionally specify a metrics `manager` to configure. If `manager`
309 /// is 0, configure the default metrics manager; if `manager` is 0 and
310 /// the default metrics manager has not been initialized, this method
311 /// has no effect. Return 0 on success, or a non-zero value if
312 /// `manager` is 0 and the default metrics manager has not been
313 /// initialized. If a `MetricId` does not exist for `category` and
314 /// `metricName`, create one and add it to the metric registry of the
315 /// indicated metrics manager.
316 static int setFormat(const char *category,
317 const char *metricName,
318 const MetricFormat& format,
319 MetricsManager *manager = 0);
320
321 /// Set the format specification for the metric aggregate indicated by
322 /// the specified `category`, `metricName`, and `publicationType` to
323 /// the specified `formatSpec`. Optionally specify a metrics `manager`
324 /// to configure. If `manager` is 0, configure the default metrics
325 /// manager; if `manager` is 0 and the default metrics manager has not
326 /// been initialized, this method has no effect. Return 0 on success,
327 /// or a non-zero value if `manager` is 0 and the default metrics
328 /// manager has not been initialized. If a `MetricId` does not exist
329 /// for `category` and `metricName`, create one and add it to the metric
330 /// registry of the indicated metrics manager. For example a
331 /// publication type of `e_AVG`, and a format spec with a scale of
332 /// 1000.0 and a format of "%.2f ms", indicates that the average value
333 /// of the indicated metric should be formatted by scaling the value by
334 /// 1000 and then rounding the value to the second decimal place and
335 /// appending " ms".
336 static int setFormatSpec(const char *category,
337 const char *metricName,
338 PublicationType::Value publicationType,
339 const MetricFormatSpec& formatSpec,
340 MetricsManager *manager = 0);
341
342 /// Set the preferred publication type of the metric identified by the
343 /// specified `category` and `metricName` to the specified
344 /// `publicationType`. Optionally specify a metrics `manager` to
345 /// configure. If `manager` is 0, configure the default metrics
346 /// manager; if `manager` is 0 and the default metrics manager has not
347 /// been initialized, this method has no effect. Return 0 on success,
348 /// or a non-zero value if `manager` is 0 and the default metrics
349 /// manager has not been initialized. The preferred publication type of
350 /// a metric indicates the preferred aggregate to publish for that
351 /// metric, or `PublicationType::e_UNSPECIFIED` if there is no
352 /// preference. For example, specifying `e_AVG` indicates that the
353 /// average value of the collected metric should be reported. If a
354 /// `MetricId` does not exist for `category` and `metricName`, create
355 /// one and add it to the metric registry of the indicated metrics manager.
356 ///
357 /// \note Note that there is no uniform definition for how
358 /// publishers will interpret this value.
360 const char *category,
361 const char *metricName,
362 PublicationType::Value publicationType,
363 MetricsManager *manager = 0);
364
365 /// Return a new unique key that can be used to associate (via
366 /// `setUserData`) a value with a metric (or group of metrics).
367 /// Optionally specify a metrics `manager` to configure. If `manager`
368 /// is 0, configure the default metrics manager; if `manager` is 0 and
369 /// the default metrics manager has not been initialized, then an unspecified integer value is returned.
370 ///
371 /// \note Note that the returned key
372 /// can be used by clients of `balm` to associate additional
373 /// information with a metric.
375 MetricsManager *manager = 0);
376
377 /// Associate the specified `value` with the specified data `key` in the
378 /// description of the metric having the specified `category` and
379 /// `metricName`. Optionally specify a metrics `manager` to configure.
380 /// If `manager` is 0, configure the default metrics manager; if
381 /// `manager` is 0 and the default metrics manager has not been
382 /// initialized, this method has no effect. If a `MetricId` does not
383 /// exist for the `category` and `metricName`, create one and add it to
384 /// the metric registry of the indicated metrics manager.
385 ///
386 /// \pre The behavior is undefined unless `key` was previously created for the indicated
387 /// metrics manager's metrics registry (e.g., by calling `createUserDataKey`).
388 ///
389 /// \note Note that this method allows clients of
390 /// `balm` to associate (opaque) application-specific information with a
391 /// metric.
392 static void setUserData(const char *category,
393 const char *metricName,
395 const void *value,
396 MetricsManager *manager = 0);
397
398 /// Associate the specified `value` with the specified data `key` in
399 /// any metric belonging to a category having the specified
400 /// `categoryName`, or, if `categoryName` ends with an asterisk (`*`),
401 /// any metric belonging to a category whose name begins with
402 /// `categoryName` (without the asterisk). Optionally specify a
403 /// metrics `manager` to configure. If `manager` is 0, configure the
404 /// default metrics manager; if `manager` is 0 and the default metrics
405 /// manager has not been initialized, this method has no effect. This
406 /// association applies to existing metrics as well as any subsequently
407 /// created ones. When a metric is created that matches more than one
408 /// registered category prefix, it is not specified which supplied
409 /// value will be associated with `key`, unless only one of those values
410 /// is non-null, in which case the unique non-null value is used.
411 ///
412 /// \pre The behavior is undefined unless `key` was previously created for the
413 /// indicated metrics manager's metrics registry (e.g., by calling
414 /// `createUserDataKey`).
415 static void setUserData(const char *categoryName,
417 const void *value,
418 MetricsManager *manager = 0);
419};
420} // close package namespace
421
422// ============================================================================
423// INLINE DEFINITIONS
424// ============================================================================
425
426
427
428#endif
429
430// ----------------------------------------------------------------------------
431// Copyright 2015 Bloomberg Finance L.P.
432//
433// Licensed under the Apache License, Version 2.0 (the "License");
434// you may not use this file except in compliance with the License.
435// You may obtain a copy of the License at
436//
437// http://www.apache.org/licenses/LICENSE-2.0
438//
439// Unless required by applicable law or agreed to in writing, software
440// distributed under the License is distributed on an "AS IS" BASIS,
441// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
442// See the License for the specific language governing permissions and
443// limitations under the License.
444// ----------------------------- END-OF-FILE ----------------------------------
445
446/** @} */
447/** @} */
448/** @} */
int UserDataKey
Definition balm_metricdescription.h:192
Definition balm_metricformat.h:183
Definition balm_metricformat.h:321
Definition balm_metricsmanager.h:490
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balm_bdlmmetricsadapter.h:142
Definition balm_configurationutil.h:302
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:83