BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_fileobserver2.h
Go to the documentation of this file.
1/// @file ball_fileobserver2.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_fileobserver2.h -*-C++-*-
8
9#ifndef INCLUDED_BALL_FILEOBSERVER2
10#define INCLUDED_BALL_FILEOBSERVER2
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id: $")
14
15/// @defgroup ball_fileobserver2 ball_fileobserver2
16/// @brief Provide a thread-safe observer that emits log records to a file.
17/// @addtogroup bal
18/// @{
19/// @addtogroup ball
20/// @{
21/// @addtogroup ball_fileobserver2
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#ball_fileobserver2-purpose"> Purpose</a>
26/// * <a href="#ball_fileobserver2-classes"> Classes </a>
27/// * <a href="#ball_fileobserver2-description"> Description </a>
28/// * <a href="#ball_fileobserver2-file-observer-configuration-synopsis"> File Observer Configuration Synopsis </a>
29/// * <a href="#ball_fileobserver2-log-record-formatting"> Log Record Formatting </a>
30/// * <a href="#ball_fileobserver2-log-record-timestamps"> Log Record Timestamps </a>
31/// * <a href="#ball_fileobserver2-local-time-offset-calculations"> Local Time Offset Calculations </a>
32/// * <a href="#ball_fileobserver2-log-filename-patterns"> Log Filename Patterns </a>
33/// * <a href="#ball_fileobserver2-log-file-rotation"> Log File Rotation </a>
34/// * <a href="#ball_fileobserver2-file-rotation-conditions"> File Rotation Conditions </a>
35/// * <a href="#ball_fileobserver2-rotated-file-naming"> Rotated File Naming </a>
36/// * <a href="#ball_fileobserver2-thread-safety"> Thread Safety </a>
37/// * <a href="#ball_fileobserver2-usage"> Usage </a>
38/// * <a href="#ball_fileobserver2-example-basic-usage"> Example: Basic Usage </a>
39///
40/// # Purpose {#ball_fileobserver2-purpose}
41/// Provide a thread-safe observer that emits log records to a file.
42///
43/// # Classes {#ball_fileobserver2-classes}
44///
45/// - ball::FileObserver2: observer that outputs log records to a file
46///
47/// @see ball_record, ball_context, ball_observer,
48/// ball_recordstringformatter
49///
50/// # Description {#ball_fileobserver2-description}
51/// This component provides a concrete implementation of the
52/// `ball::Observer` protocol, `ball::FileObserver2`, for publishing log records
53/// to a user-specified file. The following inheritance hierarchy diagram shows
54/// the classes involved and their methods:
55/// @code
56/// ,-------------------.
57/// ( ball::FileObserver2 )
58/// `-------------------'
59/// | ctor
60/// | disableFileLogging
61/// | disableTimeIntervalRotation
62/// | disableSizeRotation
63/// | disablePublishInLocalTime
64/// | enableFileLogging
65/// | enablePublishInLocalTime
66/// | forceRotation
67/// | rotateOnSize
68/// | rotateOnTimeInterval
69/// | setLogFileFunctor
70/// | setOnFileRotationCallback
71/// | suppressUniqueFileNameOnRotation
72/// | isFileLoggingEnabled
73/// | isPublishInLocalTimeEnabled
74/// | isSuppressUniqueFileNameOnRotation
75/// | rotationLifetime
76/// | rotationSize
77/// V
78/// ,--------------.
79/// ( ball::Observer )
80/// `--------------'
81/// dtor
82/// publish
83/// releaseRecords
84/// @endcode
85/// A `ball::FileObserver2` object processes the log records received through
86/// its `publish` method by writing them to a user-specified file. Note that
87/// the `enableFileLogging` method must be called to enable logging since
88/// logging to a file is initially disabled following construction. The format
89/// of published log records is user-configurable (see {Log Record Formatting}
90/// below). In addition, a file observer may be configured to perform automatic
91/// log file rotation (see {Log File Rotation} below).
92///
93/// ## File Observer Configuration Synopsis {#ball_fileobserver2-file-observer-configuration-synopsis}
94///
95///
96/// `ball::FileObserver2` offers several manipulators that may be used to
97/// configure various aspects of a file observer object. These are summarized
98/// in the following table along with the accessors that can be used to query
99/// the current state of the configuration. Further details are provided in the
100/// following sections and the function-level documentation.
101/// @code
102/// +-------------+------------------------------------+
103/// | Aspect | Related Methods |
104/// +=============+====================================+
105/// | Log Record | setLogFileFunctor |
106/// | Formatting | |
107/// +-------------+------------------------------------+
108/// | Log Record | enablePublishInLocalTime |
109/// | Timestamps | disablePublishInLocalTime |
110/// | | isPublishInLocalTimeEnabled |
111/// +-------------+------------------------------------+
112/// | File | enableFileLogging |
113/// | Logging | disableFileLogging |
114/// | | isFileLoggingEnabled |
115/// +-------------+------------------------------------+
116/// | Log File | rotateOnSize |
117/// | Rotation | rotateOnTimeInterval |
118/// | | disableSizeRotation |
119/// | | disableTimeIntervalRotation |
120/// | | setOnFileRotationCallback |
121/// | | suppressUniqueFileNameOnRotation |
122/// | | rotationSize |
123/// | | rotationLifetime |
124/// | | isSuppressUniqueFileNameOnRotation |
125/// +-------------+------------------------------------+
126/// @endcode
127/// In general, a `ball::FileObserver2` object can be dynamically configured
128/// throughout its lifetime (in particular, before or after being registered
129/// with a logger manager). However, note that for `ball::FileObserver2`,
130/// configuration changes that affect how records are logged (e.g.,
131/// `enablePublishInLocalTime` and `disablePublishInLocalTime`) impact only
132/// those records that are published subsequent to making the configuration
133/// change.
134///
135/// ## Log Record Formatting {#ball_fileobserver2-log-record-formatting}
136///
137///
138/// By default, the output format of published log records is:
139/// @code
140/// DATE_TIME PID:THREAD-ID SEVERITY FILE:LINE CATEGORY MESSAGE USER-FIELDS
141/// @endcode
142/// where `DATE` and `TIME` are of the form `DDMonYYYY` and `HH:MM:SS.mmm`,
143/// respectively (`Mon` being the 3-letter abbreviation for the month). For
144/// example, assuming that no user-defined fields are present, a log record
145/// will have the following appearance when the default format is in effect:
146/// @code
147/// 18MAY2005_18:58:12.076 7959:1 WARN ball_fileobserver2.t.cpp:404 TEST hello!
148/// @endcode
149/// The default format can be overridden by supplying a suitable formatting
150/// functor to `setLogFileFunctor`. For example, an instance of
151/// `ball::RecordStringFormatter` conveniently provides such a functor:
152/// @code
153/// fileObserver.setLogFileFunctor(
154/// ball::RecordStringFormatter("\n%I %p:%t %s %f:%l %c %m %u\n"));
155/// @endcode
156/// The above statement will cause subsequent records to be logged in a format
157/// that is almost identical to the default format except that the timestamp
158/// attribute will be written in ISO 8601 format. See
159/// @ref ball_recordstringformatter for information on how format specifications
160/// are defined and interpreted.
161///
162/// Note that the observer emits newline characters at the beginning and at the
163/// end of a log record by default, so the user needs to add them explicitly to
164/// the format string to preserve this behavior.
165///
166/// Also note that in the sample message above the timestamp has millisecond
167/// precision (`18MAY2005_18:58:12.076`). If microsecond precision is desired
168/// instead, consider using either the `%D` or `%O` format specification
169/// supported by @ref ball_recordstringformatter .
170///
171/// ## Log Record Timestamps {#ball_fileobserver2-log-record-timestamps}
172///
173///
174/// By default, the timestamp attributes of published records are written in UTC
175/// time. To write timestamps in local time instead, call the
176/// `enablePublishInLocalTime` method. Note that the local time offset is
177/// calculated using the UTC timestamp of each record. To revert to UTC time,
178/// call the `disablePublishInLocalTime` method. Whether UTC time or local time
179/// is in effect can be queried via `isPublishInLocalTimeEnabled`. However,
180/// note that if the user installs a log record formatting functor via
181/// `setLogFileFunctor`, then the supplied functor determines how record
182/// timestamps are rendered to the log.
183///
184/// ### Local Time Offset Calculations {#ball_fileobserver2-local-time-offset-calculations}
185///
186///
187/// The calculation of the local time offset adds some overhead to the
188/// publication of each log record. If this overhead is an issue, it can be
189/// mitigated by installing a high-performance local-time offset callback for
190/// `bdlt::CurrentTime` in `main`. See @ref bsls_systemtime for the details of
191/// installing such a callback and see @ref baltzo_localtimeoffsetutil for an
192/// example facility. Note that such callbacks can improve performance for all
193/// users of `bdlt::CurrentTime`, not just the `ball` logger.
194///
195/// ## Log Filename Patterns {#ball_fileobserver2-log-filename-patterns}
196///
197///
198/// The `enableFileLogging` method supports the use of `%`-escape sequences to
199/// specify log filenames. The recognized sequences are as follows:
200/// @code
201/// %Y - current year (4 digits with leading zeros)
202/// %M - current month (2 digits with leading zeros)
203/// %D - current day (2 digits with leading zeros)
204/// %h - current hour (2 digits with leading zeros)
205/// %m - current minute (2 digits with leading zeros)
206/// %s - current second (2 digits with leading zeros)
207/// %T - current datetime, equivalent to "%Y%M%D_%h%m%s"
208/// %p - process ID
209/// @endcode
210/// The date and time elements of the derived filename are based on the time
211/// when the log file is created. Furthermore, these elements are based on
212/// either UTC time or local time depending on the value returned by
213/// `isPublishInLocalTimeEnabled`. (See {Log Record Timestamps} for the
214/// similarity with the treatment of record timestamps.)
215///
216/// For example, a log filename pattern of "task.log.%Y%M%D_%h%m%s" will yield
217/// the filename `task.log.20110501_123000` if the file is created on
218/// 01-May-2011 at 12:30:00 local time (assuming `enablePublishInLocalTime` was
219/// called).
220///
221/// ## Log File Rotation {#ball_fileobserver2-log-file-rotation}
222///
223///
224/// A `ball::FileObserver2` may be configured to perform automatic rotation of
225/// log files based on simple file rotation conditions (or rules).
226///
227/// ### File Rotation Conditions {#ball_fileobserver2-file-rotation-conditions}
228///
229///
230/// Rotation rules may be established based on the size of the log file (i.e., a
231/// "rotation-on-size" rule), and a periodic time interval (i.e., a
232/// "rotation-on-time-interval" rule). These rules are independently enabled by
233/// the `rotateOnSize` and `rotateOnTimeInterval` methods, respectively. If
234/// both rules are in effect, log file rotation is performed whenever either
235/// rule applies.
236///
237/// ### Rotated File Naming {#ball_fileobserver2-rotated-file-naming}
238///
239///
240/// When a log file is rotated, a new filename is generated using the pattern
241/// supplied to `enableFileLogging`. If the file having the new name does not
242/// exist, the current log file is closed, and the logging continues to the new
243/// file.
244///
245/// If the file having the new name already exits, then the behavior of the file
246/// rotation is further controlled by the flag set with
247/// `suppressUniqueFileNameOnRotation`:
248///
249/// * `suppressUniqueFileNameOnRotation(false)` (*default* behavior)
250/// The current log filename is renamed by appending a timestamp in the form
251/// ".%Y%M%D_%h%m%s" where the timestamp indicates when the file being
252/// rotated was last opened (the time of either the last file rotation or the
253/// last call to `enableFileLogging`, whichever is most recent). As with the
254/// timestamps of logged records, the timestamps appended to log filenames
255/// upon rotation will be in UTC time or local time depending on the value
256/// returned by `isPublishInLocalTimeEnabled`.
257/// * `suppressUniqueFileNameOnRotation(true)`
258/// The logging continues to the *current* log file, effectively suppressing
259/// log filename rotation. This may happen when the log file pattern does
260/// not contain %-escape sequences indicating a time period, or the rotation
261/// interval is less than the time period encoded by %-escape sequences. In
262/// order to rotate log files in this mode, the log file pattern MUST contain
263/// %-escape sequences that specify date and (optionally) time. For example,
264/// the log filename pattern "app_%Y%M%D.log" will produce a single log file
265/// per calendar day (assuming, the rotation on time is enabled and the
266/// rotation happens at least once a day).
267///
268/// The two tables below illustrate the names of old and new log files when a
269/// file rotation occurs. We assume that the log file is rotated on 2011-May-21
270/// at 12:29:59 local time and that the last rotation occurred at 12:30:00 on
271/// the previous day. We further assume that `enablePublishInLocalTime` was
272/// called, so that all date and time elements are rendered in local time.
273///
274/// The first table shows the name change (if any) of the (old) log file being
275/// rotated when the flag controlled by `suppressUniqueFileNameOnRotation`
276/// is set to `false`:
277/// @code
278/// Disabled: `suppressUniqueFileNameOnRotation`
279///
280/// For brevity:
281/// <TS1> = 20210520_123000
282/// <TS2> = 20210521_122959 (aka next day, about the same time)
283///
284/// +----------------+-----------------+----------------+----------------------
285/// | Pattern | Filename Before | Filename After | Rotated Filename
286/// | | Rotation | Rotation |
287/// +----------------+-----------------+----------------+----------------------
288/// | "a.log" | a.log | a.log | a.log.<TS1>
289/// | "a.log.%T" | a.log.<TS1> | a.log.<TS2> | a.log.<TS1>
290/// | "a.log.%Y%M" | a.log.202105 | a.log.202105 | a.log.202105.<TS1>
291/// | "a.log.%Y%M%D" | a.log.20210520 | a.log.20110521 | a.log.20210520
292/// +----------------+-----------------+----------------+----------------------
293/// @endcode
294/// Note that upon rotation a timestamp was appended to the name of the rotated
295/// file when the log pattern does not contain %-escape sequences indicating a
296/// time period ("a.log"), or the rotation period (in our case, one day) is less
297/// than the time period encoded in the pattern (in case of "a.log.%Y%M" the
298/// period is one month).
299///
300/// The next table shows the rotated name when the flag controlled by
301/// `suppressUniqueFileNameOnRotation` is set to `true`, and (possibly new) name
302/// of the (new) log file following rotation:
303/// @code
304/// Enabled: `suppressUniqueFileNameOnRotation`
305///
306/// +----------------+-----------------+----------------+----------------------
307/// | Pattern | Filename Before | Filename After | Rotated Filename
308/// | | Rotation | Rotation |
309/// +----------------+-----------------+----------------+----------------------
310/// | "a.log" | a.log | a.log | none
311/// | "a.log.%T" | a.log.<TS1> | a.log.<TS2> | a.log.<TS1>
312/// | "a.log.%Y%M" | a.log.202105 | a.log.202105 | none
313/// | "a.log.%Y%M%D" | a.log.20210520 | a.log.20110521 | a.log.20210520
314/// +----------------+-----------------+----------------+----------------------
315/// @endcode
316/// Note that the original filename is reused when the log pattern does not
317/// contain %-escape sequences indicating a time period ("a.log"), or the
318/// rotation period (in our case, one day) is less than the time period encoded
319/// in the pattern (in case of "a.log.%Y%M" the period is one month).
320///
321/// Also note, that in any cases, when the log pattern includes "%T", or encodes
322/// a time period that coincides the rotation period (in case of "a.log.%Y%M%D"
323/// the period is one day), then a unique name on each rotation is produced with
324/// the (local) time at which file rotation occurred embedded in the filename.
325///
326/// ## Thread Safety {#ball_fileobserver2-thread-safety}
327///
328///
329/// All methods of `ball::FileObserver2` are thread-safe, and can be called
330/// concurrently by multiple threads.
331///
332/// ## Usage {#ball_fileobserver2-usage}
333///
334///
335/// This section illustrates intended use of this component.
336///
337/// ### Example: Basic Usage {#ball_fileobserver2-example-basic-usage}
338///
339///
340/// First, we create a `ball::LoggerManagerConfiguration` object, `lmConfig`,
341/// and set the logging "pass-through" level -- the level at which log records
342/// are published to registered observers -- to `DEBUG`:
343/// @code
344/// int main()
345/// {
346/// ball::LoggerManagerConfiguration lmConfig;
347/// lmConfig.setDefaultThresholdLevelsIfValid(ball::Severity::e_DEBUG);
348/// @endcode
349/// Next, create a `ball::LoggerManagerScopedGuard` object whose constructor
350/// takes the configuration object just created. The guard will initialize the
351/// logger manager singleton on creation and destroy the singleton upon
352/// destruction. This guarantees that any resources used by the logger manager
353/// will be properly released when they are not needed:
354/// @code
355/// ball::LoggerManagerScopedGuard guard(lmConfig);
356/// ball::LoggerManager& manager = ball::LoggerManager::singleton();
357/// @endcode
358/// Next, we create a `ball::FileObserver2` object and register it with the
359/// `ball` logging system;
360/// @code
361/// bsl::shared_ptr<ball::FileObserver2> observer =
362/// bsl::make_shared<ball::FileObserver2>();
363/// @endcode
364/// Next, we configure the log file rotation rules:
365/// @code
366/// // Rotate the file when its size becomes greater than or equal to 128
367/// // megabytes.
368/// observer->rotateOnSize(1024 * 128);
369///
370/// // Rotate the file every 24 hours.
371/// observer->rotateOnTimeInterval(bdlt::DatetimeInterval(1));
372/// @endcode
373/// Note that in this configuration the user may end up with multiple log files
374/// for a specific day (because of the rotation-on-size rule).
375///
376/// Then, we enable logging to a file:
377/// @code
378/// // Create and log records to a file named "/var/log/task/task.log".
379/// observer->enableFileLogging("/var/log/task/task.log");
380/// @endcode
381/// Finally, we register the file observer with the logger manager. Upon
382/// successful registration, the observer will start to receive log records via
383/// the `publish` method:
384/// @code
385/// int rc = manager.registerObserver(observer, "default");
386/// assert(0 == rc);
387/// return 0;
388/// }
389/// @endcode
390/// @}
391/** @} */
392/** @} */
393
394/** @addtogroup bal
395 * @{
396 */
397/** @addtogroup ball
398 * @{
399 */
400/** @addtogroup ball_fileobserver2
401 * @{
402 */
403
404#include <balscm_version.h>
405
406#include <ball_observer.h>
407#include <ball_severity.h>
408
409#include <bdls_fdstreambuf.h>
410
411#include <bdlt_datetime.h>
413
414#include <bslma_allocator.h>
416
418
419#include <bslmt_mutex.h>
420
421#include <bsls_keyword.h>
422#include <bsls_libraryfeatures.h>
423
424#include <bsl_fstream.h>
425#include <bsl_functional.h>
426#include <bsl_iosfwd.h>
427#include <bsl_memory.h>
428#include <bsl_string.h>
429
430#include <string> // `std::string`, `std::pmr::string`
431
432
433namespace ball {
434
435class Context;
436class Record;
437
438 // ===================
439 // class FileObserver2
440 // ===================
441
442/// This class implements the `Observer` protocol. The `publish` method of
443/// this class outputs the log records that it receives to a user-specified
444/// file. This class is thread-safe; different threads can operate on an
445/// object concurrently. This class is exception-neutral with no guarantee
446/// of rollback. In no event is memory leaked.
447///
448/// See @ref ball_fileobserver2
449class FileObserver2 : public Observer {
450
451 public:
452 // PUBLIC TYPES
453
454 /// `LogRecordFunctor` is an alias for the type of the functor used for
455 /// formatting log records to a stream.
456 typedef bsl::function<void(bsl::ostream&, const Record&)> LogRecordFunctor;
457
458 /// `OnFileRotationCallback` is an alias for a user-supplied callback
459 /// function that is invoked after the file observer attempts to rotate
460 /// its log file. The callback takes two arguments: (1) an integer
461 /// status value where 0 indicates a new log file was successfully
462 /// created and a non-zero value indicates an error occurred during
463 /// rotation, and (2) a string that provides the name of the rotated log
464 /// file if the rotation was successful. E.g.:
465 /// @code
466 /// void onLogFileRotation(int rotationStatus,
467 /// const bsl::string& rotatedLogFileName);
468 /// @endcode
469 typedef bsl::function<void(int, const bsl::string&)>
471
472 private:
473 // DATA
474 bdls::FdStreamBuf d_logStreamBuf; // stream buffer for
475 // file logging
476
477 bsl::ostream d_logOutStream; // output stream for
478 // file logging (refers
479 // to `d_logStreamBuf`)
480
481 bsl::string d_logFilePattern; // log filename pattern
482
483 bsl::string d_logFileName; // current log filename
484
485 bdlt::Datetime d_logFileTimestampUtc; // modification time of
486 // the log file when it
487 // was opened (or the
488 // creation time if the
489 // log file did not
490 // already exist)
491
492 LogRecordFunctor d_logFileFunctor; // formatting functor
493 // used when writing to
494 // log file
495
496 bool d_publishInLocalTime; // `true` if timestamps
497 // of records are output
498 // in local time,
499 // otherwise UTC time
500
501 bool d_suppressUniqueFileName; // `false` if rotated
502 // log file has a unique
503 // name
504
505 mutable bslmt::Mutex d_mutex; // serialize operations
506
507 int d_rotationSize; // maximum log file size
508 // before rotation (in
509 // kilobytes)
510
511 bdlt::Datetime d_rotationReferenceTime; // reference start time
512 // (time-zone determined
513 // by
514 // d_publishInLocalTime)
515 // for time-based
516 // rotation
517
518 bdlt::DatetimeInterval d_rotationInterval; // time interval between
519 // two time-based
520 // rotations
521
522 bdlt::Datetime d_nextRotationTimeUtc; // next scheduled time
523 // for time-based
524 // rotation
525
526 OnFileRotationCallback d_onRotationCb; // user callback
527 // invoked following
528 // file rotation
529
530 mutable bslmt::Mutex d_rotationCbMutex; // serialize access to
531 // 'd_onRotationCb';
532 // required because
533 // callback must be
534 // called with 'd_mutex'
535 // unlocked
536
537 private:
538 // NOT IMPLEMENTED
540 FileObserver2& operator=(const FileObserver2&);
541
542 private:
543 // PRIVATE MANIPULATORS
544
545 /// Write the specified log `record` to the specified output `stream`
546 /// using the default record format of this file observer.
547 void logRecordDefault(bsl::ostream& stream, const Record& record);
548
549 /// Perform a log file rotation by closing the current log file of this
550 /// file observer, renaming the closed log file if necessary, and
551 /// opening a new log file. Load, into the specified
552 /// `rotatedLogFileName`, the name of the rotated log file. Return 0 on
553 /// success, a positive value if logging is not enabled, and a negative
554 /// value otherwise. The existing log file is renamed if the new log
555 /// filename, as determined by the `logFilenamePattern` of the latest
556 /// call to `enableFileLogging`, is the same as the old log filename.
557 int rotateFile(bsl::string *rotatedLogFileName);
558
559 /// Perform log file rotation if the specified `currentLogTimeUtc` is
560 /// later than the scheduled rotation time of the current log file, or
561 /// if the log file is larger than the allowable size, and if a rotation
562 /// is performed, load into the specified `rotatedLogFileName` the name
563 /// of the rotated file. Return 0 if the log file is rotated
564 /// successfully, a positive value if a rotation was determined to be
565 /// unnecessary, and a negative value otherwise. The rotation schedule
566 /// and the allowable file size are set by the `rotateOnTimeInterval`
567 /// and the `rotateOnSize` methods, respectively. The behavior is
568 /// undefined unless the caller acquired the lock for this object.
569 int rotateIfNecessary(bsl::string *rotatedLogFileName,
570 const bdlt::Datetime& currentLogTimeUtc);
571
572 // PRIVATE ACCESSORS
573
574 /// Return `true` if file logging is enabled for this file observer, and
575 /// `false` otherwise. Load the specified `result` with the name of the
576 /// current log file if file logging is enabled, and leave `result`
577 /// unmodified otherwise.
578 template <class t_STRING>
579 bool isFileLoggingEnabledImpl(t_STRING *result) const;
580
581 public:
582 // TRAITS
584
585 // CREATORS
586
587 /// Create a file observer with file logging initially disabled.
588 /// Optionally specify a `basicAllocator` used to supply memory. If
589 /// `basicAllocator` is 0, the currently installed default allocator is
590 /// used. Note that `isPublishInLocalTimeEnabled` returns `false`
591 /// following construction indicating that the timestamp attribute of
592 /// published records will be written in UTC time (see
593 /// `enablePublishInLocalTime`). Also note that a default record format
594 /// is in effect for file logging (see `setLogFileFunctor`).
595 explicit FileObserver2(bslma::Allocator *basicAllocator = 0);
596
597 /// Close the log file of this file observer if file logging is enabled,
598 /// and destroy this file observer.
600
601 // MANIPULATORS
602
603 /// Disable file logging for this file observer. This method has no
604 /// effect if file logging is not enabled. Note that records
605 /// subsequently received through the `publish` method will be dropped
606 /// until file logging is re-enabled.
608
609 /// Disable log file rotation based on a periodic time interval for this
610 /// file observer. This method has no effect if
611 /// rotation-on-time-interval is not enabled.
612 ///
613 /// @deprecated Use @ref disableTimeIntervalRotation instead.
615
616 /// Disable publishing of the timestamp attribute of records in local
617 /// time by this file observer; henceforth, timestamps will be in UTC
618 /// time. This method has no effect if publishing in local time is not
619 /// enabled. Note that this method also affects log filenames (see {Log
620 /// Filename Patterns}).
622
623 /// Disable log file rotation based on log file size for this file
624 /// observer. This method has no effect if rotation-on-size is not
625 /// enabled.
627
628 /// Disable log file rotation based on a periodic time interval for this
629 /// file observer. This method has no effect if
630 /// rotation-on-time-interval is not enabled.
632
633 /// Enable logging of all records published to this file observer to a
634 /// file whose name is derived from the specified `logFilenamePattern`.
635 /// Return 0 on success, a positive value if file logging is already
636 /// enabled (with no effect), and a negative value otherwise. The
637 /// basename of `logFilenamePattern` may contain `%`-escape sequences
638 /// that are interpreted as follows:
639 /// @code
640 /// %Y - current year (4 digits with leading zeros)
641 /// %M - current month (2 digits with leading zeros)
642 /// %D - current day (2 digits with leading zeros)
643 /// %h - current hour (2 digits with leading zeros)
644 /// %m - current minute (2 digits with leading zeros)
645 /// %s - current second (2 digits with leading zeros)
646 /// %T - current datetime, equivalent to "%Y%M%D_%h%m%s"
647 /// %p - process ID
648 /// @endcode
649 /// Each time a log file is opened by this file observer (upon a
650 /// successful call to this method and following each log file
651 /// rotation), the name of the new log file is derived from
652 /// `logFilenamePattern` by interpreting the above recognized `%`-escape
653 /// sequences. If `isPublishInLocalTimeEnabled` returns `true`, the
654 /// `%`-escape sequences related to time will be substituted with local
655 /// time values, and UTC time values otherwise. See {Log Filename
656 /// Patterns}.
657 int enableFileLogging(const char *logFilenamePattern);
658
659 /// Enable logging of all records published to this file observer to a
660 /// file whose name is derived from the specified `logFilenamePattern`
661 /// and append a timestamp to the log filename if the specified
662 /// `appendTimestampFlag` is `true`. Return 0 on success, a positive
663 /// value if file logging is already enabled (with no effect), and a
664 /// negative value otherwise. If the `appendTimestampFlag` is `true`
665 /// and `logFilenamePattern` does not contain any `%`-escape sequences,
666 /// this method behaves as if ".%T" is appended to `logFilenamePattern`.
667 ///
668 /// @deprecated Use @ref enableFileLogging(logFilenamePattern) instead
669 /// (use the ".%T" pattern to replicate `true == appendTimestampFlag`
670 /// behavior).
671 int enableFileLogging(const char *logFilenamePattern,
672 bool appendTimestampFlag);
673
674 /// Enable publishing of the timestamp attribute of records in local
675 /// time by this file observer. This method has no effect if publishing
676 /// in local time is already enabled. Note that this method also
677 /// affects log filenames (see {Log Filename Patterns}).
679
680 /// Process the specified log `record` having the specified publishing
681 /// `context` by writing `record` and `context` to the current log file
682 /// if file logging is enabled for this file observer. The method has
683 /// no effect if file logging is not enabled, in which case `record` is
684 /// dropped.
685 ///
686 /// @deprecated Do not use.
687 void publish(const Record& record,
688 const Context& context) BSLS_KEYWORD_OVERRIDE;
689
690 /// Process the record referenced by the specified `record` shared
691 /// pointer having the specified publishing `context` by writing the
692 /// record and `context` to the current log file if file logging is
693 /// enabled for this file observer. The method has no effect if file
694 /// logging is not enabled, in which case `record` is dropped.
695 void publish(const bsl::shared_ptr<const Record>& record,
696 const Context& context)
698
699 /// Discard any shared references to `Record` objects that were supplied
700 /// to the `publish` method, and are held by this observer. Note that
701 /// this operation should be called if resources underlying the
702 /// previously provided shared pointers must be released.
704
705 /// Forcefully perform a log file rotation by this file observer. Close
706 /// the current log file, rename the log file if necessary, and open a
707 /// new log file. This method has no effect if file logging is not
708 /// enabled. See {Rotated File Naming} for details on filenames of
709 /// rotated log files.
711
712 /// Set this file observer to perform log file rotation when the size of
713 /// the file exceeds the specified `size` (in kilobytes). This rule
714 /// replaces any rotation-on-size rule currently in effect. The
715 /// behavior is undefined unless `size > 0`.
716 void rotateOnSize(int size);
717
718 /// Set this file observer to perform a periodic log file rotation at
719 /// multiples of the specified `timeInterval`. This rule replaces any
720 /// rotation-on-time-interval rule currently in effect. The behavior is
721 /// undefined unless `0 < timeInterval.totalMilliseconds()`.
722 ///
723 /// @deprecated Use @ref rotateOnTimeInterval instead.
724 void rotateOnLifetime(const bdlt::DatetimeInterval& timeInterval);
725
726 void rotateOnTimeInterval(const bdlt::DatetimeInterval& interval);
727 /// Set this file observer to perform a periodic log file rotation at
728 /// multiples of the specified `interval`. Optionally specify a
729 /// `startTime` indicating the datetime to use as the starting point for
730 /// computing the periodic rotation schedule. If
731 /// `isPublishInLocalTimeEnabled` is `true`, the `startTime` is
732 /// interpreted as local time, and as a UTC time otherwise. If
733 /// `startTime` is not specified, the current time is used. This rule
734 /// replaces any rotation-on-time-interval rule currently in effect.
735 /// The behavior is undefined unless `0 < interval.totalMilliseconds()`.
736 /// Note that `startTime` may be a fixed time in the past; e.g., a
737 /// reference time of `bdlt::Datetime(1, 1, 1)` and an interval of 24
738 /// hours would configure a periodic rotation at midnight each day.
739 void rotateOnTimeInterval(const bdlt::DatetimeInterval& interval,
740 const bdlt::Datetime& startTime);
741
742 /// Set the formatting functor used when writing records to the log file
743 /// of this file observer to the specified `logFileFunctor`. Note that
744 /// a default format ("\n%d %p:%t %s %f:%l %c %m %u\n") is in effect
745 /// until this method is called (see @ref ball_recordstringformatter ).
746 /// Also note that the observer emits newline characters at the
747 /// beginning and at the end of a log record by default, so the user
748 /// needs to add them explicitly to the format string to preserve this
749 /// behavior.
750 void setLogFileFunctor(const LogRecordFunctor& logFileFunctor);
751
752
753 /// Set the specified `onRotationCallback` to be invoked after each time
754 /// this file observer attempts to perform a log file rotation. The
755 /// behavior is undefined if the supplied function calls either
756 /// `setOnFileRotationCallback`, `forceRotation`, or `publish` on this
757 /// file observer (i.e., the supplied callback should *not* attempt to
758 /// write to the `ball` log).
760 const OnFileRotationCallback& onRotationCallback);
761
762 /// Suppress generating a unique log file name upon rotation if the
763 /// specified `suppress` is `true`, and generate a unique filename
764 /// otherwise. See {Rotated File Naming} for details.
766
767 // ACCESSORS
768
769 /// Return `true` if file logging is enabled for this file observer, and
770 /// `false` otherwise. Load the optionally specified `result` with the
771 /// name of the current log file if file logging is enabled, and leave
772 /// `result` unmodified otherwise. Note that records received through
773 /// the `publish` method of this file observer will be dropped when this
774 /// method returns `false`.
776 bool isFileLoggingEnabled(bsl::string *result) const;
777 bool isFileLoggingEnabled(std::string *result) const;
778
779#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
780 /// Return `true` if file logging is enabled for this file observer, and
781 /// `false` otherwise. Load the specified `result` with the name of the
782 /// current log file if file logging is enabled, and leave `result`
783 /// unmodified otherwise.
784 bool isFileLoggingEnabled(std::pmr::string *result) const;
785#endif // BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
786
787 /// Return `true` if this file observer writes the timestamp attribute
788 /// of records that it publishes in local time, and `false` otherwise
789 /// (in which case timestamps are written in UTC time). Note that the
790 /// value returned by this method also affects log filenames (see {Log
791 /// Filename Patterns}).
793
794 /// Return `true` if the log filename uniqueness check on rotation is
795 /// suppressed, and false otherwise.
797
798 /// Return the lifetime of the log file that will trigger a file
799 /// rotation by this file observer if rotation-on-lifetime is in effect,
800 /// and a 0 time interval otherwise.
802
803 /// Return the size (in kilobytes) of the log file that will trigger a
804 /// file rotation by this file observer if rotation-on-size is in
805 /// effect, and 0 otherwise.
806 int rotationSize() const;
807
808 /// Return the difference between the local time and UTC time in effect
809 /// when this file observer was constructed. Note that this value
810 /// remains unchanged during the lifetime of this object and therefore
811 /// may become incorrect when the difference between the local time and
812 /// UTC time changes (e.g., when transitioning into or out of daylight
813 /// savings time).
814 ///
815 /// @deprecated Use @ref bdlt::LocalTimeOffset instead.
817};
818
819// ============================================================================
820// INLINE DEFINITIONS
821// ============================================================================
822
823 // -------------------
824 // class FileObserver2
825 // -------------------
826
827// MANIPULATORS
828inline
830 const Context& context)
831{
832 publish(*record, context);
833}
834
835inline
839
840} // close package namespace
841
842
843#endif
844
845// ----------------------------------------------------------------------------
846// Copyright 2015 Bloomberg Finance L.P.
847//
848// Licensed under the Apache License, Version 2.0 (the "License");
849// you may not use this file except in compliance with the License.
850// You may obtain a copy of the License at
851//
852// http://www.apache.org/licenses/LICENSE-2.0
853//
854// Unless required by applicable law or agreed to in writing, software
855// distributed under the License is distributed on an "AS IS" BASIS,
856// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
857// See the License for the specific language governing permissions and
858// limitations under the License.
859// ----------------------------- END-OF-FILE ----------------------------------
860
861/** @} */
862/** @} */
863/** @} */
Definition ball_context.h:295
Definition ball_fileobserver2.h:449
void rotateOnSize(int size)
bsl::function< void(int, const bsl::string &)> OnFileRotationCallback
Definition ball_fileobserver2.h:470
void rotateOnTimeInterval(const bdlt::DatetimeInterval &interval)
bool isSuppressUniqueFileNameOnRotation() const
bdlt::DatetimeInterval rotationLifetime() const
bdlt::DatetimeInterval localTimeOffset() const
void disablePublishInLocalTime()
void rotateOnLifetime(const bdlt::DatetimeInterval &timeInterval)
void releaseRecords() BSLS_KEYWORD_OVERRIDE
Definition ball_fileobserver2.h:836
bool isFileLoggingEnabled() const
void disableLifetimeRotation()
int rotationSize() const
void disableTimeIntervalRotation()
~FileObserver2() BSLS_KEYWORD_OVERRIDE
void enablePublishInLocalTime()
void publish(const Record &record, const Context &context) BSLS_KEYWORD_OVERRIDE
bsl::function< void(bsl::ostream &, const Record &)> LogRecordFunctor
Definition ball_fileobserver2.h:456
void setOnFileRotationCallback(const OnFileRotationCallback &onRotationCallback)
int enableFileLogging(const char *logFilenamePattern)
BSLMF_NESTED_TRAIT_DECLARATION(FileObserver2, bslma::UsesBslmaAllocator)
bool isPublishInLocalTimeEnabled() const
void setLogFileFunctor(const LogRecordFunctor &logFileFunctor)
FileObserver2(bslma::Allocator *basicAllocator=0)
void suppressUniqueFileNameOnRotation(bool suppress)
Definition ball_observer.h:235
Definition ball_record.h:178
Definition bdls_fdstreambuf.h:653
Definition bdlt_datetimeinterval.h:201
Definition bdlt_datetime.h:331
Definition bslstl_string.h:1281
Forward declaration.
Definition bslstl_function.h:934
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 bdldfp_decimal.h:5188
Definition bslma_usesbslmaallocator.h:343