BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_fileobserver.h
Go to the documentation of this file.
1/// @file ball_fileobserver.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_fileobserver.h -*-C++-*-
8#ifndef INCLUDED_BALL_FILEOBSERVER
9#define INCLUDED_BALL_FILEOBSERVER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_fileobserver ball_fileobserver
15/// @brief Provide a thread-safe observer that logs to a file and to `stdout`.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_fileobserver
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_fileobserver-purpose"> Purpose</a>
25/// * <a href="#ball_fileobserver-classes"> Classes </a>
26/// * <a href="#ball_fileobserver-description"> Description </a>
27/// * <a href="#ball_fileobserver-file-observer-configuration-synopsis"> File Observer Configuration Synopsis </a>
28/// * <a href="#ball_fileobserver-log-record-formatting"> Log Record Formatting </a>
29/// * <a href="#ball_fileobserver-log-record-timestamps"> Log Record Timestamps </a>
30/// * <a href="#ball_fileobserver-local-time-offset-calculations"> Local Time Offset Calculations </a>
31/// * <a href="#ball_fileobserver-log-filename-patterns"> Log Filename Patterns </a>
32/// * <a href="#ball_fileobserver-log-file-rotation"> Log File Rotation </a>
33/// * <a href="#ball_fileobserver-file-rotation-conditions"> File Rotation Conditions </a>
34/// * <a href="#ball_fileobserver-rotated-file-naming"> Rotated File Naming </a>
35/// * <a href="#ball_fileobserver-thread-safety"> Thread Safety </a>
36/// * <a href="#ball_fileobserver-usage"> Usage </a>
37/// * <a href="#ball_fileobserver-example-basic-usage"> Example: Basic Usage </a>
38///
39/// # Purpose {#ball_fileobserver-purpose}
40/// Provide a thread-safe observer that logs to a file and to `stdout`.
41///
42/// # Classes {#ball_fileobserver-classes}
43///
44/// - ball::FileObserver: observer that writes log records to a file and `stdout`
45///
46/// @see ball_record, ball_context, ball_observer, ball_fileobserver2
47///
48/// # Description {#ball_fileobserver-description}
49/// This component provides a concrete implementation of the
50/// `ball::Observer` protocol, `ball::FileObserver`, for publishing log records
51/// to `stdout` and, optionally, to a user-specified file. The following
52/// inheritance hierarchy diagram shows the classes involved and their methods:
53/// @code
54/// ,------------------.
55/// ( ball::FileObserver )
56/// `------------------'
57/// | ctor
58/// | disableFileLogging
59/// | disableTimeIntervalRotation
60/// | disableSizeRotation
61/// | disableStdoutLoggingPrefix
62/// | disablePublishInLocalTime
63/// | enableFileLogging
64/// | enableStdoutLoggingPrefix
65/// | enablePublishInLocalTime
66/// | forceRotation
67/// | rotateOnSize
68/// | rotateOnTimeInterval
69/// | setOnFileRotationCallback
70/// | setStdoutThreshold
71/// | setLogFormat
72/// | suppressUniqueFileNameOnRotation
73/// | getLogFormat
74/// | isFileLoggingEnabled
75/// | isStdoutLoggingPrefixEnabled
76/// | isPublishInLocalTimeEnabled
77/// | isSuppressUniqueFileNameOnRotation
78/// | rotationLifetime
79/// | rotationSize
80/// | stdoutThreshold
81/// V
82/// ,--------------.
83/// ( ball::Observer )
84/// `--------------'
85/// dtor
86/// publish
87/// releaseRecords
88/// @endcode
89/// A `ball::FileObserver` object processes the log records received through its
90/// `publish` method by writing them to `stdout` and, if so configured, to a
91/// user-specified file. The format of published log records is
92/// user-configurable for both destinations, `stdout` and file (see {Log Record
93/// Formatting} below). Although logging to a file is initially disabled
94/// following construction, the most common use-case for `ball::FileObserver` is
95/// to also log to a file, enabled by calling the `enableFileLogging` method.
96/// In addition, a file observer may be configured to perform automatic log file
97/// rotation (see {Log File Rotation} below).
98///
99/// ## File Observer Configuration Synopsis {#ball_fileobserver-file-observer-configuration-synopsis}
100///
101///
102/// `ball::FileObserver` offers several constructor arguments and manipulators
103/// that may be used to configure various aspects of a file observer object.
104/// These are summarized in the following tables along with the accessors that
105/// can be used to query the current state of the configuration. Further
106/// details are provided in the following sections and the function-level
107/// documentation.
108/// @code
109/// +-----------------------+-----------------------+
110/// | Aspect | Constructor Arguments |
111/// +=======================+=======================+
112/// | Log Record Timestamps | publishInLocalTime |
113/// +-----------------------+-----------------------+
114/// | `stdout` Logging | stdoutThreshold |
115/// +-----------------------+-----------------------+
116///
117/// +-------------+------------------------------------+
118/// | Aspect | Related Methods |
119/// +=============+====================================+
120/// | Log Record | setLogFormat |
121/// | Formatting | enableStdoutLoggingPrefix |
122/// | | disableStdoutLoggingPrefix |
123/// | | getLogFormat |
124/// | | isStdoutLoggingPrefixEnabled |
125/// +-------------+------------------------------------+
126/// | Log Record | enablePublishInLocalTime |
127/// | Timestamps | disablePublishInLocalTime |
128/// | | isPublishInLocalTimeEnabled |
129/// | | |
130/// +-------------+------------------------------------+
131/// | File | enableFileLogging |
132/// | Logging | disableFileLogging |
133/// | | isFileLoggingEnabled |
134/// | | |
135/// +-------------+------------------------------------+
136/// | `stdout` | setStdoutThreshold |
137/// | Logging | enableStdoutLoggingPrefix |
138/// | | disableStdoutLoggingPrefix |
139/// | | stdoutThreshold |
140/// | | isStdoutLoggingPrefixEnabled |
141/// +-------------+------------------------------------+
142/// | Log File | rotateOnSize |
143/// | Rotation | rotateOnTimeInterval |
144/// | | disableSizeRotation |
145/// | | disableTimeIntervalRotation |
146/// | | setOnFileRotationCallback |
147/// | | suppressUniqueFileNameOnRotation |
148/// | | rotationSize |
149/// | | rotationLifetime |
150/// | | isSuppressUniqueFileNameOnRotation |
151/// +-------------+------------------------------------+
152/// @endcode
153/// In general, a `ball::FileObserver` object can be dynamically configured
154/// throughout its lifetime (in particular, before or after being registered
155/// with a logger manager). However, note that for `ball::FileObserver`,
156/// configuration changes that affect how records are logged (e.g.,
157/// `enablePublishInLocalTime` and `disablePublishInLocalTime`) impact only
158/// those records that are published subsequent to making the configuration
159/// change.
160///
161/// ## Log Record Formatting {#ball_fileobserver-log-record-formatting}
162///
163///
164/// By default, the output format of published log records, whether written to
165/// `stdout` or to a user-specified file, is:
166/// @code
167/// DATE_TIME PID:THREAD-ID SEVERITY FILE:LINE CATEGORY MESSAGE USER-FIELDS
168/// @endcode
169/// where `DATE` and `TIME` are of the form `DDMonYYYY` and `HH:MM:SS.mmm`,
170/// respectively (`Mon` being the 3-letter abbreviation for the month). For
171/// example, a log record will have the following appearance when the default
172/// format is in effect (assuming that no user-defined fields are present):
173/// @code
174/// 18MAY2005_18:58:12.076 7959:1 WARN ball_fileobserver.t.cpp:404 TEST hello!
175/// @endcode
176/// The default format for records published to `stdout` (only) can be shortened
177/// by calling `disableStdoutLoggingPrefix`. This method has the effect of
178/// reducing the above example message to the following when output to `stdout`:
179/// @code
180/// WARN ball_fileobserver.t.cpp:404 TEST hello!
181/// @endcode
182/// For additional flexibility, the `setLogFormat` method can be called to
183/// configure the format of published records. This method takes two arguments:
184/// the first argument specifies the format of records logged to a file and the
185/// second applies to records that are logged to `stdout`. The respective
186/// formats are specified using `printf`-style (`%`-prefixed) conversion
187/// specifications. (See @ref ball_recordstringformatter for information on how
188/// format specifications are defined and interpreted.) For example, the
189/// following statement will force subsequent records to be logged in a format
190/// that is almost identical to the default long format except that the
191/// timestamp attribute will be written in ISO 8601 format:
192/// @code
193/// fileObserver.setLogFormat("\n%I %p:%t %s %f:%l %c %m %u\n",
194/// "\n%I %p:%t %s %f:%l %c %m %u\n");
195/// @endcode
196/// Once a customized format is specified for `stdout`, calling
197/// `disableStdoutLoggingPrefix` will switch to the default short format, i.e.,
198/// "\n%s %f:%l %c %m %u\n". If `enableStdoutLoggingPrefix` is subsequently
199/// called, the customized format specified in the most recent call to
200/// `setLogFormat` will be reinstated. Note that the observer emits newline
201/// characters at the beginning and at the end of a log record by default, so
202/// the user needs to add them explicitly to the format string to preserve this
203/// behavior.
204///
205/// Note that in the sample long-form message above the timestamp has
206/// millisecond precision (`18MAY2005_18:58:12.076`). If microsecond precision
207/// is desired instead, consider using either the `%D` or `%O` format
208/// specification supported by @ref ball_recordstringformatter .
209///
210/// ## Log Record Timestamps {#ball_fileobserver-log-record-timestamps}
211///
212///
213/// By default, the timestamp attributes of published records are written in UTC
214/// time (unless `true` is supplied for the optional `publishInLocalTime`
215/// constructor flag). To write timestamps in local time instead, call the
216/// `enablePublishInLocalTime` method. Note that the local time offset is
217/// calculated using the UTC timestamp of each record. To revert to UTC time,
218/// call the `disablePublishInLocalTime` method. Whether UTC time or local time
219/// is in effect can be queried via `isPublishInLocalTimeEnabled`.
220///
221/// ### Local Time Offset Calculations {#ball_fileobserver-local-time-offset-calculations}
222///
223///
224/// The calculation of the local time offset adds some overhead to the
225/// publication of each log record. If this overhead is an issue, it can be
226/// mitigated by installing a high-performance local-time offset callback for
227/// `bdlt::CurrentTime` in `main`. See @ref bsls_systemtime for the details of
228/// installing such a callback and see @ref baltzo_localtimeoffsetutil for an
229/// example facility. Note that such callbacks can improve performance for all
230/// users of `bdlt::CurrentTime`, not just the `ball` logger.
231///
232/// ## Log Filename Patterns {#ball_fileobserver-log-filename-patterns}
233///
234///
235/// The `enableFileLogging` method supports the use of `%`-escape sequences to
236/// specify log filenames. The recognized sequences are as follows:
237/// @code
238/// %Y - current year (4 digits with leading zeros)
239/// %M - current month (2 digits with leading zeros)
240/// %D - current day (2 digits with leading zeros)
241/// %h - current hour (2 digits with leading zeros)
242/// %m - current minute (2 digits with leading zeros)
243/// %s - current second (2 digits with leading zeros)
244/// %T - current datetime, equivalent to "%Y%M%D_%h%m%s"
245/// %p - process ID
246/// @endcode
247/// The date and time elements of the derived filename are based on the time
248/// when the log file is created. Furthermore, these elements are based on
249/// either UTC time or local time depending on the value returned by
250/// `isPublishInLocalTimeEnabled`. (See {Log Record Timestamps} for the
251/// similarity with the treatment of record timestamps.)
252///
253/// For example, a log filename pattern of "task.log.%Y%M%D_%h%m%s" will yield
254/// the filename `task.log.20110501_123000` if the file is created on
255/// 01-May-2011 at 12:30:00 local time (assuming `enablePublishInLocalTime` was
256/// called).
257///
258/// ## Log File Rotation {#ball_fileobserver-log-file-rotation}
259///
260///
261/// A `ball::FileObserver` may be configured to perform automatic rotation of
262/// log files based on simple file rotation conditions (or rules).
263///
264/// ### File Rotation Conditions {#ball_fileobserver-file-rotation-conditions}
265///
266///
267/// Rotation rules may be established based on the size of the log file (i.e., a
268/// "rotation-on-size" rule), and a periodic time interval (i.e., a
269/// "rotation-on-time-interval" rule). These rules are independently enabled by
270/// the `rotateOnSize` and `rotateOnTimeInterval` methods, respectively. If
271/// both rules are in effect, log file rotation is performed whenever either
272/// rule applies.
273///
274/// ### Rotated File Naming {#ball_fileobserver-rotated-file-naming}
275///
276///
277/// When a log file is rotated, a new filename is generated using the pattern
278/// supplied to `enableFileLogging`. If the file having the new name does not
279/// exist, the current log file is closed, and the logging continues to the new
280/// file.
281///
282/// If the file having the new name already exits, then the behavior of the file
283/// rotation is further controlled by the flag set with
284/// `suppressUniqueFileNameOnRotation`:
285///
286/// * `suppressUniqueFileNameOnRotation(false)` (*default* behavior)
287/// The current log filename is renamed by appending a timestamp in the form
288/// ".%Y%M%D_%h%m%s" where the timestamp indicates when the file being
289/// rotated was last opened (the time of either the last file rotation or the
290/// last call to `enableFileLogging`, whichever is most recent). As with the
291/// timestamps of logged records, the timestamps appended to log filenames
292/// upon rotation will be in UTC time or local time depending on the value
293/// returned by `isPublishInLocalTimeEnabled`.
294/// * `suppressUniqueFileNameOnRotation(true)`
295/// The logging continues to the *current* log file, effectively suppressing
296/// log filename rotation. This may happen when the log file pattern does
297/// not contain %-escape sequences indicating a time period, or the rotation
298/// interval is less than the time period encoded by %-escape sequences. In
299/// order to rotate log files in this mode, the log file pattern MUST contain
300/// %-escape sequences that specify date and (optionally) time. For example,
301/// the log filename pattern "app_%Y%M%D.log" will produce a single log file
302/// per calendar day (assuming, the rotation on time is enabled and the
303/// rotation happens at least once a day).
304///
305/// The two tables below illustrate the names of old and new log files when a
306/// file rotation occurs. We assume that the log file is rotated on 2011-May-21
307/// at 12:29:59 local time and that the last rotation occurred at 12:30:00 on
308/// the previous day. We further assume that `enablePublishInLocalTime` was
309/// called, so that all date and time elements are rendered in local time.
310///
311/// The first table shows the name change (if any) of the (old) log file being
312/// rotated when the flag controlled by `suppressUniqueFileNameOnRotation`
313/// is set to `false`:
314/// @code
315/// Disabled: `suppressUniqueFileNameOnRotation`
316///
317/// For brevity:
318/// <TS1> = 20210520_123000
319/// <TS2> = 20210521_122959 (aka next day, about the same time)
320///
321/// +----------------+-----------------+----------------+----------------------
322/// | Pattern | Filename Before | Filename After | Rotated Filename
323/// | | Rotation | Rotation |
324/// +----------------+-----------------+----------------+----------------------
325/// | "a.log" | a.log | a.log | a.log.<TS1>
326/// | "a.log.%T" | a.log.<TS1> | a.log.<TS2> | a.log.<TS1>
327/// | "a.log.%Y%M" | a.log.202105 | a.log.202105 | a.log.202105.<TS1>
328/// | "a.log.%Y%M%D" | a.log.20210520 | a.log.20110521 | a.log.20210520
329/// +----------------+-----------------+----------------+----------------------
330/// @endcode
331/// Note that upon rotation a timestamp was appended to the name of the rotated
332/// file when the log pattern does not contain %-escape sequences indicating a
333/// time period ("a.log"), or the rotation period (in our case, one day) is less
334/// than the time period encoded in the pattern (in case of "a.log.%Y%M" the
335/// period is one month).
336///
337/// The next table shows the rotated name when the flag controlled by
338/// `suppressUniqueFileNameOnRotation` is set to `true`, and (possibly new) name
339/// of the (new) log file following rotation:
340/// @code
341/// Enabled: `suppressUniqueFileNameOnRotation`
342///
343/// +----------------+-----------------+----------------+----------------------
344/// | Pattern | Filename Before | Filename After | Rotated Filename
345/// | | Rotation | Rotation |
346/// +----------------+-----------------+----------------+----------------------
347/// | "a.log" | a.log | a.log | none
348/// | "a.log.%T" | a.log.<TS1> | a.log.<TS2> | a.log.<TS1>
349/// | "a.log.%Y%M" | a.log.202105 | a.log.202105 | none
350/// | "a.log.%Y%M%D" | a.log.20210520 | a.log.20110521 | a.log.20210520
351/// +----------------+-----------------+----------------+----------------------
352/// @endcode
353/// Note that the original filename is reused when the log pattern does not
354/// contain %-escape sequences indicating a time period ("a.log"), or the
355/// rotation period (in our case, one day) is less than the time period encoded
356/// in the pattern (in case of "a.log.%Y%M" the period is one month).
357///
358/// Also note, that in any cases, when the log pattern includes "%T", or encodes
359/// a time period that coincides the rotation period (in case of "a.log.%Y%M%D"
360/// the period is one day), then a unique name on each rotation is produced with
361/// the (local) time at which file rotation occurred embedded in the filename.
362///
363/// ## Thread Safety {#ball_fileobserver-thread-safety}
364///
365///
366/// All methods of `ball::FileObserver` are thread-safe, and can be called
367/// concurrently by multiple threads.
368///
369/// ## Usage {#ball_fileobserver-usage}
370///
371///
372/// This section illustrates intended use of this component.
373///
374/// ### Example: Basic Usage {#ball_fileobserver-example-basic-usage}
375///
376///
377/// First, we create a `ball::LoggerManagerConfiguration` object, `lmConfig`,
378/// and set the logging "pass-through" level -- the level at which log records
379/// are published to registered observers -- to `DEBUG`:
380/// @code
381/// int main()
382/// {
383/// ball::LoggerManagerConfiguration lmConfig;
384/// lmConfig.setDefaultThresholdLevelsIfValid(ball::Severity::e_DEBUG);
385/// @endcode
386/// Next, create a `ball::LoggerManagerScopedGuard` object whose constructor
387/// takes the configuration object just created. The guard will initialize the
388/// logger manager singleton on creation and destroy the singleton upon
389/// destruction. This guarantees that any resources used by the logger manager
390/// will be properly released when they are not needed:
391/// @code
392/// ball::LoggerManagerScopedGuard guard(lmConfig);
393/// ball::LoggerManager& manager = ball::LoggerManager::singleton();
394/// @endcode
395/// Next, we create a `ball::FileObserver` object and register it with the
396/// `ball` logging system;
397/// @code
398/// bsl::shared_ptr<ball::FileObserver> observer =
399/// bsl::make_shared<ball::FileObserver>();
400/// int rc = manager.registerObserver(observer, "default");
401/// ASSERT(0 == rc);
402/// @endcode
403/// The default format for outputting log records can be changed by calling the
404/// `setLogFormat` method. The statement below outputs record timestamps in ISO
405/// 8601 format to the log file and in `bdlt`-style (default) format to
406/// `stdout`, where timestamps are output with millisecond precision in both
407/// cases:
408/// @code
409/// observer->setLogFormat("%I %p:%t %s %f:%l %c %m\n",
410/// "%d %p:%t %s %f:%l %c %m\n");
411/// @endcode
412/// Note that both of the above format specifications omit user fields (`%u`) in
413/// the output. Also note that, unlike the default, this format does not emit a
414/// blank line between consecutive log messages.
415///
416/// Henceforth, all messages that are published by the logging system will be
417/// transmitted to the `publish` method of `observer`. By default, only the
418/// messages with a `e_WARN`, `e_ERROR`, or `e_FATAL` severity will be logged to
419/// `stdout`:
420/// @code
421/// BALL_LOG_SET_CATEGORY("main")
422/// BALL_LOG_INFO << "Will not be published on 'stdout'.";
423/// BALL_LOG_WARN << "This warning *will* be published on 'stdout'.";
424/// @endcode
425/// This default can be changed by specifying an optional argument to the
426/// `ball::FileObserver` constructor or by calling the `setStdoutThreshold`
427/// method:
428/// @code
429/// observer->setStdoutThreshold(ball::Severity::e_INFO);
430///
431/// BALL_LOG_DEBUG << "This debug message is not published on 'stdout'.";
432/// BALL_LOG_INFO << "This info message *will* be published on 'stdout'.";
433/// BALL_LOG_WARN << "This warning will be published on 'stdout'.";
434/// @endcode
435/// The user can log all messages to a specified file and specify rotation rules
436/// based on the size of the log file or its lifetime:
437/// @code
438/// // Create and log records to a file named "/var/log/task/task.log".
439/// observer->enableFileLogging("/var/log/task/task.log");
440///
441/// // Disable 'stdout' logging.
442/// observer->setStdoutThreshold(ball::Severity::e_OFF);
443///
444/// // Rotate the file when its size becomes greater than or equal to 256
445/// // megabytes.
446/// observer->rotateOnSize(1024 * 256);
447///
448/// // Rotate the file every 24 hours.
449/// observer->rotateOnTimeInterval(bdlt::DatetimeInterval(1));
450/// @endcode
451/// Note that in this configuration the user may end up with multiple log files
452/// for any given day (because of the rotation-on-size rule). This feature can
453/// be disabled dynamically later:
454/// @code
455/// observer->disableSizeRotation();
456/// return 0;
457/// }
458/// @endcode
459/// @}
460/** @} */
461/** @} */
462
463/** @addtogroup bal
464 * @{
465 */
466/** @addtogroup ball
467 * @{
468 */
469/** @addtogroup ball_fileobserver
470 * @{
471 */
472
473#include <balscm_version.h>
474
475#include <ball_fileobserver2.h>
476#include <ball_observer.h>
478#include <ball_severity.h>
479
481
482#include <bslma_allocator.h>
484
486
487#include <bslmt_mutex.h>
488
489#include <bsls_keyword.h>
490#include <bsls_libraryfeatures.h>
491
492#include <bsl_memory.h>
493#include <bsl_string.h>
494
495#include <string> // 'std::string', 'std::pmr::string'
496
497
498namespace ball {
499
500class Context;
501class Record;
502
503 // ==================
504 // class FileObserver
505 // ==================
506
507/// This class implements the `Observer` protocol. The `publish` method of
508/// this class outputs the log records that it receives to `stdout` and
509/// optionally to a user-specified file. This class is thread-safe;
510/// different threads can operate on an object concurrently. This class is
511/// exception-neutral with no guarantee of rollback. In no event is memory
512/// leaked.
513///
514/// See @ref ball_fileobserver
515class FileObserver : public Observer {
516
517 // DATA
518 RecordStringFormatter d_logFileFormatter; // record formatter used when
519 // logging to a file
520
521 RecordStringFormatter d_stdoutFormatter; // record formatter used when
522 // logging to `stdout`
523
524 Severity::Level d_stdoutThreshold; // minimum severity for records
525 // logged to `stdout`
526
527 bool d_useRegularFormatOnStdoutFlag;
528 // `true` if records published
529 // to `stdout` in regular
530 // (long) format, otherwise
531 // short format is used
532
533 bool d_publishInLocalTime; // `true` if timestamps of
534 // records are output in local
535 // time, otherwise UTC time
536
537 bool d_userFieldsLoggingFlag;
538 // `true` if user-defined
539 // fields published
540 // (!DEPRECATED!)
541
542 bsl::string d_stdoutLongFormat; // initially set to default
543 // long format for records
544 // printed to `stdout`; updated
545 // by `setLogFormat`
546
547 bsl::string d_stdoutShortFormat; // default short format for
548 // records printed to `stdout`
549
550 mutable bslmt::Mutex d_mutex; // serialize operations
551
552 FileObserver2 d_fileObserver2; // forward most operations to
553 // this object
554
555 private:
556 // NOT IMPLEMENTED
558 FileObserver& operator=(const FileObserver&);
559
560 public:
561 // TYPES
562
563 /// `OnFileRotationCallback` is an alias for a user-supplied callback
564 /// function that is invoked after the file observer attempts to rotate
565 /// its log file. The callback takes two arguments: (1) an integer
566 /// status value where 0 indicates a new log file was successfully
567 /// created and a non-zero value indicates an error occurred during
568 /// rotation, and (2) a string that provides the name of the rotated log
569 /// file if the rotation was successful. E.g.:
570 /// @code
571 /// void onLogFileRotation(int rotationStatus,
572 /// const bsl::string& rotatedLogFileName);
573 /// @endcode
575
576 // TRAITS
578
579 // CREATORS
580
582 explicit FileObserver(bslma::Allocator *basicAllocator);
583 /// Create a file observer that publishes log records to `stdout` if
584 /// their severity is at least as severe as the optionally specified
585 /// `stdoutThreshold` level, and has file logging initially disabled.
586 /// If `stdoutThreshold` is not specified, log records are published to
587 /// `stdout` if their severity is at least as severe as
588 /// `Severity::e_WARN`. Optionally specify a `basicAllocator` used to
589 /// supply memory. If `basicAllocator` is 0, the currently installed
590 /// default allocator is used. Note that `isPublishInLocalTimeEnabled`
591 /// returns `false` following construction indicating that the timestamp
592 /// attribute of published records will be written in UTC time (see
593 /// `enablePublishInLocalTime`). Also note that independent default
594 /// record formats are in effect for `stdout` and file logging (see
595 /// `setLogFormat`).
597 bslma::Allocator *basicAllocator = 0);
598
599 /// Create a file observer that publishes log records to `stdout` if
600 /// their severity is at least as severe as the specified
601 /// `stdoutThreshold` level, and has file logging initially disabled.
602 /// The timestamp attribute of published records is written in local
603 /// time if the specified `publishInLocalTime` flag is `true`, and in
604 /// UTC time otherwise. Optionally specify a `basicAllocator` used to
605 /// supply memory. If `basicAllocator` is 0, the currently installed
606 /// default allocator is used. Note that following construction
607 /// independent default record formats are in effect for `stdout` and
608 /// file logging (see `setLogFormat`).
610 bool publishInLocalTime,
611 bslma::Allocator *basicAllocator = 0);
612
613 /// Close the log file of this file observer if file logging is enabled,
614 /// and destroy this file observer.
616
617 // MANIPULATORS
618
619 /// Disable file logging for this file observer. This method has no
620 /// effect if file logging is not enabled. Note that records
621 /// subsequently received through the `publish` method of this file
622 /// observer may still be logged to `stdout` after calling this method.
623 void disableFileLogging();
624
625 /// Disable log file rotation based on a periodic time interval for this
626 /// file observer. This method has no effect if
627 /// rotation-on-time-interval is not enabled.
628 ///
629 /// @deprecated Use @ref disableTimeIntervalRotation instead.
631
632 /// Disable log file rotation based on a periodic time interval for this
633 /// file observer. This method has no effect if
634 /// rotation-on-time-interval is not enabled.
636
637 /// Disable log file rotation based on log file size for this file
638 /// observer. This method has no effect if rotation-on-size is not
639 /// enabled.
640 void disableSizeRotation();
641
642 /// Disable this file observer from using the long output format when
643 /// logging to `stdout`. Henceforth, this file observer will use the
644 /// default short output format ("\n%s %f:%l %c %m %u\n") when logging
645 /// to `stdout`. This method has no effect if the long output format
646 /// for `stdout` logging is not enabled. Note that this method omits
647 /// the "%d %p:%t " prefix from the default long output format.
649
650 /// Disable the logging of user-defined fields by this file observer.
651 /// This method has no effect if logging of user-defined fields is not
652 /// enabled, or if a format string other than the default one is in
653 /// effect.
654 ///
655 /// @deprecated Use @ref setLogFormat instead.
657
658 /// Disable publishing of the timestamp attribute of records in local
659 /// time by this file observer; henceforth, timestamps will be in UTC
660 /// time. This method has no effect if publishing in local time is not
661 /// enabled. Note that this method also affects log filenames (see {Log
662 /// Filename Patterns}).
664
665 /// Enable logging of all records published to this file observer to a
666 /// file whose name is derived from the specified `logFilenamePattern`.
667 /// Return 0 on success, a positive value if file logging is already
668 /// enabled (with no effect), and a negative value otherwise. The
669 /// basename of `logFilenamePattern` may contain `%`-escape sequences
670 /// that are interpreted as follows:
671 /// @code
672 /// %Y - current year (4 digits with leading zeros)
673 /// %M - current month (2 digits with leading zeros)
674 /// %D - current day (2 digits with leading zeros)
675 /// %h - current hour (2 digits with leading zeros)
676 /// %m - current minute (2 digits with leading zeros)
677 /// %s - current second (2 digits with leading zeros)
678 /// %T - current datetime, equivalent to "%Y%M%D_%h%m%s"
679 /// %p - process ID
680 /// @endcode
681 /// Each time a log file is opened by this file observer (upon a
682 /// successful call to this method and following each log file
683 /// rotation), the name of the new log file is derived from
684 /// `logFilenamePattern` by interpreting the above recognized `%`-escape
685 /// sequences. If `isPublishInLocalTimeEnabled` returns `true`, the
686 /// `%`-escape sequences related to time will be substituted with local
687 /// time values, and UTC time values otherwise. See {Log Filename
688 /// Patterns}.
689 int enableFileLogging(const char *logFilenamePattern);
690
691 /// Enable logging of all records published to this file observer to a
692 /// file whose name is derived from the specified `logFilenamePattern`
693 /// and append a timestamp to the log filename if the specified
694 /// `appendTimestampFlag` is `true`. Return 0 on success, a positive
695 /// value if file logging is already enabled (with no effect), and a
696 /// negative value otherwise. If the `appendTimestampFlag` is `true`
697 /// and `logFilenamePattern` does not contain any `%`-escape sequences,
698 /// this method behaves as if ".%T" is appended to `logFilenamePattern`.
699 ///
700 /// @deprecated Use @ref enableFileLogging(logFilenamePattern) instead
701 /// (use the ".%T" pattern to replicate `true == appendTimestampFlag`
702 /// behavior).
703 int enableFileLogging(const char *logFilenamePattern,
704 bool appendTimestampFlag);
705
706 /// Enable this file observer to use the long output format when logging
707 /// to `stdout`. Henceforth, this file observer will use the output
708 /// format for `stdout` logging that was set by the most recent call to
709 /// `setLogFormat`, or the default long output format
710 /// ("\n%d %p:%t %s %f:%l %c %m %u\n") if `setLogFormat` has not yet
711 /// been called. This method has no effect if the long output format
712 /// for `stdout` logging is already enabled.
714
715 /// Enable the logging of user-defined fields by this file observer.
716 /// This method has no effect if logging of user-defined fields is
717 /// already enabled, or if a format string other than the default one is
718 /// in effect.
719 ///
720 /// @deprecated Use @ref setLogFormat instead.
722
723 /// Enable publishing of the timestamp attribute of records in local
724 /// time by this file observer. This method has no effect if publishing
725 /// in local time is already enabled. Note that this method also
726 /// affects log filenames (see {Log Filename Patterns}).
728
729 /// Process the specified log `record` having the specified publishing
730 /// `context` by writing `record` and `context` to the current log file
731 /// if file logging is enabled for this file observer, and to `stdout`
732 /// if the severity of `record` is at least as severe as the value
733 /// returned by `stdoutThreshold`.
734 ///
735 /// @deprecated Do not use.
736 void publish(const Record& record,
737 const Context& context) BSLS_KEYWORD_OVERRIDE;
738
739 /// Process the record referenced by the specified 'record' shared
740 /// pointer having the specified publishing 'context' by writing the
741 /// record and 'context' to the current log file if file logging is
742 /// enabled for this file observer, and to 'stdout' if the severity of
743 /// 'record' is at least as severe as the value returned by
744 /// 'stdoutThreshold'.
745 void publish(const bsl::shared_ptr<const Record>& record,
746 const Context& context)
748
749 /// Discard any shared references to `Record` objects that were supplied
750 /// to the `publish` method, and are held by this observer. Note that
751 /// this operation should be called if resources underlying the
752 /// previously provided shared pointers must be released.
754
755 /// Forcefully perform a log file rotation by this file observer. Close
756 /// the current log file, rename the log file if necessary, and open a
757 /// new log file. This method has no effect if file logging is not
758 /// enabled. See {Rotated File Naming} for details on filenames of
759 /// rotated log files.
760 void forceRotation();
761
762 /// Set this file observer to perform a periodic log file rotation at
763 /// multiples of the specified `timeInterval`. The behavior is
764 /// undefined unless `0 < timeInterval.totalMilliseconds()`. This rule
765 /// replaces any rotation-on-time-interval rule currently in effect.
766 ///
767 /// @deprecated Use @ref rotateOnTimeInterval instead.
768 void rotateOnLifetime(const bdlt::DatetimeInterval& timeInterval);
769
770 /// Set this file observer to perform log file rotation when the size of
771 /// the file exceeds the specified `size` (in kilobytes). This rule
772 /// replaces any rotation-on-size rule currently in effect. The
773 /// behavior is undefined unless `size > 0`.
774 void rotateOnSize(int size);
775
776 void rotateOnTimeInterval(const bdlt::DatetimeInterval& interval);
777 /// Set this file observer to perform a periodic log file rotation at
778 /// multiples of the specified `interval`. Optionally specify a
779 /// `startTime` indicating the datetime to use as the starting point for
780 /// computing the periodic rotation schedule. If
781 /// `isPublishInLocalTimeEnabled` is `true`, the `startTime` is
782 /// interpreted as local time, and as a UTC time otherwise. If
783 /// `startTime` is not specified, the current time is used. This rule
784 /// replaces any rotation-on-time-interval rule currently in effect.
785 /// The behavior is undefined unless `0 < interval.totalMilliseconds()`.
786 /// Note that `startTime` may be a fixed time in the past; e.g., a
787 /// reference time of `bdlt::Datetime(1, 1, 1)` and an interval of 24
788 /// hours would configure a periodic rotation at midnight each day.
789 void rotateOnTimeInterval(const bdlt::DatetimeInterval& interval,
790 const bdlt::Datetime& startTime);
791
792 /// Set the specified `onRotationCallback` to be invoked after each time
793 /// this file observer attempts to perform a log file rotation. The
794 /// behavior is undefined if the supplied function calls either
795 /// `setOnFileRotationCallback`, `forceRotation`, or `publish` on this
796 /// file observer (i.e., the supplied callback should *not* attempt to
797 /// write to the `ball` log).
799 const OnFileRotationCallback& onRotationCallback);
800
801 /// Set the minimum severity of records logged to `stdout` by this file
802 /// observer to the specified `stdoutThreshold` level. Note that if the
803 /// value of `stdoutThreshold` is `Severity::e_OFF`, logging to `stdout`
804 /// is disabled.
806
807 /// Set the format specifications for log records written to the log
808 /// file and to `stdout` to the specified `logFileFormat` and
809 /// `stdoutFormat`, respectively. If the default short output format is
810 /// currently in effect for logging to `stdout`, this method has the
811 /// effect of calling `enableStdoutLoggingPrefix` (see that method and
812 /// `disableStdoutLoggingPrefix`). See {Log Record Formatting} for
813 /// details on the syntax of format specifications. Note that default
814 /// formats are in effect following construction until this method is
815 /// called ("\n%d %p:%t %s %f:%l %c %m %u\n" for both file and `stdout`
816 /// logging). Also note that the observer emits newline characters at
817 /// the beginning and at the end of a log record by default, so the user
818 /// needs to add them explicitly to the format string to preserve this
819 /// behavior.
820 void setLogFormat(const char *logFileFormat, const char *stdoutFormat);
821
822 /// Suppress generating a unique log file name upon rotation if the
823 /// specified `suppress` is `true`, and generate a unique filename
824 /// otherwise. See {Rotated File Naming} for details.
825 void suppressUniqueFileNameOnRotation(bool suppress);
826
827 // ACCESSORS
828
829 /// Return the memory allocator used by this object.
830 bslma::Allocator *allocator() const;
831
832 /// Load the format specification for log records written by this file
833 /// observer to the log file into the specified `*logFileFormat` address
834 /// and the format specification for log records written to `stdout`
835 /// into the specified `*stdoutFormat` address. See {Log Record
836 /// Formatting} for details on the syntax of format specifications.
837 void getLogFormat(const char **logFileFormat,
838 const char **stdoutFormat) const;
839
840 /// Return `true` if file logging is enabled for this file observer, and
841 /// `false` otherwise. Load the optionally specified `result` with the
842 /// name of the current log file if file logging is enabled, and leave
843 /// `result` unmodified otherwise. Note that records received through
844 /// the `publish` method of this file observer may still be logged to
845 /// `stdout` when this method returns `false`.
846 bool isFileLoggingEnabled() const;
847 bool isFileLoggingEnabled(bsl::string *result) const;
848 bool isFileLoggingEnabled(std::string *result) const;
849
850#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
851 /// Return `true` if file logging is enabled for this file observer, and
852 /// `false` otherwise. Load the specified `result` with the name of the
853 /// current log file if file logging is enabled, and leave `result`
854 /// unmodified otherwise. Note that records received through the
855 /// `publish` method of this file observer may still be logged to
856 /// `stdout` when this method returns `false`.
857 bool isFileLoggingEnabled(std::pmr::string *result) const;
858#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
859
860 /// Return `true` if this file observer uses the long output format when
861 /// writing to `stdout`, and `false` otherwise (in which case the
862 /// default short output format is used). See
863 /// `enableStdoutLoggingPrefix` and `disableStdoutLoggingPrefix`.
865
866 /// Return `true` if the logging of user-defined fields is enabled for
867 /// this file observer, and `false` otherwise.
868 ///
869 /// @deprecated Do not use.
871
872 /// Return `true` if this file observer writes the timestamp attribute
873 /// of records that it publishes in local time, and `false` otherwise
874 /// (in which case timestamps are written in UTC time). Note that the
875 /// value returned by this method also affects log filenames (see {Log
876 /// Filename Patterns}).
878
879 /// Return `true` if the log filename uniqueness check on rotation is
880 /// suppressed, and false otherwise.
882
883 /// Return the difference between the local time and UTC time in effect
884 /// when this file observer was constructed. Note that this value
885 /// remains unchanged during the lifetime of this object and therefore
886 /// may become incorrect when the difference between the local time and
887 /// UTC time changes (e.g., when transitioning into or out of daylight
888 /// savings time).
889 ///
890 /// @deprecated Use @ref bdlt::LocalTimeOffset instead.
892
893 /// Return the lifetime of the log file that will trigger a file
894 /// rotation by this file observer if rotation-on-lifetime is in effect,
895 /// and a 0 time interval otherwise.
897
898 /// Return the size (in kilobytes) of the log file that will trigger a
899 /// file rotation by this file observer if rotation-on-size is in
900 /// effect, and 0 otherwise.
901 int rotationSize() const;
902
903 /// Return the minimum severity of records that will be logged to
904 /// `stdout` by this file observer. Note that records with a threshold
905 /// less severe than `stdoutThreshold()` may still be output to the log
906 /// file if file logging is enabled.
908};
909
910// ============================================================================
911// INLINE DEFINITIONS
912// ============================================================================
913
914 // ------------------
915 // class FileObserver
916 // ------------------
917
918// MANIPULATORS
919inline
921{
922 d_fileObserver2.disableFileLogging();
923}
924
925inline
930
931inline
933{
934 d_fileObserver2.disableSizeRotation();
935}
936
937inline
942
943inline
944int FileObserver::enableFileLogging(const char *logFilenamePattern)
945{
946 return d_fileObserver2.enableFileLogging(logFilenamePattern);
947}
948
949inline
950int FileObserver::enableFileLogging(const char *logFilenamePattern,
951 bool appendTimestampFlag)
952{
953 return d_fileObserver2.enableFileLogging(logFilenamePattern,
954 appendTimestampFlag);
955}
956
957inline
959{
960 d_fileObserver2.forceRotation();
961}
962
963inline
965 const Context& context)
966{
967 publish(*record, context);
968}
969
970inline
974
975inline
977{
978 d_fileObserver2.rotateOnTimeInterval(timeInterval);
979}
980
981inline
983{
984 d_fileObserver2.rotateOnSize(size);
985}
986
987inline
989{
990 d_fileObserver2.rotateOnTimeInterval(interval);
991}
992
993inline
995 const bdlt::DatetimeInterval& interval,
996 const bdlt::Datetime& startTime)
997{
998 d_fileObserver2.rotateOnTimeInterval(interval, startTime);
999}
1000
1001inline
1003 const OnFileRotationCallback& onRotationCallback)
1004{
1005 d_fileObserver2.setOnFileRotationCallback(onRotationCallback);
1006}
1007
1008inline
1010{
1011 d_fileObserver2.suppressUniqueFileNameOnRotation(suppress);
1012}
1013
1014// ACCESSORS
1015inline
1017{
1018 return d_fileObserver2.isFileLoggingEnabled();
1019}
1020
1021inline
1023{
1024 return d_fileObserver2.isFileLoggingEnabled(result);
1025}
1026
1027inline
1028bool FileObserver::isFileLoggingEnabled(std::string *result) const
1029{
1030 return d_fileObserver2.isFileLoggingEnabled(result);
1031}
1032
1033#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
1034inline
1035bool FileObserver::isFileLoggingEnabled(std::pmr::string *result) const
1036{
1037 return d_fileObserver2.isFileLoggingEnabled(result);
1038}
1039#endif //BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
1040
1041inline
1043{
1044 return d_fileObserver2.isSuppressUniqueFileNameOnRotation();
1045}
1046
1047inline
1049{
1050 return d_fileObserver2.localTimeOffset();
1051}
1052
1053inline
1055{
1056 return d_fileObserver2.rotationLifetime();
1057}
1058
1059inline
1061{
1062 return d_fileObserver2.rotationSize();
1063}
1064
1065} // close package namespace
1066
1067
1068#endif
1069
1070// ----------------------------------------------------------------------------
1071// Copyright 2015 Bloomberg Finance L.P.
1072//
1073// Licensed under the Apache License, Version 2.0 (the "License");
1074// you may not use this file except in compliance with the License.
1075// You may obtain a copy of the License at
1076//
1077// http://www.apache.org/licenses/LICENSE-2.0
1078//
1079// Unless required by applicable law or agreed to in writing, software
1080// distributed under the License is distributed on an "AS IS" BASIS,
1081// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1082// See the License for the specific language governing permissions and
1083// limitations under the License.
1084// ----------------------------- END-OF-FILE ----------------------------------
1085
1086/** @} */
1087/** @} */
1088/** @} */
Definition ball_context.h:295
Definition ball_fileobserver2.h:449
void rotateOnSize(int size)
void rotateOnTimeInterval(const bdlt::DatetimeInterval &interval)
bool isSuppressUniqueFileNameOnRotation() const
bdlt::DatetimeInterval rotationLifetime() const
bdlt::DatetimeInterval localTimeOffset() const
bool isFileLoggingEnabled() const
int rotationSize() const
void disableTimeIntervalRotation()
void setOnFileRotationCallback(const OnFileRotationCallback &onRotationCallback)
int enableFileLogging(const char *logFilenamePattern)
void suppressUniqueFileNameOnRotation(bool suppress)
Definition ball_fileobserver.h:515
FileObserver(Severity::Level stdoutThreshold, bool publishInLocalTime, bslma::Allocator *basicAllocator=0)
int enableFileLogging(const char *logFilenamePattern)
Definition ball_fileobserver.h:944
bslma::Allocator * allocator() const
Return the memory allocator used by this object.
void getLogFormat(const char **logFileFormat, const char **stdoutFormat) const
bool isSuppressUniqueFileNameOnRotation() const
Definition ball_fileobserver.h:1042
void rotateOnLifetime(const bdlt::DatetimeInterval &timeInterval)
Definition ball_fileobserver.h:976
void releaseRecords() BSLS_KEYWORD_OVERRIDE
Definition ball_fileobserver.h:971
bdlt::DatetimeInterval rotationLifetime() const
Definition ball_fileobserver.h:1054
bool isFileLoggingEnabled() const
Definition ball_fileobserver.h:1016
void disablePublishInLocalTime()
bool isStdoutLoggingPrefixEnabled() const
void disableSizeRotation()
Definition ball_fileobserver.h:932
void enablePublishInLocalTime()
void disableLifetimeRotation()
Definition ball_fileobserver.h:926
void disableStdoutLoggingPrefix()
void rotateOnSize(int size)
Definition ball_fileobserver.h:982
bool isUserFieldsLoggingEnabled() const
BSLMF_NESTED_TRAIT_DECLARATION(FileObserver, bslma::UsesBslmaAllocator)
void setStdoutThreshold(Severity::Level stdoutThreshold)
void setOnFileRotationCallback(const OnFileRotationCallback &onRotationCallback)
Definition ball_fileobserver.h:1002
bdlt::DatetimeInterval localTimeOffset() const
Definition ball_fileobserver.h:1048
bool isPublishInLocalTimeEnabled() const
void rotateOnTimeInterval(const bdlt::DatetimeInterval &interval)
Definition ball_fileobserver.h:988
void disableTimeIntervalRotation()
Definition ball_fileobserver.h:938
FileObserver2::OnFileRotationCallback OnFileRotationCallback
Definition ball_fileobserver.h:574
void disableUserFieldsLogging()
void suppressUniqueFileNameOnRotation(bool suppress)
Definition ball_fileobserver.h:1009
void setLogFormat(const char *logFileFormat, const char *stdoutFormat)
void forceRotation()
Definition ball_fileobserver.h:958
FileObserver(Severity::Level stdoutThreshold, bslma::Allocator *basicAllocator=0)
void disableFileLogging()
Definition ball_fileobserver.h:920
void enableStdoutLoggingPrefix()
int rotationSize() const
Definition ball_fileobserver.h:1060
void enableUserFieldsLogging()
FileObserver(bslma::Allocator *basicAllocator)
Severity::Level stdoutThreshold() const
~FileObserver() BSLS_KEYWORD_OVERRIDE
void publish(const Record &record, const Context &context) BSLS_KEYWORD_OVERRIDE
Definition ball_observer.h:235
Definition ball_recordstringformatter.h:218
Definition ball_record.h:178
Definition bdlt_datetimeinterval.h:201
Definition bdlt_datetime.h:331
Definition bslstl_string.h:1281
Definition bslstl_sharedptr.h:1830
Definition bslma_allocator.h:457
Definition bslmt_mutex.h:315
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition ball_administration.h:214
Definition bbldc_basicisma30360.h:112
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bdldfp_decimal.h:5188
This struct provides a namespace for enumerating severity levels.
Definition ball_severity.h:164
Level
Definition ball_severity.h:167
Definition bslma_usesbslmaallocator.h:343