BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_logthrottle.h
Go to the documentation of this file.
1/// @file ball_logthrottle.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_logthrottle.h -*-C++-*-
8#ifndef INCLUDED_BALL_LOGTHROTTLE
9#define INCLUDED_BALL_LOGTHROTTLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_logthrottle ball_logthrottle
15/// @brief Provide throttling equivalents of some of the `ball_log` macros.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_logthrottle
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_logthrottle-purpose"> Purpose</a>
25/// * <a href="#ball_logthrottle-macros"> Macros </a>
26/// * <a href="#ball_logthrottle-description"> Description </a>
27/// * <a href="#ball_logthrottle-throttling-parameters"> Throttling Parameters </a>
28/// * <a href="#ball_logthrottle-throttling-concepts"> Throttling Concepts </a>
29/// * <a href="#ball_logthrottle-thread-safety"> Thread Safety </a>
30/// * <a href="#ball_logthrottle-macro-reference"> Macro Reference </a>
31/// * <a href="#ball_logthrottle-stream-based-throttling-macros"> Stream-Based Throttling Macros </a>
32/// * <a href="#ball_logthrottle-block-style-throttling-macros"> BLOCK-Style Throttling Macros </a>
33/// * <a href="#ball_logthrottle-printf-style-throttling-macros"> printf-Style Throttling Macros </a>
34/// * <a href="#ball_logthrottle-usage"> Usage </a>
35/// * <a href="#ball_logthrottle-example-1-c-stream-style-throttling-macro-usage"> Example 1: C++ Stream-Style Throttling Macro Usage </a>
36///
37/// # Purpose {#ball_logthrottle-purpose}
38/// Provide throttling equivalents of some of the `ball_log` macros.
39///
40/// # Macros {#ball_logthrottle-macros}
41///
42/// - BALL_LOGTHROTTLE_TRACE(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
43/// - BALL_LOGTHROTTLE_DEBUG(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
44/// - BALL_LOGTHROTTLE_INFO(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
45/// - BALL_LOGTHROTTLE_WARN(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
46/// - BALL_LOGTHROTTLE_ERROR(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
47/// - BALL_LOGTHROTTLE_FATAL(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
48/// - BALL_LOGTHROTTLE_STREAM(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
49///
50/// BALL_LOGTHROTTLE_TRACE_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
51/// BALL_LOGTHROTTLE_DEBUG_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
52/// BALL_LOGTHROTTLE_INFO_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
53/// BALL_LOGTHROTTLE_WARN_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
54/// BALL_LOGTHROTTLE_ERROR_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
55/// BALL_LOGTHROTTLE_FATAL_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
56/// BALL_LOGTHROTTLE_BLOCK(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE)
57///
58/// BALL_LOGTHROTTLEVA_TRACE(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
59/// BALL_LOGTHROTTLEVA_DEBUG(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
60/// BALL_LOGTHROTTLEVA_INFO(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
61/// BALL_LOGTHROTTLEVA_WARN(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
62/// BALL_LOGTHROTTLEVA_ERROR(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
63/// BALL_LOGTHROTTLEVA_FATAL(MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
64/// BALL_LOGTHROTTLEVA(SEV, MAX_SIMULTANEOUS_MSGS, NANOSEC_PER_MESSAGE, ...)
65///
66/// @see ball_log, bdlmt_throttle
67///
68/// # Description {#ball_logthrottle-description}
69/// This component provides numerous macros for performing logging
70/// where the number of messages logged is "throttled", meaning that the number
71/// of messages that will be logged within a given time interval is limited.
72/// The macros in this component are all analogous to corresponding macros in
73/// `ball_log`. For example, the throttling version of `BALL_LOG_INFO` is
74/// `BALL_LOGTHROTTLE_INFO`, and the throttling version of `BALL_LOGVA` is
75/// `BALL_LOGTHROTTLEVA`.
76///
77/// Each log message has a `SEVERITY` associated with it (see @ref ball_severity
78/// for the definitions of the six standard severities). Those macros that
79/// don't contain a `SEVERITY` in their name are passed an integral severity
80/// value in the range `[0 .. 255]`, with suggested values defined in
81/// `ball::Severity`, as their first argument. The next two arguments,
82/// `MAX_SIMULTANEOUS_MESSAGES` and `NANOSECONDS_PER_MESSAGE`, are described
83/// immediately below.
84///
85/// Each invocation of any of the macros provided by this component instantiates
86/// its own `bdlmt::Throttle` object to effect the throttling behavior. Note
87/// that each throttle object is statically declared, so it is shared by all
88/// threads.
89///
90/// ## Throttling Parameters {#ball_logthrottle-throttling-parameters}
91///
92///
93/// Clients supply the throttling macros with configuration values for
94/// `MAX_SIMULTANEOUS_MESSAGESS`, and `NANOSECONDS_PER_MESSAGE`. The macros
95/// keep track of the number of logged messages, and over time throttles the
96/// average number of messages permitted to a rate of `1 / NANOSEC_PER_MESSAGE`
97/// (messages-per-nanosecond). So, for example, to limit the average rate of
98/// messages permitted to 10 messages per second (10 actions / one billion
99/// nanoseconds), the value for `NANOSECONDS_PER_MESSAGE` would be
100/// 100,000,000 (which is one billion / 10).
101///
102/// As client code publishes a log message from a macro, the macro accumulates a
103/// time debt for each message, which dissipates over time. The maximum value
104/// for this time debt is given by
105/// `MAX_SIMULTANEOUS_MESSAGES * NANOSECONDS_PER_MESSAGE`. The
106/// `MAX_SIMULTANEOUS_MESSAGES` configuration parameter thereby limits the
107/// maximum number of messages that can be simultaneously published.
108///
109/// `MAX_SIMULTANEOUS_MESSAGES`: configures (an approximation of) the maximum
110/// number of messages that can be simultaneously logged.
111///
112/// `NANOSECONDS_PER_MESSAGE`: configures (an approximation of) the minimum
113/// period between messages (and, by extension, the maximum rate).
114///
115/// So, for example:
116/// @code
117/// static const bsls::Types::Int64 k_NS_PER_S =
118/// bdlt::TimeUnitRatio::k_NANOSECONDS_PER_SECOND;
119///
120/// // Log 1 WARN-level message every second on average:
121/// BALL_LOGTHROTTLE_WARN(1, k_NS_PER_S) << "message 1";
122///
123/// // Log 1 WARN-level message every second on average, but allow a "burst"
124/// // of up to 2 messages to be published simultaneously:
125/// BALL_LOGTHROTTLE_WARN(2, k_NS_PER_S) << "message 2";
126/// @endcode
127/// Notice that `NANOSECONDS_PER_MESSAGE` controls an approximation for the
128/// average rate of messages to be published, and `MAX_SIMULTANEOUS_MESSAGES`
129/// controls an approximation for the size of bursts of messages to be
130/// published.
131///
132/// Note that this component is built on top of @ref bdlmt_throttle , and mirrors
133/// its behavior.
134///
135/// ## Throttling Concepts {#ball_logthrottle-throttling-concepts}
136///
137///
138/// The behavior implemented by this component is known as a "leaky-bucket"
139/// algorithm: permitted actions place water in the bucket, the passage
140/// of time drains water from the bucket, and the bucket has a maximum capacity.
141/// Actions are permitted when there is enough empty room in the bucket that
142/// the water placed won't overflow it. A leaky bucket is an efficiently
143/// implementable approximation for allowing a certain number of actions over a
144/// window of time.
145///
146/// ## Thread Safety {#ball_logthrottle-thread-safety}
147///
148///
149/// All macros defined in this component are thread-safe, and can be invoked
150/// concurrently by multiple threads.
151///
152/// ## Macro Reference {#ball_logthrottle-macro-reference}
153///
154///
155/// The following constraints pertain to all of the macros defined in this
156/// component.
157///
158/// * `MAX_SIMULTANEOUS_MESSAGES` and `NANOSECONDS_PER_MESSAGE` must be
159/// compile-time constants, and may not contain any floating-point
160/// subexpressions.
161/// * `MAX_SIMULTANEOUS_MESSAGES`, `NANOSECONDS_PER_MESSAGE`, and `SEVERITY`
162/// are of types `int`, `bsls::Types::Int64`, and `int`, respectively.
163/// * The behavior is undefined unless `SEVERITY` is in the range `[0 .. 255]`,
164/// `0 <= MAX_SIMULTANEOUS_MESSAGES`, `0 <= NANOSECONDS_PER_MESSAGE`,
165/// `0 < MAX_SIMULTANEOUS_MESSAGES || 0 < NANOSECONDS_PER_MESSAGE`, and
166/// `MAX_SIMULTANEOUS_MESSAGES * NANOSECONDS_PER_MESSAGE <= LLONG_MAX`.
167///
168/// Each `BALL_LOGTHROTTLE_*` is analogous to the corresponding `BALL_LOG_*`
169/// macro, except that they take two additional throttle-related arguments,
170/// `MAX_SIMULTANEOUS_MESSAGES` and `NANOSECONDS_PER_MESSAGE`, described above.
171///
172/// ### Stream-Based Throttling Macros {#ball_logthrottle-stream-based-throttling-macros}
173///
174///
175/// The following macros mirror the corresponding `BALL_LOG_<SEVERITY>` macros:
176/// @code
177/// BALL_LOGTHROTTLE_<SEVERITY>(MAX_SIMULTANEOUS_MESSAGES,
178/// NANOSECONDS_PER_MESSAGE) << X << Y ... ;
179/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
180/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}, where
181/// `X, Y, ...` represents any sequence of values for which `operator<<` is
182/// defined. If the throttle permits a message to be logged, the resulting
183/// formatted message is logged with the severity indicated by the name of
184/// the macro (e.g., `BALL_LOGTHROTTLE_ERROR` logs with severity
185/// `ball::Severity::e_ERROR`).
186///
187/// BALL_LOGTHROTTLE_STREAM(SEVERITY,
188/// MAX_SIMULTANEOUS_MESSAGES,
189/// NANOSECONDS_PER_MESSAGE) << X << Y ... ;
190/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
191/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}, where
192/// `X, Y, ...` represents any sequence of values for which `operator<<` is
193/// defined. If the throttle permits a message to be logged, the resulting
194/// formatted message is logged with the specified `SEVERITY`.
195/// @endcode
196///
197/// ### BLOCK-Style Throttling Macros {#ball_logthrottle-block-style-throttling-macros}
198///
199///
200/// The following macros mirror the corresponding `BALL_LOG_*_BLOCK` macros:
201/// @code
202/// BALL_LOGTHROTTLE_<SEVERITY>_BLOCK(MAX_SIMULTANEOUS_MESSAGES,
203/// NANOSECONDS_PER_MESSAGE) <block>
204/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
205/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}, where
206/// any sequence of values for which `operator<<` is defined may be
207/// streamed to `BALL_LOG_OUTPUT_STREAM` within the controlled `<block>`.
208/// If the throttle permits a message to be logged, the resulting formatted
209/// message is logged with the severity indicated by the name of the macro
210/// (e.g., `BALL_LOGTHROTTLE_WARN_BLOCK` logs with severity
211/// `ball::Severity::e_WARN`).
212///
213/// BALL_LOGTHROTTLE_BLOCK(SEVERITY,
214/// MAX_SIMULTANEOUS_MESSAGES,
215/// NANOSECONDS_PER_MESSAGE) <block>
216/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
217/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}, where
218/// any sequence of values for which `operator<<` is defined may be
219/// streamed to `BALL_LOG_OUTPUT_STREAM` within the controlled `<block>`.
220/// If the throttle permits a message to be logged, the resulting formatted
221/// message is logged with the specified `SEVERITY`.
222/// @endcode
223///
224/// ### printf-Style Throttling Macros {#ball_logthrottle-printf-style-throttling-macros}
225///
226///
227/// The following macros mirror the corresponding `BALL_LOGVA_*` macros:
228/// @code
229/// BALL_LOGTHROTTLEVA_<SEVERITY>(MAX_SIMULTANEOUS_MESSAGE,
230/// NANOSECONDS_PER_MESSAGE,
231/// MSG,
232/// ...);
233/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
234/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}. If
235/// the throttle permits a message to be logged, format the specified `...`
236/// optional arguments, if any, according to the `printf`-style format
237/// specification in the specified `MSG` (assumed to be of type convertible
238/// to `const char *`), and log the resulting formatted message with the
239/// severity indicated by the name of the macro (e.g.,
240/// `BALL_LOGTHROTTLEVA_INFO` logs with severity `ball::Severity::e_INFO`).
241/// The behavior is undefined unless the number and types of the optional
242/// arguments are compatible with the format specification in `MSG`. Note
243/// that each use of these macros must be terminated by a `;`.
244///
245/// BALL_LOGTHROTTLEVA(SEVERITY,
246/// MAX_SIMULTANEOUS_MESSAGES,
247/// NANOSECONDS_PER_MESSAGE,
248/// MSG,
249/// ...);
250/// Throttle logging with the specified `MAX_SIMULTANEOUS_MESSAGES` and
251/// `NANOSECONDS_PER_MESSAGE` as described in {Throttling Parameters}. If
252/// the throttle permits a message to be logged, format the specified `...`
253/// optional arguments, if any, according to the `printf`-style format
254/// specification in the specified `MSG` (assumed to be of type convertible
255/// to `const char *`), and log the resulting formatted message with the
256/// specified `SEVERITY`. The behavior is undefined unless the number and
257/// types of the optional arguments are compatible with the format
258/// specification in `MSG`. Note that each use of this macro must be
259/// terminated by a `;`.
260/// @endcode
261///
262/// ## Usage {#ball_logthrottle-usage}
263///
264///
265/// This section illustrates the intended use of this component.
266///
267/// ### Example 1: C++ Stream-Style Throttling Macro Usage {#ball_logthrottle-example-1-c-stream-style-throttling-macro-usage}
268///
269///
270/// Suppose a computer is reading `double` values from a radio receiver, ten per
271/// second, which represent readings of radiation detected by a Geiger counter
272/// on a spacecraft, and is transmitting them to a ground control at Jet
273/// Propulsion Laboratories in California.
274///
275/// The readings are returned by the `double yield()` manipulator of a
276/// `RadiationMeterReceiver` object (the implementation of which is omitted).
277/// The `yield` method blocks until it obtains a reading to return. If called
278/// in a tight loop, `yield` returns ten readings per second.
279///
280/// Readings range from 0 to 100.
281///
282/// * Readings above 10 but not greater than 30 are a concern, but are not very
283/// serious. We will report those with an `e_TRACE` severity, and at most
284/// one per hour (i.e., messages will be throttled).
285/// * Readings above 30 but not greater than 60 are more of a worry. We will
286/// report those with an `e_DEBUG` severity, and at most five per hour.
287/// * Readings above 60 but not greater than 90 are very serious. They will be
288/// reported with an `e_INFO` severity, and at most twenty per hour.
289/// * Readings above 90 are potentially catastrophic, and will be reported with
290/// an `e_WARN` severity, with no limit on the number of readings reported
291/// (i.e., no throttling).
292///
293/// We are to write a daemon process, which will loop gathering readings. A
294/// reading of an impossible value of -1.0 will indicate termination.
295///
296/// First we define a set of useful constants:
297/// @code
298/// enum {
299/// k_NUM_INFO = 20, // max # of info messages in a very short time
300/// k_NUM_DEBUG = 5, // max # of debug messages in a very short time
301/// k_NUM_TRACE = 1 // max # of trace messages in a very short time
302/// };
303///
304/// const Int64 k_NS_PER_HOUR =
305/// BloombergLP::bdlt::TimeUnitRatio::k_NANOSECONDS_PER_HOUR;
306///
307/// const Int64 k_NS_PER_INFO = k_NS_PER_HOUR / k_NUM_INFO;
308/// // long-term minimum nanoseconds per info message permitted
309/// const Int64 k_NS_PER_DEBUG = k_NS_PER_HOUR / k_NUM_DEBUG;
310/// // long-term minimum nanoseconds per debug message permitted
311/// const Int64 k_NS_PER_TRACE = k_NS_PER_HOUR / k_NUM_TRACE;
312/// // long-term minimum nanoseconds per trace message permitted
313/// @endcode
314/// Then we implement the radiation monitor using the log-throttle macros to
315/// throttle the number of log records being published:
316/// @code
317/// /// Daemon to run the radiation monitor.
318/// void radiationMonitorStreamDaemon()
319/// {
320/// BALL_LOG_SET_CATEGORY("RADIATION.MONITOR");
321///
322/// RadiationMeterReceiver receiver;
323///
324/// BALL_LOG_DEBUG << "Start gathering data.";
325///
326/// double reading;
327/// while (-1.0 != (reading = receiver.yield())) {
328///
329/// if (90 < reading) {
330/// BALL_LOG_WARN << "Serious Radiation reading of " << reading;
331/// }
332///
333/// else if (60 < reading) {
334/// BALL_LOGTHROTTLE_INFO(k_NUM_INFO, k_NS_PER_INFO) <<
335/// "Radiation reading of " << reading;
336/// }
337///
338/// else if (30 < reading) {
339/// BALL_LOGTHROTTLE_DEBUG(k_NUM_DEBUG, k_NS_PER_DEBUG) <<
340/// "Radiation reading of " << reading;
341/// }
342///
343/// else if (10 < reading) {
344/// BALL_LOGTHROTTLE_TRACE(k_NUM_TRACE, k_NS_PER_TRACE) <<
345/// "Radiation reading of " << reading;
346/// }
347/// }
348///
349/// BALL_LOG_DEBUG << "Finished gathering data.";
350/// }
351/// @endcode
352///
353/// `radiationMonitorPrintfDaemon` produces output like:
354/// @code
355/// 24APR2018_16:36:22.791 61260 139907579877152 DEBUG ball_logthrottle.t.cpp
356/// 460 RADIATION.MONITOR Start gathering data.
357///
358/// 24APR2018_16:36:23.094 61260 139907579877152 TRACE ball_logthrottle.t.cpp
359/// 488 RADIATION.MONITOR Radiation reading of 12.3
360///
361/// 24APR2018_16:36:23.396 61260 139907579877152 DEBUG ball_logthrottle.t.cpp
362/// 481 RADIATION.MONITOR Radiation reading of 33.1
363///
364/// 24APR2018_16:36:23.597 61260 139907579877152 DEBUG ball_logthrottle.t.cpp
365/// 481 RADIATION.MONITOR Radiation reading of 53.7
366///
367/// 24APR2018_16:36:23.901 61260 139907579877152 DEBUG ball_logthrottle.t.cpp
368/// 481 RADIATION.MONITOR Radiation reading of 46.1
369///
370/// 24APR2018_16:36:24.102 61260 139907579877152 INFO ball_logthrottle.t.cpp
371/// 474 RADIATION.MONITOR Radiation reading of 67.4
372/// @endcode
373/// @}
374/** @} */
375/** @} */
376
377/** @addtogroup bal
378 * @{
379 */
380/** @addtogroup ball
381 * @{
382 */
383/** @addtogroup ball_logthrottle
384 * @{
385 */
386
387#include <balscm_version.h>
388
389#include <ball_category.h>
390#include <ball_log.h>
391#include <ball_severity.h>
392
393#include <bdlmt_throttle.h>
394
395 // ====================================
396 // Implementation Details: Do *NOT* Use
397 // ====================================
398
399#define BALL_LOGTHROTTLE_STREAM_CONST_IMP(SEVERITY, \
400 MAX_SIMULTANEOUS_MESSAGES, \
401 NANOSECONDS_PER_MESSAGE) \
402for (const BloombergLP::ball::CategoryHolder *ball_logthrottle_cAtEgOrYhOlDeR \
403 = BloombergLP::ball::Log::categoryHolderIfEnabled<(SEVERITY)>( \
404 ball_log_getCategoryHolder(BALL_LOG_CATEGORYHOLDER)); \
405 ball_logthrottle_cAtEgOrYhOlDeR; \
406 ball_logthrottle_cAtEgOrYhOlDeR = 0) \
407for (static BloombergLP::bdlmt::Throttle ball_logthrottle_tHrOtTlE = \
408 BDLMT_THROTTLE_INIT((MAX_SIMULTANEOUS_MESSAGES), \
409 (NANOSECONDS_PER_MESSAGE)); \
410 ball_logthrottle_cAtEgOrYhOlDeR \
411 && ball_logthrottle_tHrOtTlE.requestPermission(); \
412 ) \
413for (BloombergLP::ball::Log_Stream ball_log_lOg_StReAm( \
414 ball_logthrottle_cAtEgOrYhOlDeR->category(), \
415 __FILE__, \
416 __LINE__, \
417 (SEVERITY)); \
418 ball_logthrottle_cAtEgOrYhOlDeR; \
419 ball_logthrottle_cAtEgOrYhOlDeR = 0)
420
421#define BALL_LOGTHROTTLE_STREAM_IMP(SEVERITY, \
422 MAX_SIMULTANEOUS_MESSAGES, \
423 NANOSECONDS_PER_MESSAGE) \
424for (const BloombergLP::ball::CategoryHolder *ball_logthrottle_cAtEgOrYhOlDeR \
425 = ball_log_getCategoryHolder(BALL_LOG_CATEGORYHOLDER); \
426 ball_logthrottle_cAtEgOrYhOlDeR \
427 && ball_logthrottle_cAtEgOrYhOlDeR->threshold() >= (SEVERITY) \
428 && BloombergLP::ball::Log::isCategoryEnabled( \
429 ball_logthrottle_cAtEgOrYhOlDeR, \
430 (SEVERITY)); \
431 ball_logthrottle_cAtEgOrYhOlDeR = 0) \
432for (static BloombergLP::bdlmt::Throttle ball_logthrottle_tHrOtTlE = \
433 BDLMT_THROTTLE_INIT((MAX_SIMULTANEOUS_MESSAGES), \
434 (NANOSECONDS_PER_MESSAGE)); \
435 ball_logthrottle_cAtEgOrYhOlDeR \
436 && ball_logthrottle_tHrOtTlE.requestPermission(); \
437 ) \
438for (BloombergLP::ball::Log_Stream ball_log_lOg_StReAm( \
439 ball_logthrottle_cAtEgOrYhOlDeR->category(), \
440 __FILE__, \
441 __LINE__, \
442 (SEVERITY)); \
443 ball_logthrottle_cAtEgOrYhOlDeR; \
444 ball_logthrottle_cAtEgOrYhOlDeR = 0)
445
446#define BALL_LOGTHROTTLEVA_CONST_IMP(SEVERITY, \
447 MAX_SIMULTANEOUS_MESSAGES, \
448 NANOSECONDS_PER_MESSAGE, \
449 ...) \
450do { \
451 static BloombergLP::bdlmt::Throttle ball_logthrottle_tHrOtTlE = \
452 BDLMT_THROTTLE_INIT((MAX_SIMULTANEOUS_MESSAGES), \
453 (NANOSECONDS_PER_MESSAGE)); \
454 const BloombergLP::ball::CategoryHolder \
455 *ball_logthrottle_cAtEgOrYhOlDeR \
456 = BloombergLP::ball::Log::categoryHolderIfEnabled<(SEVERITY)>( \
457 ball_log_getCategoryHolder(BALL_LOG_CATEGORYHOLDER)); \
458 if (ball_logthrottle_cAtEgOrYhOlDeR && \
459 ball_logthrottle_tHrOtTlE.requestPermission()) { \
460 BloombergLP::ball::Log_Formatter ball_logthrottle_fOrMaTtEr( \
461 ball_logthrottle_cAtEgOrYhOlDeR->category(), \
462 __FILE__, \
463 __LINE__, \
464 (SEVERITY)); \
465 BloombergLP::ball::Log::format( \
466 ball_logthrottle_fOrMaTtEr.messageBuffer(), \
467 ball_logthrottle_fOrMaTtEr.messageBufferLen(), \
468 __VA_ARGS__); \
469 } \
470} while(0)
471
472 // ==================================
473 // C++ Stream-Style throttling macros
474 // ==================================
475
476#define BALL_LOGTHROTTLE_STREAM(SEVERITY, \
477 MAX_SIMULTANEOUS_MESSAGES, \
478 NANOSECONDS_PER_MESSAGE) \
479 BALL_LOGTHROTTLE_STREAM_IMP((SEVERITY), \
480 (MAX_SIMULTANEOUS_MESSAGES), \
481 (NANOSECONDS_PER_MESSAGE)) \
482 BALL_LOG_OUTPUT_STREAM
483
484#define BALL_LOGTHROTTLE_TRACE( \
485 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
486 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_TRACE, \
487 (MAX_SIMULTANEOUS_MESSAGES), \
488 (NANOSECONDS_PER_MESSAGE)) \
489 BALL_LOG_OUTPUT_STREAM
490
491#define BALL_LOGTHROTTLE_DEBUG( \
492 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
493 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_DEBUG, \
494 (MAX_SIMULTANEOUS_MESSAGES), \
495 (NANOSECONDS_PER_MESSAGE)) \
496 BALL_LOG_OUTPUT_STREAM
497
498#define BALL_LOGTHROTTLE_INFO( \
499 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
500 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_INFO, \
501 (MAX_SIMULTANEOUS_MESSAGES), \
502 (NANOSECONDS_PER_MESSAGE)) \
503 BALL_LOG_OUTPUT_STREAM
504
505#define BALL_LOGTHROTTLE_WARN( \
506 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
507 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_WARN, \
508 (MAX_SIMULTANEOUS_MESSAGES), \
509 (NANOSECONDS_PER_MESSAGE)) \
510 BALL_LOG_OUTPUT_STREAM
511
512#define BALL_LOGTHROTTLE_ERROR( \
513 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
514 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_ERROR, \
515 (MAX_SIMULTANEOUS_MESSAGES), \
516 (NANOSECONDS_PER_MESSAGE)) \
517 BALL_LOG_OUTPUT_STREAM
518
519#define BALL_LOGTHROTTLE_FATAL( \
520 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
521 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_FATAL, \
522 (MAX_SIMULTANEOUS_MESSAGES), \
523 (NANOSECONDS_PER_MESSAGE)) \
524 BALL_LOG_OUTPUT_STREAM
525
526 // =============================
527 // BLOCK-Style throttling macros
528 // =============================
529
530#define BALL_LOGTHROTTLE_BLOCK(SEVERITY, \
531 MAX_SIMULTANEOUS_MESSAGES, \
532 NANOSECONDS_PER_MESSAGE) \
533 BALL_LOGTHROTTLE_STREAM_IMP((SEVERITY), \
534 (MAX_SIMULTANEOUS_MESSAGES), \
535 (NANOSECONDS_PER_MESSAGE))
536
537#define BALL_LOGTHROTTLE_TRACE_BLOCK( \
538 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
539 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_TRACE, \
540 (MAX_SIMULTANEOUS_MESSAGES), \
541 (NANOSECONDS_PER_MESSAGE))
542
543#define BALL_LOGTHROTTLE_DEBUG_BLOCK( \
544 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
545 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_DEBUG, \
546 (MAX_SIMULTANEOUS_MESSAGES), \
547 (NANOSECONDS_PER_MESSAGE))
548
549#define BALL_LOGTHROTTLE_INFO_BLOCK( \
550 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
551 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_INFO, \
552 (MAX_SIMULTANEOUS_MESSAGES), \
553 (NANOSECONDS_PER_MESSAGE))
554
555#define BALL_LOGTHROTTLE_WARN_BLOCK( \
556 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
557 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_WARN, \
558 (MAX_SIMULTANEOUS_MESSAGES), \
559 (NANOSECONDS_PER_MESSAGE))
560
561#define BALL_LOGTHROTTLE_ERROR_BLOCK( \
562 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
563 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_ERROR, \
564 (MAX_SIMULTANEOUS_MESSAGES), \
565 (NANOSECONDS_PER_MESSAGE))
566
567#define BALL_LOGTHROTTLE_FATAL_BLOCK( \
568 MAX_SIMULTANEOUS_MESSAGES, NANOSECONDS_PER_MESSAGE) \
569 BALL_LOGTHROTTLE_STREAM_CONST_IMP(BloombergLP::ball::Severity::e_FATAL, \
570 (MAX_SIMULTANEOUS_MESSAGES), \
571 (NANOSECONDS_PER_MESSAGE))
572
573 // ================================
574 // 'printf'-style throttling macros
575 // ================================
576
577#define BALL_LOGTHROTTLEVA(SEVERITY, \
578 MAX_SIMULTANEOUS_MESSAGES, \
579 NANOSECONDS_PER_MESSAGE, \
580 ...) \
581do { \
582 static BloombergLP::bdlmt::Throttle ball_logthrottle_tHrOtTlE = \
583 BDLMT_THROTTLE_INIT((MAX_SIMULTANEOUS_MESSAGES), \
584 (NANOSECONDS_PER_MESSAGE)); \
585 const BloombergLP::ball::CategoryHolder *ball_logthrottle_cAtEgOrYhOlDeR \
586 = ball_log_getCategoryHolder(BALL_LOG_CATEGORYHOLDER); \
587 if (ball_logthrottle_cAtEgOrYhOlDeR->threshold() >= (SEVERITY) \
588 && BloombergLP::ball::Log::isCategoryEnabled( \
589 ball_logthrottle_cAtEgOrYhOlDeR, \
590 (SEVERITY)) \
591 && ball_logthrottle_tHrOtTlE.requestPermission()) { \
592 BloombergLP::ball::Log_Formatter ball_logthrottle_fOrMaTtEr( \
593 ball_logthrottle_cAtEgOrYhOlDeR->category(), \
594 __FILE__, \
595 __LINE__, \
596 (SEVERITY)); \
597 BloombergLP::ball::Log::format( \
598 ball_logthrottle_fOrMaTtEr.messageBuffer(), \
599 ball_logthrottle_fOrMaTtEr.messageBufferLen(), \
600 __VA_ARGS__); \
601 } \
602} while(0)
603
604#define BALL_LOGTHROTTLEVA_TRACE(MAX_SIMULTANEOUS_MESSAGES, \
605 NANOSECONDS_PER_MESSAGE, \
606 ...) \
607 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_TRACE, \
608 (MAX_SIMULTANEOUS_MESSAGES), \
609 (NANOSECONDS_PER_MESSAGE), \
610 __VA_ARGS__)
611
612#define BALL_LOGTHROTTLEVA_DEBUG(MAX_SIMULTANEOUS_MESSAGES, \
613 NANOSECONDS_PER_MESSAGE, \
614 ...) \
615 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_DEBUG, \
616 (MAX_SIMULTANEOUS_MESSAGES), \
617 (NANOSECONDS_PER_MESSAGE), \
618 __VA_ARGS__)
619
620#define BALL_LOGTHROTTLEVA_INFO( MAX_SIMULTANEOUS_MESSAGES, \
621 NANOSECONDS_PER_MESSAGE, \
622 ...) \
623 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_INFO, \
624 (MAX_SIMULTANEOUS_MESSAGES), \
625 (NANOSECONDS_PER_MESSAGE), \
626 __VA_ARGS__)
627
628#define BALL_LOGTHROTTLEVA_WARN( MAX_SIMULTANEOUS_MESSAGES, \
629 NANOSECONDS_PER_MESSAGE, \
630 ...) \
631 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_WARN, \
632 (MAX_SIMULTANEOUS_MESSAGES), \
633 (NANOSECONDS_PER_MESSAGE), \
634 __VA_ARGS__)
635
636#define BALL_LOGTHROTTLEVA_ERROR(MAX_SIMULTANEOUS_MESSAGES, \
637 NANOSECONDS_PER_MESSAGE, \
638 ...) \
639 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_ERROR, \
640 (MAX_SIMULTANEOUS_MESSAGES), \
641 (NANOSECONDS_PER_MESSAGE), \
642 __VA_ARGS__)
643
644#define BALL_LOGTHROTTLEVA_FATAL(MAX_SIMULTANEOUS_MESSAGES, \
645 NANOSECONDS_PER_MESSAGE, \
646 ...) \
647 BALL_LOGTHROTTLEVA_CONST_IMP(BloombergLP::ball::Severity::e_FATAL, \
648 (MAX_SIMULTANEOUS_MESSAGES), \
649 (NANOSECONDS_PER_MESSAGE), \
650 __VA_ARGS__)
651
652#endif
653
654// ----------------------------------------------------------------------------
655// Copyright 2018 Bloomberg Finance L.P.
656//
657// Licensed under the Apache License, Version 2.0 (the "License");
658// you may not use this file except in compliance with the License.
659// You may obtain a copy of the License at
660//
661// http://www.apache.org/licenses/LICENSE-2.0
662//
663// Unless required by applicable law or agreed to in writing, software
664// distributed under the License is distributed on an "AS IS" BASIS,
665// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
666// See the License for the specific language governing permissions and
667// limitations under the License.
668// ----------------------------- END-OF-FILE ----------------------------------
669
670/** @} */
671/** @} */
672/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195