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
>
12
BSLS_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) \
402
for (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) \
407
for (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
) \
413
for (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) \
424
for (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) \
432
for (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
) \
438
for (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
...) \
450
do { \
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
...) \
581
do { \
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
/** @} */
ball_category.h
ball_log.h
ball_severity.h
bdlmt_throttle.h
bsls_ident.h
BSLS_IDENT
#define BSLS_IDENT(str)
Definition
bsls_ident.h:195
doxygen_input
bde
groups
bal
ball
ball_logthrottle.h
Generated by
1.9.8