BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balm_metrics.h
Go to the documentation of this file.
1/// @file balm_metrics.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balm_metrics.h -*-C++-*-
8#ifndef INCLUDED_BALM_METRICS
9#define INCLUDED_BALM_METRICS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balm_metrics balm_metrics
15/// @brief Provide a suite of operations for recording metric values.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balm
19/// @{
20/// @addtogroup balm_metrics
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balm_metrics-purpose"> Purpose</a>
25/// * <a href="#balm_metrics-classes"> Classes </a>
26/// * <a href="#balm_metrics-description"> Description </a>
27/// * <a href="#balm_metrics-alternative-systems-for-telemetry"> Alternative Systems for Telemetry </a>
28/// * <a href="#balm_metrics-thread-safety"> Thread Safety </a>
29/// * <a href="#balm_metrics-macro-summary"> Macro Summary </a>
30/// * <a href="#balm_metrics-macro-reference"> Macro Reference </a>
31/// * <a href="#balm_metrics-usage"> Usage </a>
32/// * <a href="#balm_metrics-example-1-create-and-configure-the-default-balm-metricsmanager-instance"> Example 1: Create and Configure the Default balm::MetricsManager Instance </a>
33/// * <a href="#balm_metrics-example-2-updating-a-metric"> Example 2: Updating a Metric </a>
34/// * <a href="#balm_metrics-example-3-using-balm_metrics_if_category_enabled"> Example 3: Using BALM_METRICS_IF_CATEGORY_ENABLED </a>
35///
36/// # Purpose {#balm_metrics-purpose}
37/// Provide a suite of operations for recording metric values.
38///
39/// # Classes {#balm_metrics-classes}
40///
41///
42/// @see balm_collector, balm_integercollector, balm_defaultmetricsmanager
43///
44/// # Description {#balm_metrics-description}
45/// This component provides a suite of macros to simplify the
46/// process of collecting metrics. A metric records the number of times an
47/// event occurs, as well as an associated measurement value. A metric
48/// maintains a count of event occurrences and the aggregated minimum, maximum,
49/// and total of the measured metric-event values. Note that this component
50/// does *not* define what constitutes an event nor what the associated value
51/// represents.
52///
53/// ## Alternative Systems for Telemetry {#balm_metrics-alternative-systems-for-telemetry}
54///
55///
56/// Bloomberg software may alternatively use the GUTS telemetry API, which is
57/// integrated into Bloomberg infrastructure.
58///
59/// ## Thread Safety {#balm_metrics-thread-safety}
60///
61///
62/// All the macros defined in this component are *thread-safe*, meaning that
63/// they can be safely invoked simultaneously from multiple threads. It is
64/// *not* safe, however, to invoke any of the macros defined in this component
65/// while the default metrics manager is being either created or destroyed.
66///
67/// ## Macro Summary {#balm_metrics-macro-summary}
68///
69///
70/// This section provides a brief description of the macros defined in this
71/// component. In most cases, category and metric names supplied as macro
72/// arguments are required to be *runtime* *constants*, meaning that their
73/// values must be constant for the lifetime of the process. More complete
74/// documentation is provided in the `Macro Reference` section.
75/// @code
76/// BALM_METRICS_IF_CATEGORY_ENABLED(CATEGORY)
77/// This macro behaves like an 'if' clause, executing the subsequent
78/// (compound) statement if the specified 'CATEGORY' is enabled.
79///
80/// BALM_METRICS_UPDATE(CATEGORY, METRIC1, VALUE1)
81/// BALM_METRICS_UPDATE2(CATEGORY, METRIC1, VALUE1, METRIC2, VALUE2)
82/// BALM_METRICS_UPDATE3(CATEGORY, METRIC1, VALUE1, ..., METRIC3, VALUE3)
83/// BALM_METRICS_UPDATE4(CATEGORY, METRIC1, VALUE1, ..., METRIC4, VALUE4)
84/// BALM_METRICS_UPDATE5(CATEGORY, METRIC1, VALUE1, ..., METRIC5, VALUE5)
85/// BALM_METRICS_UPDATE6(CATEGORY, METRIC1, VALUE1, ..., METRIC6, VALUE6)
86/// BALM_METRICS_INT_UPDATE(CATEGORY, METRIC1, VALUE1)
87/// BALM_METRICS_INT_UPDATE2(CATEGORY, METRIC1, VALUE1, METRIC2, VALUE2)
88/// BALM_METRICS_INT_UPDATE3(CATEGORY, METRIC1, VALUE1, ..., METRIC3, VALUE3)
89/// BALM_METRICS_INT_UPDATE4(CATEGORY, METRIC1, VALUE1, ..., METRIC4, VALUE4)
90/// BALM_METRICS_INT_UPDATE5(CATEGORY, METRIC1, VALUE1, ..., METRIC5, VALUE5)
91/// BALM_METRICS_INT_UPDATE6(CATEGORY, METRIC1, VALUE1, ..., METRIC6, VALUE6)
92/// Update each of up to 6 metrics by the corresponding values.
93/// The supplied category and metric names must be *runtime* *constants*.
94///
95/// BALM_METRICS_TYPED_UPDATE(CATEGORY, METRIC, VALUE, PREFERRED_TYPE)
96/// BALM_METRICS_TYPED_INT_UPDATE(CATEGORY, METRIC, VALUE, PREFERRED_TYPE)
97/// Update the identified metric by 'VALUE' and set its preferred
98/// publication type. 'CATEGORY' and 'METRIC' must be *runtime*
99/// *constants*.
100///
101/// BALM_METRICS_INCREMENT(CATEGORY, METRIC)
102/// Increment (by 1) the identified metric. 'CATEGORY' and 'METRIC' must
103/// be *runtime* *constants*.
104///
105/// BALM_METRICS_TYPED_INCREMENT(CATEGORY, METRIC, PREFERRED_TYPE)
106/// Increment (by 1) the identified metric and set the metric's preferred
107/// publication type. 'CATEGORY' and 'METRIC' must be *runtime*
108/// *constants*.
109///
110/// BALM_METRICS_DYNAMIC_UPDATE(CATEGORY, METRIC, VALUE)
111/// BALM_METRICS_DYNAMIC_INT_UPDATE(CATEGORY, METRIC, VALUE)
112/// Update the identified metric by 'VALUE'. This operation performs a
113/// lookup on 'CATEGORY' and 'METRIC' on each invocation, so those values
114/// need *not* be runtime constants.
115///
116/// BALM_METRICS_DYNAMIC_INCREMENT(CATEGORY, METRIC)
117/// Increment (by 1) the identified metric. This operation performs a
118/// lookup on 'CATEGORY' and 'METRIC' on each invocation, so those values
119/// need *not* be runtime constants.
120///
121/// BALM_METRICS_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS)
122/// BALM_METRICS_TIME_BLOCK_SECONDS(CATEGORY, METRIC)
123/// BALM_METRICS_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC)
124/// BALM_METRICS_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC)
125/// BALM_METRICS_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC)
126/// Update the identified metric by the elapsed (wall) time, in the
127/// indicated units, from the instantiation point of the macro to the end
128/// of the enclosing lexical scope. 'CATEGORY' and 'METRIC' must
129/// be *runtime* *constants*.
130///
131/// BALM_METRICS_DYNAMIC_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS)
132/// BALM_METRICS_DYNAMIC_TIME_BLOCK_SECONDS(CATEGORY, METRIC)
133/// BALM_METRICS_DYNAMIC_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC)
134/// BALM_METRICS_DYNAMIC_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC)
135/// BALM_METRICS_DYNAMIC_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC)
136/// Update the identified metric by the elapsed (wall) time, in the
137/// indicated units, from the instantiation point of the macro to the end
138/// of the enclosing lexical scope. This operation performs a lookup on
139/// 'CATEGORY' and 'METRIC' on each invocation, so those values need *not*
140/// be runtime constants.
141/// @endcode
142///
143/// ## Macro Reference {#balm_metrics-macro-reference}
144///
145///
146/// The macros defined in this component make use of the default instance of
147/// `balm::MetricsManager`. The macros have no effect unless the metrics
148/// manager default instance has been initialized via a call to
149/// `balm::DefaultMetricsManager::create`.
150///
151/// The macros defined below provide two basic operations identified by their
152/// suffixes: update (`*_UPDATE`) and increment (`*_INCREMENT`). The update
153/// operation increments (by 1) the identified metric's count of events,
154/// increases the metric's total by the supplied value, if the supplied value
155/// is less than the metric's current minimum value then the minimum value is
156/// set to the supplied value, and if the supplied value is greater than the
157/// metric's current maximum value then the maximum value is set to the supplied
158/// value. The increment operation is logically equivalent to an update of 1.
159///
160/// The update, increment, and timing operations come in two variations:
161/// standard, and dynamic (*<u>DYNAMIC</u>*). The standard variation maintains a
162/// (function-scope static) cache containing the identity of the metric being
163/// collected. This cache is initialized the *first* time the flow of control
164/// passes through the instantiated macro, which in practice means that the
165/// identifiers for the metric(s) passed as parameters to that macro must be
166/// *runtime* *constants*. The dynamic variant looks up the supplied category
167/// and metric(s) on each invocation of the macro, resulting in additional
168/// runtime overhead compared to the standard variant.
169///
170/// The following are the standard (non-dynamic) macros provided by this
171/// component for updating a metric's value:
172/// @code
173/// BALM_METRICS_UPDATE(CATEGORY, METRIC, VALUE)
174/// Update the indicated metric, identified by the specified 'CATEGORY'
175/// and 'METRIC' names, with the specified 'VALUE'. 'CATEGORY' and
176/// 'METRIC' must be null-terminated strings of a type convertible to
177/// 'const char *', and 'VALUE' is assumed to be of a type convertible to
178/// 'double'. This macro maintains a (function-scope static) cache
179/// containing the identity of the metric being updated. This cache is
180/// initialized using the 'CATEGORY' and 'METRIC' specified on the *first*
181/// application of this macro at a particular instantiation point;
182/// subsequent applications use that cached information, which in
183/// practice means that 'CATEGORY' and 'METRIC' must be *runtime*
184/// *constants*. If the default metrics manager has not been
185/// initialized, or if the indicated 'CATEGORY' is currently disabled,
186/// this macro has no effect.
187///
188/// BALM_METRICS_INT_UPDATE(CATEGORY, METRIC, VALUE)
189/// Update the indicated metric, identified by the specified 'CATEGORY'
190/// and 'METRIC' names, with the specified *integer* 'VALUE'. 'CATEGORY'
191/// and 'METRIC' must be null-terminated strings of a type convertible to
192/// 'const char *', and 'VALUE' is assumed to be of a type convertible to
193/// 'int'. This macro maintains a (function-scope static) cache
194/// containing the identity of the metric being updated. This cache is
195/// initialized using the 'CATEGORY' and 'METRIC' specified on the *first*
196/// application of this macro at a particular instantiation point;
197/// subsequent applications use that cached information, which in
198/// practice, means that 'CATEGORY' and 'METRIC' must be *runtime*
199/// *constants*. If the default metrics manager has not been initialized,
200/// or if the indicated 'CATEGORY' is currently disabled, this macro has
201/// no effect.
202///
203/// BALM_METRICS_UPDATE2(CATEGORY, METRIC1, VALUE1, METRIC2, VALUE2)
204/// BALM_METRICS_UPDATEn(CATEGORY, METRIC1, VALUE1, ..., METRICn, VALUEn)
205/// Where 2 <= n <= 6
206/// Update each of the indicated metrics, identified by the specified
207/// 'CATEGORY' name and the respective metric names 'METRIC1', 'METRIC2',
208/// ..., 'METRICn' (2 <= n <= 6), with the corresponding specified
209/// 'VALUE1', 'VALUE2', ..., 'VALUEn'. 'CATEGORY' and 'METRIC1',
210/// 'METRIC2', ..., 'METRICn', must be null-terminated strings of a type
211/// convertible to 'const char *', and 'VALUE1', 'VALUE2', ..., 'VALUEn'
212/// are assumed to be of a type convertible to 'double'. These macros
213/// maintain a (function-scope static) cache containing the identity of
214/// the metrics being updated. This cache is initialized using the
215/// 'CATEGORY' and metric identifiers specified on the *first*
216/// application of these macros at a particular instantiation point;
217/// subsequent applications use that cached information, which in
218/// practice means that the 'CATEGORY' and metric identifiers must be
219/// *runtime* *constants*. If the default metrics manager has not been
220/// initialized, or if the indicated 'CATEGORY' is currently disabled,
221/// these macros have no effect.
222///
223/// BALM_METRICS_INT_UPDATE2(CATEGORY, METRIC1, VALUE1, METRIC2, VALUE2)
224/// BALM_METRICS_INT_UPDATEn(CATEGORY, METRIC1, VALUE1, ..., METRICn, VALUEn)
225/// Where 2 <= n <= 6
226/// Update each of the indicated metrics, identified by the specified
227/// 'CATEGORY' name and the respective metric names 'METRIC1', 'METRIC2',
228/// ..., 'METRICn' (2 <= n <= 6), with the corresponding specified
229/// *integer* 'VALUE1', 'VALUE2', ..., 'VALUEn'. 'CATEGORY' and
230/// 'METRIC1', 'METRIC2', ..., 'METRICn', must be null-terminated strings
231/// of a type convertible to 'const char *', and 'VALUE1', 'VALUE2', ...,
232/// 'VALUEn' are assumed to be of a type convertible to 'int'. These
233/// macros maintain a (function-scope static) cache containing the
234/// identity of the metrics being updated. This cache is initialized
235/// using the 'CATEGORY' and metric identifiers specified on the *first*
236/// application of these macros at a particular instantiation point;
237/// subsequent applications use that cached information, which in
238/// practice means that the 'CATEGORY' and metric identifiers must be
239/// *runtime* *constants*. If the default metrics manager has not been
240/// initialized, or if the indicated 'CATEGORY' is currently disabled,
241/// these macros have no effect.
242///
243/// BALM_METRICS_TYPED_UPDATE(CATEGORY,
244/// METRIC,
245/// VALUE,
246/// PREFERRED_PUBLICATION_TYPE)
247/// BALM_METRICS_TYPED_INT_UPDATE(CATEGORY,
248/// METRIC,
249/// VALUE,
250/// PREFERRED_PUBLICATION_TYPE)
251/// The behavior of these macros is logically equivalent to
252/// 'BALM_METRICS_UPDATE(CATEGORY, METRIC, VALUE)' and
253/// 'BALM_METRICS_INT_UPDATE(CATEGORY, METRIC, VALUE)', respectively,
254/// except that, on the first invocation, these macros also set the
255/// indicated metric's 'PREFERRED_PUBLICATION_TYPE'. The preferred
256/// publication type of a metric indicates the preferred aggregate to
257/// publish for that metric (e.g., 'COUNT', 'TOTAL', 'MIN', 'MAX', or
258/// 'RATE'). The behavior is undefined unless
259/// 'PREFERRED_PUBLICATION_TYPE' is convertible to
260/// 'balm::PublicationType::Value'. Note that there is no uniform
261/// definition for how publishers will interpret this value; an
262/// 'UNSPECIFIED' value, however, generally indicates that all of the
263/// collected aggregates (total, count, minimum, and maximum value)
264/// should be published.
265///
266/// BALM_METRICS_INCREMENT(CATEGORY, METRIC)
267/// The behavior of this macro is logically equivalent to:
268/// 'BALM_METRICS_INT_UPDATE(CATEGORY, METRIC, 1)'.
269///
270/// BALM_METRICS_TYPED_INCREMENT(CATEGORY, METRIC, PREFERRED_TYPE)
271/// The behavior of this macro is logically equivalent to
272/// 'BALM_METRICS_TYPED_UPDATE(CATEGORY, METRIC, 1, PREFERRED_TYPE)'.
273/// @endcode
274/// The following are the dynamic macros provided by this component for
275/// updating a metric's value; these macros do not statically cache the
276/// identity of the metric and look up the supplied `CATEGORY` and `METRIC` on
277/// each invocation:
278/// @code
279/// BALM_METRICS_DYNAMIC_UPDATE(CATEGORY, METRIC, VALUE)
280/// Update the indicated metric, identified by the specified 'CATEGORY'
281/// and 'METRIC' names, by the specified 'VALUE'. 'CATEGORY' and
282/// 'METRIC' must be null-terminated strings of a type convertible to
283/// 'const char *', and 'VALUE' is assumed to be of a type convertible to
284/// 'double'. If the default metrics manager has not been initialized,
285/// or if the indicated 'CATEGORY' is currently disabled, this macro has
286/// no effect. Note that this operation looks up the 'CATEGORY'
287/// and 'METRIC' on *each* application, resulting in (unnecessary)
288/// additional runtime overhead (if the 'CATEGORY' and 'METRIC' values are
289/// always the same for a particular point of call).
290///
291/// BALM_METRICS_DYNAMIC_INT_UPDATE(CATEGORY, METRIC, VALUE)
292/// Update the indicated metric, identified by the specified 'CATEGORY'
293/// and 'METRIC' names, by the specified *integer* 'VALUE'. 'CATEGORY'
294/// and 'METRIC' must be null-terminated strings of a type convertible to
295/// 'const char *', and 'VALUE' is assumed to be of a type convertible
296/// to 'int'. If the default metrics manager has not been initialized,
297/// or if the indicated 'CATEGORY' is currently disabled, this macro has
298/// no effect. Note that this operation looks up the 'CATEGORY'
299/// and 'METRIC' on *each* application, resulting in (unnecessary)
300/// additional runtime overhead (if the 'CATEGORY' and 'METRIC' values
301/// are always the same for a particular point of call).
302///
303/// BALM_METRICS_DYNAMIC_INCREMENT(CATEGORY, METRIC)
304/// The behavior of this macro is logically equivalent to
305/// 'BALM_METRICS_DYNAMIC_INT_UPDATE(CATEGORY, METRIC, 1)'.
306/// @endcode
307/// The following macro, `BALM_METRICS_IF_CATEGORY_ENABLED`, allows clients to
308/// (efficiently) determine if a (*runtime* *constant*) category is enabled:
309/// @code
310/// BALM_METRICS_IF_CATEGORY_ENABLED(CATEGORY)
311/// This macro behaves like an 'if' clause, executing the subsequent
312/// (compound) statement if the specified 'CATEGORY' is enabled.
313/// 'CATEGORY' must be a null-terminated string of a type convertible to
314/// 'const char *'. If the default metrics manager has not been
315/// initialized, or if the indicated 'CATEGORY' is currently disabled,
316/// the following statement is not executed (i.e., the 'if'-condition
317/// is 'false'). This macro maintains a (function-scope static) cache
318/// containing the identity of the category. This cache is initialized
319/// using the 'CATEGORY' specified on the *first* application of this
320/// macro at a particular instantiation point; subsequent applications
321/// use that cached information, which in practice means that
322/// 'CATEGORY' must be a *runtime* *constant*. *WARNING*: although the
323/// 'BALM_METRICS_IF_CATEGORY_ENABLED' may look like a function call,
324/// it actually consists of a declaration and an 'if' statement, which
325/// means that the following is syntactically *incorrect*:
326/// 'if (BALM_METRICS_IF_CATEGORY_ENABLED("myCategory")) { stuff() }'.
327/// That should instead be written as:
328/// 'BALM_METRICS_IF_CATEGORY_ENABLED("myCategory") { stuff(); }'.
329/// @endcode
330/// Finally, this component provides a set of macros to record the elapsed wall
331/// time of a block of code:
332/// @code
333/// BALM_METRICS_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS)
334/// Update the indicated metric, identified by the specified 'CATEGORY'
335/// and 'METRIC' names, by the elapsed (wall) time, in the specified
336/// 'TIME_UNITS', from the point of instantiation of the macro to the end
337/// of the enclosing lexical scope. 'CATEGORY' and 'METRIC' must be
338/// null-terminated strings of a type convertible to 'const char *',
339/// while 'TIME_UNITS' is assumed to be of a type convertible to the
340/// enumerated type 'balm::StopwatchScopedGuard::Units'. This macro
341/// maintains a (function-scope static) cache containing the identity of
342/// the metric being updated. This cache is initialized using the
343/// 'CATEGORY' and 'METRIC' specified on the *first* application of this
344/// macro at a particular instantiation point; subsequent applications
345/// use that cached information, which in practice means that
346/// 'CATEGORY' and 'METRIC' must be *runtime* *constants*. If the
347/// default metrics manager has not been initialized, or the identified
348/// 'CATEGORY' is disabled, this macro has no effect. Note that
349/// 'TIME_UNITS' indicates the scale of value to report, but does *not*
350/// affect the precision of the elapsed time measurement.
351///
352/// BALM_METRICS_TIME_BLOCK_SECONDS(CATEGORY, METRIC)
353/// The behavior of this macro is logically equivalent to
354/// 'BALM_METRICS_TIME_BLOCK' called with
355/// 'balm::StopwatchScopedGuard::k_SECONDS'.
356///
357/// BALM_METRICS_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC)
358/// The behavior of this macro is logically equivalent to
359/// 'BALM_METRICS_TIME_BLOCK' called with
360/// 'balm::StopwatchScopedGuard::k_MILLISECONDS'.
361///
362/// BALM_METRICS_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC)
363/// The behavior of this macro is logically equivalent to
364/// 'BALM_METRICS_TIME_BLOCK' called with
365/// 'balm::StopwatchScopedGuard::k_MICROSECONDS'.
366///
367/// BALM_METRICS_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC)
368/// The behavior of this macro is logically equivalent to
369/// 'BALM_METRICS_TIME_BLOCK' called with
370/// 'balm::StopwatchScopedGuard::k_NANOSECONDS'.
371///
372/// BALM_METRICS_DYNAMIC_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS)
373/// Update the indicated metric, identified by the specified 'CATEGORY'
374/// and 'METRIC' names, by the elapsed (wall) time, in the specified
375/// 'TIME_UNITS', from the instantiation of the macro to the end of the
376/// enclosing lexical scope. 'CATEGORY' and 'METRIC' must be
377/// null-terminated strings of a type convertible to 'const char *',
378/// while 'TIME_UNITS' is assumed to be of a type convertible to the
379/// enumerated type 'balm::StopwatchScopedGuard::Units'. If the default
380/// metrics manager has not been initialized, or the identified
381/// 'CATEGORY' is disabled, this macro has no effect. Note that
382/// this operation looks up the 'CATEGORY' and 'METRIC' on *each*
383/// application, resulting in (unnecessary) additional runtime overhead
384/// (if the 'CATEGORY' and 'METRIC' values are always the same for a
385/// particular point of call). Also note that 'TIME_UNITS' indicates the
386/// scale of value to report, but does *not* affect the precision of the
387/// elapsed time measurement.
388///
389/// BALM_METRICS_DYNAMIC_TIME_BLOCK_SECONDS(CATEGORY, METRIC)
390/// The behavior of this macro is logically equivalent to
391/// 'BALM_METRICS_DYNAMIC_TIME_BLOCK' called with
392/// 'balm::StopwatchScopedGuard::k_SECONDS'.
393///
394/// BALM_METRICS_DYNAMIC_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC)
395/// The behavior of this macro is logically equivalent to
396/// 'BALM_METRICS_DYNAMIC_TIME_BLOCK' called with
397/// 'balm::StopwatchScopedGuard::k_MILLISECONDS'.
398///
399/// BALM_METRICS_DYNAMIC_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC)
400/// The behavior of this macro is logically equivalent to
401/// 'BALM_METRICS_DYNAMIC_TIME_BLOCK' called with
402/// 'balm::StopwatchScopedGuard::k_MICROSECONDS'.
403///
404/// BALM_METRICS_DYNAMIC_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC)
405/// The behavior of this macro is logically equivalent to
406/// 'BALM_METRICS_DYNAMIC_TIME_BLOCK' called with
407/// 'balm::StopwatchScopedGuard::k_NANOSECONDS'.
408/// @endcode
409///
410/// ## Usage {#balm_metrics-usage}
411///
412///
413/// This section illustrates intended use of this component.
414///
415/// ### Example 1: Create and Configure the Default balm::MetricsManager Instance {#balm_metrics-example-1-create-and-configure-the-default-balm-metricsmanager-instance}
416///
417///
418/// This example demonstrates how to create the default `balm::MetricsManager`
419/// instance and perform a trivial configuration.
420///
421/// First we create a `balm::DefaultMetricsManagerScopedGuard`, which manages
422/// the lifetime of the default metrics manager instance. At construction, we
423/// provide this guard with an output stream (`stdout`) to which the default
424/// metrics manager will publish metrics. Note that the default metrics
425/// manager is intended to be created and destroyed by the *owner* of `main`:
426/// An instance of the manager should be created during the initialization of
427/// an application (while the task has a single thread) and destroyed just
428/// prior to termination (when there is similarly a single thread).
429/// @code
430/// int main(int argc, char *argv[])
431/// {
432/// // ...
433///
434/// balm::DefaultMetricsManagerScopedGuard managerGuard(bsl::cout);
435/// @endcode
436/// Once the default manager object has been created, it can be accessed using
437/// the `instance` operation.
438/// @code
439/// balm::MetricsManager *manager =
440/// balm::DefaultMetricsManager::instance();
441/// assert(0 != manager);
442/// @endcode
443/// Note that the default metrics manager will be released when the
444/// `managerGuard` exits this scoped and is destroyed. Clients that choose to
445/// explicitly call `balm::DefaultMetricsManager::create()` must also explicitly
446/// call `balm::DefaultMetricsManager::release()`.
447///
448/// ### Example 2: Updating a Metric {#balm_metrics-example-2-updating-a-metric}
449///
450///
451/// Once a metrics manager is initialized, we can use the various macros to
452/// record metric values. In this second example, we collect metrics from a
453/// hypothetical event-processing function. We use `BALM_METRICS_UPDATE` to
454/// record the size of the data being processed to a metric named "msgSize",
455/// and the elapsed time (in milliseconds) to process the event to a metric
456/// named "elapsedTime". Finally, we use `BALM_METRICS_INCREMENT` to record a
457/// count of failures to a metric named "failureCount". Note that we do not use
458/// the `*_DYNAMIC_*` variants of the `BALM_METRICS_UPDATE` or
459/// `BALM_METRICS_INCREMENT` macros because the category and metric names are
460/// constant across all applications of the macro at a particular instantiation
461/// point (the `DYNAMIC` variants look up the category and metric name on each
462/// application, which would incur unnecessary runtime overhead).
463/// @code
464/// int processEvent(int eventId, const bsl::string& eventMessage)
465/// // Process the event described by the specified 'eventId' and
466/// // 'eventMessage'. Return 0 on success, and a non-zero
467/// // value otherwise.
468/// {
469/// (void)eventId;
470///
471/// int returnCode = 0;
472///
473/// BALM_METRICS_UPDATE("processEvent",
474/// "msgSize",
475/// static_cast<double>(eventMessage.size()));
476/// BALM_METRICS_TIME_BLOCK_MILLISECONDS("processingEvent", "elapsedTime");
477///
478/// // Process 'data'.
479///
480/// if (0 != returnCode) {
481/// BALM_METRICS_INCREMENT("processEvent", "failureCount");
482/// }
483///
484/// return returnCode;
485/// }
486/// @endcode
487///
488/// ### Example 3: Using BALM_METRICS_IF_CATEGORY_ENABLED {#balm_metrics-example-3-using-balm_metrics_if_category_enabled}
489///
490///
491/// In this next example, we use `BALM_METRICS_IF_CATEGORY_ENABLED` to
492/// conditionally disable a (relatively) expensive operation involved in
493/// computing a metric value. The `processEvent2` function, defined below, uses
494/// a `bsls::Stopwatch` to record the elapsed system, user, and wall times,
495/// associated with processing the event. The system calls used (via
496/// `bsls::Stopwatch`) to record the elapsed time may be relatively expensive,
497/// so we use `BALM_METRICS_IF_CATEGORY_ENABLED` to ensure we perform those
498/// operations only if metrics collection is enabled. Finally, we use
499/// `BALM_METRICS_UPDATE3` to update the three metrics, which is (slightly) more
500/// efficient than updating each metric individually using `BALM_METRIC_UPDATE`.
501/// @code
502/// int processEvent2(int eventId, const bsl::string& eventMessage)
503/// // Process the event described by the specified 'eventId' and
504/// // 'eventMessage'. Return 0 on success, and a non-zero
505/// // value otherwise.
506/// {
507/// (void)eventId;
508/// (void)eventMessage;
509///
510/// int returnCode = 0;
511///
512/// bsls::Stopwatch stopwatch;
513/// BALM_METRICS_IF_CATEGORY_ENABLED("processEvent2") {
514/// stopwatch.start(true);
515/// }
516///
517/// // Process 'data'.
518///
519/// BALM_METRICS_IF_CATEGORY_ENABLED("processEvent2") {
520/// double systemTime, userTime, wallTime;
521/// stopwatch.accumulatedTimes(&systemTime, &userTime, &wallTime);
522/// BALM_METRICS_UPDATE3("processEvent2",
523/// "systemTime", systemTime,
524/// "userTime", userTime,
525/// "wallTime", wallTime);
526/// }
527///
528/// return returnCode;
529/// }
530/// @endcode
531/// @}
532/** @} */
533/** @} */
534
535/** @addtogroup bal
536 * @{
537 */
538/** @addtogroup balm
539 * @{
540 */
541/** @addtogroup balm_metrics
542 * @{
543 */
544
545#include <balscm_version.h>
546
547#include <balm_category.h>
548#include <balm_collector.h>
552#include <balm_metricid.h>
553#include <balm_metricregistry.h>
554#include <balm_metricsmanager.h>
555#include <balm_publicationtype.h>
557
558#include <bsls_atomic.h>
559#include <bsls_performancehint.h>
560#include <bsls_platform.h>
561#include <bsls_spinlock.h>
562
563 // ================================
564 // BALM_METRICS_IF_CATEGORY_ENABLED
565 // ================================
566
567#define BALM_METRICS_IF_CATEGORY_ENABLED(CATEGORY) \
568 BALM_METRICS_IF_CATEGORY_ENABLED_IMP( \
569 CATEGORY, BALM_METRICS_UNIQUE_NAME(categoryHolder))
570
571 // ===================
572 // BALM_METRICS_UPDATE
573 // ===================
574
575// Note that the static collector address must be assigned *before*
576// initializing category holder to ensure initialization is thread safe.
577#define BALM_METRICS_UPDATE(CATEGORY, METRIC1, VALUE1) do { \
578 using namespace BloombergLP; \
579 typedef balm::Metrics_Helper Helper; \
580 static balm::CategoryHolder holder = { false, 0, 0 }; \
581 static bsls::AtomicPointer<balm::Collector> collector1; \
582 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
583 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
584 bsls::SpinLockGuard guard(&lock); \
585 if (0 == holder.category()) { \
586 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
587 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
588 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
589 Helper::initializeCategoryHolder(&holder, CATEGORY); \
590 } \
591 } \
592 if (holder.enabled()) { \
593 collector1->update(VALUE1); \
594 } \
595 } while (0)
596
597#define BALM_METRICS_UPDATE2(CATEGORY, METRIC1, VALUE1, METRIC2, VALUE2) do { \
598 using namespace BloombergLP; \
599 typedef balm::Metrics_Helper Helper; \
600 static balm::CategoryHolder holder = { false, 0, 0 }; \
601 static bsls::AtomicPointer<balm::Collector> collector1; \
602 static bsls::AtomicPointer<balm::Collector> collector2; \
603 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
604 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
605 bsls::SpinLockGuard guard(&lock); \
606 if (0 == holder.category()) { \
607 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
608 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
609 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
610 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
611 collector2 = Helper::getCollector(CATEGORY, METRIC2); \
612 Helper::initializeCategoryHolder(&holder, CATEGORY); \
613 } \
614 } \
615 if (holder.enabled()) { \
616 collector1->update(VALUE1); \
617 collector2->update(VALUE2); \
618 } \
619 } while (0)
620
621#define BALM_METRICS_UPDATE3(CATEGORY, \
622 METRIC1, \
623 VALUE1, \
624 METRIC2, \
625 VALUE2, \
626 METRIC3, \
627 VALUE3) do { \
628 using namespace BloombergLP; \
629 typedef balm::Metrics_Helper Helper; \
630 static balm::CategoryHolder holder = { false, 0, 0 }; \
631 static bsls::AtomicPointer<balm::Collector> collector1; \
632 static bsls::AtomicPointer<balm::Collector> collector2; \
633 static bsls::AtomicPointer<balm::Collector> collector3; \
634 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
635 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
636 bsls::SpinLockGuard guard(&lock); \
637 if (0 == holder.category()) { \
638 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
639 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
640 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
641 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
642 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
643 collector2 = Helper::getCollector(CATEGORY, METRIC2); \
644 collector3 = Helper::getCollector(CATEGORY, METRIC3); \
645 Helper::initializeCategoryHolder(&holder, CATEGORY); \
646 } \
647 } \
648 if (holder.enabled()) { \
649 collector1->update(VALUE1); \
650 collector2->update(VALUE2); \
651 collector3->update(VALUE3); \
652 } \
653 } while (0)
654
655#define BALM_METRICS_UPDATE4(CATEGORY, \
656 METRIC1, \
657 VALUE1, \
658 METRIC2, \
659 VALUE2, \
660 METRIC3, \
661 VALUE3, \
662 METRIC4, \
663 VALUE4) do { \
664 using namespace BloombergLP; \
665 typedef balm::Metrics_Helper Helper; \
666 static balm::CategoryHolder holder = { false, 0, 0 }; \
667 static bsls::AtomicPointer<balm::Collector> collector1; \
668 static bsls::AtomicPointer<balm::Collector> collector2; \
669 static bsls::AtomicPointer<balm::Collector> collector3; \
670 static bsls::AtomicPointer<balm::Collector> collector4; \
671 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
672 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
673 bsls::SpinLockGuard guard(&lock); \
674 if (0 == holder.category()) { \
675 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
676 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
677 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
678 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
679 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
680 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
681 collector2 = Helper::getCollector(CATEGORY, METRIC2); \
682 collector3 = Helper::getCollector(CATEGORY, METRIC3); \
683 collector4 = Helper::getCollector(CATEGORY, METRIC4); \
684 Helper::initializeCategoryHolder(&holder, CATEGORY); \
685 } \
686 } \
687 if (holder.enabled()) { \
688 collector1->update(VALUE1); \
689 collector2->update(VALUE2); \
690 collector3->update(VALUE3); \
691 collector4->update(VALUE4); \
692 } \
693 } while (0)
694
695#define BALM_METRICS_UPDATE5(CATEGORY, \
696 METRIC1, \
697 VALUE1, \
698 METRIC2, \
699 VALUE2, \
700 METRIC3, \
701 VALUE3, \
702 METRIC4, \
703 VALUE4, \
704 METRIC5, \
705 VALUE5) do { \
706 using namespace BloombergLP; \
707 typedef balm::Metrics_Helper Helper; \
708 static balm::CategoryHolder holder = { false, 0, 0 }; \
709 static bsls::AtomicPointer<balm::Collector> collector1; \
710 static bsls::AtomicPointer<balm::Collector> collector2; \
711 static bsls::AtomicPointer<balm::Collector> collector3; \
712 static bsls::AtomicPointer<balm::Collector> collector4; \
713 static bsls::AtomicPointer<balm::Collector> collector5; \
714 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
715 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
716 bsls::SpinLockGuard guard(&lock); \
717 if (0 == holder.category()) { \
718 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
719 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
720 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
721 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
722 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
723 Helper::logEmptyName(METRIC5, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
724 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
725 collector2 = Helper::getCollector(CATEGORY, METRIC2); \
726 collector3 = Helper::getCollector(CATEGORY, METRIC3); \
727 collector4 = Helper::getCollector(CATEGORY, METRIC4); \
728 collector5 = Helper::getCollector(CATEGORY, METRIC5); \
729 Helper::initializeCategoryHolder(&holder, CATEGORY); \
730 } \
731 } \
732 if (holder.enabled()) { \
733 collector1->update(VALUE1); \
734 collector2->update(VALUE2); \
735 collector3->update(VALUE3); \
736 collector4->update(VALUE4); \
737 collector5->update(VALUE5); \
738 } \
739 } while (0)
740
741#define BALM_METRICS_UPDATE6(CATEGORY, \
742 METRIC1, \
743 VALUE1, \
744 METRIC2, \
745 VALUE2, \
746 METRIC3, \
747 VALUE3, \
748 METRIC4, \
749 VALUE4, \
750 METRIC5, \
751 VALUE5, \
752 METRIC6, \
753 VALUE6) do { \
754 using namespace BloombergLP; \
755 typedef balm::Metrics_Helper Helper; \
756 static balm::CategoryHolder holder = { false, 0, 0 }; \
757 static bsls::AtomicPointer<balm::Collector> collector1; \
758 static bsls::AtomicPointer<balm::Collector> collector2; \
759 static bsls::AtomicPointer<balm::Collector> collector3; \
760 static bsls::AtomicPointer<balm::Collector> collector4; \
761 static bsls::AtomicPointer<balm::Collector> collector5; \
762 static bsls::AtomicPointer<balm::Collector> collector6; \
763 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
764 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
765 bsls::SpinLockGuard guard(&lock); \
766 if (0 == holder.category()) { \
767 Helper::logEmptyName(CATEGORY, Helper::e_TYPE_CATEGORY, \
768 __FILE__, __LINE__); \
769 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
770 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
771 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
772 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
773 Helper::logEmptyName(METRIC5, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
774 Helper::logEmptyName(METRIC6, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
775 collector1 = Helper::getCollector(CATEGORY, METRIC1); \
776 collector2 = Helper::getCollector(CATEGORY, METRIC2); \
777 collector3 = Helper::getCollector(CATEGORY, METRIC3); \
778 collector4 = Helper::getCollector(CATEGORY, METRIC4); \
779 collector5 = Helper::getCollector(CATEGORY, METRIC5); \
780 collector6 = Helper::getCollector(CATEGORY, METRIC6); \
781 Helper::initializeCategoryHolder(&holder, CATEGORY); \
782 } \
783 } \
784 if (holder.enabled()) { \
785 collector1->update(VALUE1); \
786 collector2->update(VALUE2); \
787 collector3->update(VALUE3); \
788 collector4->update(VALUE4); \
789 collector5->update(VALUE5); \
790 collector6->update(VALUE6); \
791 } \
792 } while (0)
793
794#define BALM_METRICS_TYPED_UPDATE(CATEGORY, METRIC, VALUE, PREFERRED_TYPE) \
795 do { \
796 using namespace BloombergLP; \
797 typedef balm::Metrics_Helper Helper; \
798 static balm::CategoryHolder holder = { false, 0, 0 }; \
799 static bsls::AtomicPointer<balm::Collector> collector1; \
800 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
801 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
802 bsls::SpinLockGuard guard(&lock); \
803 if (0 == holder.category()) { \
804 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
805 Helper::logEmptyName(METRIC, Helper::e_TYPE_METRIC, __FILE__, __LINE__); \
806 collector1 = Helper::getCollector(CATEGORY, METRIC); \
807 Helper::setPublicationType(collector1->metricId(), PREFERRED_TYPE); \
808 Helper::initializeCategoryHolder(&holder, CATEGORY); \
809 } \
810 } \
811 if (holder.enabled()) { \
812 collector1->update(VALUE); \
813 } \
814 } while (0)
815
816#define BALM_METRICS_DYNAMIC_UPDATE(CATEGORY, METRIC, VALUE) do { \
817 using namespace BloombergLP; \
818 if (balm::DefaultMetricsManager::instance()) { \
819 balm::CollectorRepository& repository = \
820 balm::DefaultMetricsManager::instance()->collectorRepository(); \
821 balm::Collector *collector = repository.getDefaultCollector( \
822 (CATEGORY), (METRIC));\
823 if (collector->metricId().category()->enabled()) { \
824 collector->update((VALUE)); \
825 } \
826 } \
827 } while(0)
828
829 // =======================
830 // BALM_METRICS_INT_UPDATE
831 // =======================
832
833#define BALM_METRICS_INT_UPDATE(CATEGORY, METRIC1, VALUE1) do { \
834 using namespace BloombergLP; \
835 typedef balm::Metrics_Helper Helper; \
836 static balm::CategoryHolder holder = { false, 0, 0 }; \
837 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
838 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
839 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
840 bsls::SpinLockGuard guard(&lock); \
841 if (0 == holder.category()) { \
842 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
843 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
844 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
845 Helper::initializeCategoryHolder(&holder, CATEGORY); \
846 } \
847 } \
848 if (holder.enabled()) { \
849 collector1->update(VALUE1); \
850 } \
851 } while (0)
852
853#define BALM_METRICS_INT_UPDATE2(CATEGORY, \
854 METRIC1, \
855 VALUE1, \
856 METRIC2, \
857 VALUE2) do { \
858 using namespace BloombergLP; \
859 typedef balm::Metrics_Helper Helper; \
860 static balm::CategoryHolder holder = { false, 0, 0 }; \
861 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
862 static bsls::AtomicPointer<balm::IntegerCollector> collector2; \
863 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
864 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
865 bsls::SpinLockGuard guard(&lock); \
866 if (0 == holder.category()) { \
867 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
868 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
869 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
870 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
871 collector2 = Helper::getIntegerCollector(CATEGORY, METRIC2); \
872 Helper::initializeCategoryHolder(&holder, CATEGORY); \
873 } \
874 } \
875 if (holder.enabled()) { \
876 collector1->update(VALUE1); \
877 collector2->update(VALUE2); \
878 } \
879 } while (0)
880
881#define BALM_METRICS_INT_UPDATE3(CATEGORY, \
882 METRIC1, \
883 VALUE1, \
884 METRIC2, \
885 VALUE2, \
886 METRIC3, \
887 VALUE3) do { \
888 using namespace BloombergLP; \
889 typedef balm::Metrics_Helper Helper; \
890 static balm::CategoryHolder holder = { false, 0, 0 }; \
891 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
892 static bsls::AtomicPointer<balm::IntegerCollector> collector2; \
893 static bsls::AtomicPointer<balm::IntegerCollector> collector3; \
894 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
895 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
896 bsls::SpinLockGuard guard(&lock); \
897 if (0 == holder.category()) { \
898 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
899 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
900 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
901 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
902 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
903 collector2 = Helper::getIntegerCollector(CATEGORY, METRIC2); \
904 collector3 = Helper::getIntegerCollector(CATEGORY, METRIC3); \
905 Helper::initializeCategoryHolder(&holder, CATEGORY); \
906 } \
907 } \
908 if (holder.enabled()) { \
909 collector1->update(VALUE1); \
910 collector2->update(VALUE2); \
911 collector3->update(VALUE3); \
912 } \
913 } while (0)
914
915#define BALM_METRICS_INT_UPDATE4(CATEGORY, \
916 METRIC1, \
917 VALUE1, \
918 METRIC2, \
919 VALUE2, \
920 METRIC3, \
921 VALUE3, \
922 METRIC4, \
923 VALUE4) do { \
924 using namespace BloombergLP; \
925 typedef balm::Metrics_Helper Helper; \
926 static balm::CategoryHolder holder = { false, 0, 0 }; \
927 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
928 static bsls::AtomicPointer<balm::IntegerCollector> collector2; \
929 static bsls::AtomicPointer<balm::IntegerCollector> collector3; \
930 static bsls::AtomicPointer<balm::IntegerCollector> collector4; \
931 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
932 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
933 bsls::SpinLockGuard guard(&lock); \
934 if (0 == holder.category()) { \
935 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
936 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
937 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
938 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
939 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
940 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
941 collector2 = Helper::getIntegerCollector(CATEGORY, METRIC2); \
942 collector3 = Helper::getIntegerCollector(CATEGORY, METRIC3); \
943 collector4 = Helper::getIntegerCollector(CATEGORY, METRIC4); \
944 Helper::initializeCategoryHolder(&holder, CATEGORY); \
945 } \
946 } \
947 if (holder.enabled()) { \
948 collector1->update(VALUE1); \
949 collector2->update(VALUE2); \
950 collector3->update(VALUE3); \
951 collector4->update(VALUE4); \
952 } \
953 } while (0)
954
955#define BALM_METRICS_INT_UPDATE5(CATEGORY, \
956 METRIC1, \
957 VALUE1, \
958 METRIC2, \
959 VALUE2, \
960 METRIC3, \
961 VALUE3, \
962 METRIC4, \
963 VALUE4, \
964 METRIC5, \
965 VALUE5) do { \
966 using namespace BloombergLP; \
967 typedef balm::Metrics_Helper Helper; \
968 static balm::CategoryHolder holder = { false, 0, 0 }; \
969 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
970 static bsls::AtomicPointer<balm::IntegerCollector> collector2; \
971 static bsls::AtomicPointer<balm::IntegerCollector> collector3; \
972 static bsls::AtomicPointer<balm::IntegerCollector> collector4; \
973 static bsls::AtomicPointer<balm::IntegerCollector> collector5; \
974 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
975 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
976 bsls::SpinLockGuard guard(&lock); \
977 if (0 == holder.category()) { \
978 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
979 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
980 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
981 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
982 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
983 Helper::logEmptyName(METRIC5, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
984 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
985 collector2 = Helper::getIntegerCollector(CATEGORY, METRIC2); \
986 collector3 = Helper::getIntegerCollector(CATEGORY, METRIC3); \
987 collector4 = Helper::getIntegerCollector(CATEGORY, METRIC4); \
988 collector5 = Helper::getIntegerCollector(CATEGORY, METRIC5); \
989 Helper::initializeCategoryHolder(&holder, CATEGORY); \
990 } \
991 } \
992 if (holder.enabled()) { \
993 collector1->update(VALUE1); \
994 collector2->update(VALUE2); \
995 collector3->update(VALUE3); \
996 collector4->update(VALUE4); \
997 collector5->update(VALUE5); \
998 } \
999 } while (0)
1000
1001#define BALM_METRICS_INT_UPDATE6(CATEGORY, \
1002 METRIC1, \
1003 VALUE1, \
1004 METRIC2, \
1005 VALUE2, \
1006 METRIC3, \
1007 VALUE3, \
1008 METRIC4, \
1009 VALUE4, \
1010 METRIC5, \
1011 VALUE5, \
1012 METRIC6, \
1013 VALUE6) do { \
1014 using namespace BloombergLP; \
1015 typedef balm::Metrics_Helper Helper; \
1016 static balm::CategoryHolder holder = { false, 0, 0 }; \
1017 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
1018 static bsls::AtomicPointer<balm::IntegerCollector> collector2; \
1019 static bsls::AtomicPointer<balm::IntegerCollector> collector3; \
1020 static bsls::AtomicPointer<balm::IntegerCollector> collector4; \
1021 static bsls::AtomicPointer<balm::IntegerCollector> collector5; \
1022 static bsls::AtomicPointer<balm::IntegerCollector> collector6; \
1023 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
1024 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
1025 bsls::SpinLockGuard guard(&lock); \
1026 if (0 == holder.category()) { \
1027 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
1028 Helper::logEmptyName(METRIC1, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1029 Helper::logEmptyName(METRIC2, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1030 Helper::logEmptyName(METRIC3, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1031 Helper::logEmptyName(METRIC4, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1032 Helper::logEmptyName(METRIC5, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1033 Helper::logEmptyName(METRIC6, Helper::e_TYPE_METRIC, __FILE__, __LINE__);\
1034 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC1); \
1035 collector2 = Helper::getIntegerCollector(CATEGORY, METRIC2); \
1036 collector3 = Helper::getIntegerCollector(CATEGORY, METRIC3); \
1037 collector4 = Helper::getIntegerCollector(CATEGORY, METRIC4); \
1038 collector5 = Helper::getIntegerCollector(CATEGORY, METRIC5); \
1039 collector6 = Helper::getIntegerCollector(CATEGORY, METRIC6); \
1040 Helper::initializeCategoryHolder(&holder, CATEGORY); \
1041 } \
1042 } \
1043 if (holder.enabled()) { \
1044 collector1->update(VALUE1); \
1045 collector2->update(VALUE2); \
1046 collector3->update(VALUE3); \
1047 collector4->update(VALUE4); \
1048 collector5->update(VALUE5); \
1049 collector6->update(VALUE6); \
1050 } \
1051 } while (0)
1052
1053#define BALM_METRICS_TYPED_INT_UPDATE(CATEGORY, \
1054 METRIC, \
1055 VALUE, \
1056 PREFERRED_TYPE) \
1057do { \
1058 using namespace BloombergLP; \
1059 typedef balm::Metrics_Helper Helper; \
1060 static balm::CategoryHolder holder = { false, 0, 0 }; \
1061 static bsls::AtomicPointer<balm::IntegerCollector> collector1; \
1062 if (0 == holder.category() && balm::DefaultMetricsManager::instance()) { \
1063 static bsls::SpinLock lock = BSLS_SPINLOCK_UNLOCKED; \
1064 bsls::SpinLockGuard guard(&lock); \
1065 if (0 == holder.category()) { \
1066 Helper::logEmptyName(CATEGORY,Helper::e_TYPE_CATEGORY,__FILE__,__LINE__);\
1067 Helper::logEmptyName(METRIC, Helper::e_TYPE_METRIC, __FILE__, __LINE__); \
1068 collector1 = Helper::getIntegerCollector(CATEGORY, METRIC); \
1069 Helper::setPublicationType(collector1->metricId(), PREFERRED_TYPE); \
1070 Helper::initializeCategoryHolder(&holder, CATEGORY); \
1071 } \
1072 } \
1073 if (holder.enabled()) { \
1074 collector1->update(VALUE); \
1075 } \
1076 } while (0)
1077
1078#define BALM_METRICS_DYNAMIC_INT_UPDATE(CATEGORY, METRIC, VALUE) do { \
1079 using namespace BloombergLP; \
1080 if (balm::DefaultMetricsManager::instance()) { \
1081 balm::CollectorRepository& repository = \
1082 balm::DefaultMetricsManager::instance()->collectorRepository(); \
1083 balm::IntegerCollector *collector = \
1084 repository.getDefaultIntegerCollector((CATEGORY), (METRIC)); \
1085 if (collector->metricId().category()->enabled()) { \
1086 collector->update((VALUE)); \
1087 } \
1088 } \
1089 } while (0)
1090
1091#define BALM_METRICS_INCREMENT(CATEGORY, METRIC) \
1092 BALM_METRICS_INT_UPDATE(CATEGORY, METRIC, 1)
1093
1094#define BALM_METRICS_TYPED_INCREMENT(CATEGORY, METRIC, PREFERRED_TYPE) \
1095 BALM_METRICS_TYPED_INT_UPDATE(CATEGORY, METRIC, 1, PREFERRED_TYPE)
1096
1097#define BALM_METRICS_DYNAMIC_INCREMENT(CATEGORY, METRIC) \
1098 BALM_METRICS_DYNAMIC_INT_UPDATE(CATEGORY, METRIC, 1)
1099
1100 // =======================
1101 // BALM_METRICS_TIME_BLOCK
1102 // =======================
1103
1104#define BALM_METRICS_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS) \
1105 BALM_METRICS_TIME_BLOCK_IMP((CATEGORY), \
1106 (METRIC), \
1107 TIME_UNITS, \
1108 BALM_METRICS_UNIQUE_NAME(_bAlM_CoLlEcToR))
1109
1110#define BALM_METRICS_DYNAMIC_TIME_BLOCK(CATEGORY, METRIC, TIME_UNITS) \
1111 BALM_METRICS_DYNAMIC_TIME_BLOCK_IMP( \
1112 (CATEGORY), \
1113 (METRIC), \
1114 TIME_UNITS, \
1115 BALM_METRICS_UNIQUE_NAME(_bAlM_CoLlEcToR))
1116
1117#define BALM_METRICS_TIME_BLOCK_SECONDS(CATEGORY, METRIC) \
1118 BALM_METRICS_TIME_BLOCK((CATEGORY), \
1119 (METRIC), \
1120 BloombergLP::balm::StopwatchScopedGuard::k_SECONDS);
1121
1122#define BALM_METRICS_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC) \
1123 BALM_METRICS_TIME_BLOCK( \
1124 (CATEGORY), \
1125 (METRIC), \
1126 BloombergLP::balm::StopwatchScopedGuard::k_MILLISECONDS);
1127
1128#define BALM_METRICS_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC) \
1129 BALM_METRICS_TIME_BLOCK( \
1130 (CATEGORY), \
1131 (METRIC), \
1132 BloombergLP::balm::StopwatchScopedGuard::k_MICROSECONDS);
1133
1134#define BALM_METRICS_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC) \
1135 BALM_METRICS_TIME_BLOCK( \
1136 (CATEGORY), \
1137 (METRIC), \
1138 BloombergLP::balm::StopwatchScopedGuard::k_NANOSECONDS);
1139
1140#define BALM_METRICS_DYNAMIC_TIME_BLOCK_SECONDS(CATEGORY, METRIC) \
1141 BALM_METRICS_DYNAMIC_TIME_BLOCK( \
1142 (CATEGORY), \
1143 (METRIC), \
1144 BloombergLP::balm::StopwatchScopedGuard::k_SECONDS);
1145
1146#define BALM_METRICS_DYNAMIC_TIME_BLOCK_MILLISECONDS(CATEGORY, METRIC) \
1147 BALM_METRICS_DYNAMIC_TIME_BLOCK( \
1148 (CATEGORY), \
1149 (METRIC), \
1150 BloombergLP::balm::StopwatchScopedGuard::k_MILLISECONDS);
1151
1152#define BALM_METRICS_DYNAMIC_TIME_BLOCK_MICROSECONDS(CATEGORY, METRIC) \
1153 BALM_METRICS_DYNAMIC_TIME_BLOCK( \
1154 (CATEGORY), \
1155 (METRIC), \
1156 BloombergLP::balm::StopwatchScopedGuard::k_MICROSECONDS);
1157
1158#define BALM_METRICS_DYNAMIC_TIME_BLOCK_NANOSECONDS(CATEGORY, METRIC) \
1159 BALM_METRICS_DYNAMIC_TIME_BLOCK( \
1160 (CATEGORY), \
1161 (METRIC), \
1162 BloombergLP::balm::StopwatchScopedGuard::k_NANOSECONDS);
1163
1164 // =====================
1165 // Macro Implementations
1166 // =====================
1167
1168#define BALM_METRICS_IF_CATEGORY_ENABLED_IMP(CATEGORY, HOLDER_NAME) \
1169 static BloombergLP::balm::CategoryHolder HOLDER_NAME = { false, 0, 0 }; \
1170 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(!HOLDER_NAME.category()) \
1171 && BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY( \
1172 BloombergLP::balm::DefaultMetricsManager::instance() != 0)) {\
1173 BloombergLP::balm::Metrics_Helper::initializeCategoryHolder( \
1174 &HOLDER_NAME, CATEGORY); \
1175 } \
1176 if (HOLDER_NAME.enabled())
1177
1178// Declare a static pointer to a 'balm::Collector' with the specified
1179// 'VARIABLE_NAME' and an initial value of 0. If the default metrics manager
1180// is available and the declared pointer variable (named 'VARIABLE_NAME') is 0,
1181// assign to 'VARIABLE_NAME' the address of a collector for the specified
1182// 'CATEGORY' and 'METRIC'. Finally, declare a 'balm::StopwatchScopedGuard'
1183// object with a unique variable name and supply its constructor the collector
1184// address held in 'VARIABLE_NAME' and the specified 'TIME_UNITS'.
1185#define BALM_METRICS_TIME_BLOCK_IMP(CATEGORY, \
1186 METRIC, \
1187 TIME_UNITS, \
1188 VARIABLE_NAME) \
1189 static BloombergLP::balm::Collector *VARIABLE_NAME = 0; \
1190 if (BloombergLP::balm::DefaultMetricsManager::instance()) { \
1191 using namespace BloombergLP; \
1192 typedef balm::Metrics_Helper Helper; \
1193 static balm::CategoryHolder holder = { false, 0, 0 }; \
1194 if (0 == holder.category()) { \
1195 balm::CollectorRepository& repository = \
1196 balm::DefaultMetricsManager::instance()->collectorRepository(); \
1197 VARIABLE_NAME = repository.getDefaultCollector((CATEGORY), \
1198 (METRIC)); \
1199 Helper::initializeCategoryHolder(&holder, CATEGORY); \
1200 } \
1201 } \
1202 else { \
1203 VARIABLE_NAME = 0; \
1204 } \
1205 BloombergLP::balm::StopwatchScopedGuard \
1206 BALM_METRICS_UNIQUE_NAME(__bAlM_gUaRd)(VARIABLE_NAME, TIME_UNITS);
1207
1208// Declare a pointer to a 'balm::Collector' with the specified 'VARIABLE_NAME'.
1209// If the default metrics manager is available, assign to the declared pointer
1210// variable (named 'VARIABLE_NAME') the address of a collector for the
1211// specified 'CATEGORY' and 'METRIC'. Finally, declare a
1212// 'balm::StopwatchScopedGuard' object with a unique variable name and supply
1213// its constructor the collector address held in 'VARIABLE_NAME' and the
1214// specified 'TIME_UNITS'.
1215#define BALM_METRICS_DYNAMIC_TIME_BLOCK_IMP(CATEGORY, \
1216 METRIC, \
1217 TIME_UNITS, \
1218 VARIABLE_NAME) \
1219 BloombergLP::balm::Collector *VARIABLE_NAME = 0; \
1220 if (BloombergLP::balm::DefaultMetricsManager::instance()) { \
1221 using namespace BloombergLP; \
1222 balm::CollectorRepository& repository = \
1223 balm::DefaultMetricsManager::instance()->collectorRepository(); \
1224 VARIABLE_NAME = repository.getDefaultCollector((CATEGORY), \
1225 (METRIC)); \
1226 } \
1227 BloombergLP::balm::StopwatchScopedGuard \
1228 BALM_METRICS_UNIQUE_NAME(__bAlM_gUaRd)(VARIABLE_NAME, TIME_UNITS);
1229
1230 // ------------------------
1231 // Unique line number macro
1232 // ------------------------
1233
1234#if defined(BSLS_PLATFORM_CMP_MSVC)
1235// MSVC: __LINE__ macro breaks when /ZI is used (see Q199057 or KB199057)
1236// Fortunately the __COUNTER__ extension provided by MSVC is even better.
1237# define BALM_METRICS_UNIQNUM __COUNTER__
1238#else
1239# define BALM_METRICS_UNIQNUM __LINE__
1240#endif
1241
1242 // ----------------------------------
1243 // Token concatenation support macros
1244 // ----------------------------------
1245
1246// Second layer needed to ensure that arguments are expanded before
1247// concatenation.
1248#define BALM_METRICS_CAT(X, Y) BALM_METRICS_CAT_IMP(X, Y)
1249#define BALM_METRICS_CAT_IMP(X, Y) X##Y
1250
1251 // ----------------------------------
1252 // Unique variable name support macro
1253 // ----------------------------------
1254
1255// Create a unique variable name by concatenating the specified 'X' string
1256// with a unique integer value.
1257#define BALM_METRICS_UNIQUE_NAME(X) \
1258 BALM_METRICS_CAT(X, BALM_METRICS_UNIQNUM)
1259
1260
1261
1262namespace balm {
1263 // =====================
1264 // struct Metrics_Helper
1265 // =====================
1266
1267/// This `struct` provides a namespace for a suite of functions used in the
1268/// implementation of the macros defined in this component.
1269///
1270/// This type is an implementation detail and *must* *not* be used
1271/// (directly) by clients outside of this component.
1272///
1273/// See @ref balm_metrics
1275
1276 // TYPES
1278 // Enumeration indicating the type of identifier supplied to
1279 // 'logEmptyName'.
1280
1282 e_TYPE_METRIC = 1
1283#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1286#endif
1288
1289 // CLASS METHODS
1290
1291 /// Load into the specified `holder` the address and enabled status of
1292 /// the specified `category`, and add `holder` to the list of category holders for `category`.
1293 ///
1294 /// \pre The behavior is undefined unless the balm
1295 /// metrics manager singleton is valid.
1296 static void initializeCategoryHolder(CategoryHolder *holder,
1297 const char *category);
1298
1299 /// Return the address of the default metrics collector for the metric
1300 /// identified by the specified `category` and `metric` names.
1301 ///
1302 /// \pre The behavior is undefined unless the `balm` metrics manager singleton is
1303 /// valid.
1304 static Collector *getCollector(const char *category,
1305 const char *metric);
1306
1307 /// Return the address of the default integer metrics collector for the
1308 /// metric identified by the specified `category` and `metric` names.
1309 ///
1310 /// \pre The behavior is undefined unless the `balm` metrics manager
1311 /// singleton is valid.
1312 static IntegerCollector *getIntegerCollector(const char *category,
1313 const char *metric);
1314
1315 /// Set the publication type for the metric identified by the specified `id` to the specified `type`.
1316 ///
1317 /// \pre The behavior is undefined unless the
1318 /// `balm` metrics manager singleton is valid, and `id` is a valid
1319 /// identifier supplied by the singleton metrics manager.
1320 static void setPublicationType(const MetricId& id,
1322
1323 /// If the specified `name` is empty or contains only whitespace, then
1324 /// log a warning message indicating whether `name` is a category or a
1325 /// metric, depending on the specified `type`, and the location at which
1326 /// this function is called, indicated by the specified `file` and
1327 /// `line`; otherwise, do nothing.
1328 static void logEmptyName(const char *name,
1329 NameType type,
1330 const char *file,
1331 int line);
1332};
1333
1334// ============================================================================
1335// INLINE DEFINITIONS
1336// ============================================================================
1337
1338 // ---------------------
1339 // struct Metrics_Helper
1340 // ---------------------
1341
1342// CLASS METHODS
1343inline
1345 const char *category)
1346{
1348 MetricRegistry& registry = manager->metricRegistry();
1349 registry.registerCategoryHolder(registry.getCategory(category), holder);
1350}
1351
1352inline
1354 const char *metric)
1355{
1357 return manager->collectorRepository().getDefaultCollector(category,
1358 metric);
1359}
1360
1361inline
1363 const char *metric)
1364{
1366 return manager->collectorRepository().getDefaultIntegerCollector(category,
1367 metric);
1368}
1369
1370inline
1373{
1375 return manager->metricRegistry().setPreferredPublicationType(id, type);
1376
1377}
1378
1379} // close package namespace
1380
1381
1382#if !defined(BSL_DOUBLE_UNDERSCORE_XLAT) || 1 == BSL_DOUBLE_UNDERSCORE_XLAT
1383#define BALM_METRICS__UNIQUE_NAME(X) BALM_METRICS_UNIQUE_NAME(X)
1384#endif
1385
1386#endif
1387
1388// ----------------------------------------------------------------------------
1389// Copyright 2015 Bloomberg Finance L.P.
1390//
1391// Licensed under the Apache License, Version 2.0 (the "License");
1392// you may not use this file except in compliance with the License.
1393// You may obtain a copy of the License at
1394//
1395// http://www.apache.org/licenses/LICENSE-2.0
1396//
1397// Unless required by applicable law or agreed to in writing, software
1398// distributed under the License is distributed on an "AS IS" BASIS,
1399// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1400// See the License for the specific language governing permissions and
1401// limitations under the License.
1402// ----------------------------- END-OF-FILE ----------------------------------
1403
1404/** @} */
1405/** @} */
1406/** @} */
Definition balm_category.h:263
IntegerCollector * getDefaultIntegerCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:457
Collector * getDefaultCollector(const char *category, const char *metricName)
Definition balm_collectorrepository.h:450
Definition balm_collector.h:152
Definition balm_integercollector.h:151
Definition balm_metricid.h:162
Definition balm_metricregistry.h:180
const Category * getCategory(const char *category)
void setPreferredPublicationType(const MetricId &metric, PublicationType::Value type)
void registerCategoryHolder(const Category *category, CategoryHolder *holder)
Definition balm_metricsmanager.h:490
CollectorRepository & collectorRepository()
Definition balm_metricsmanager.h:1032
MetricRegistry & metricRegistry()
Definition balm_metricsmanager.h:1038
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balm_bdlmmetricsadapter.h:142
static MetricsManager * instance()
Definition balm_defaultmetricsmanager.h:310
Definition balm_metrics.h:1274
static void logEmptyName(const char *name, NameType type, const char *file, int line)
static void setPublicationType(const MetricId &id, PublicationType::Value type)
Definition balm_metrics.h:1371
static Collector * getCollector(const char *category, const char *metric)
Definition balm_metrics.h:1353
NameType
Definition balm_metrics.h:1277
@ e_TYPE_CATEGORY
Definition balm_metrics.h:1281
@ e_TYPE_METRIC
Definition balm_metrics.h:1282
@ TYPE_CATEGORY
Definition balm_metrics.h:1284
@ TYPE_METRIC
Definition balm_metrics.h:1285
static void initializeCategoryHolder(CategoryHolder *holder, const char *category)
Definition balm_metrics.h:1344
static IntegerCollector * getIntegerCollector(const char *category, const char *metric)
Definition balm_metrics.h:1362
Value
Definition balm_publicationtype.h:83