BDE 4.39.x Production Release
Loading...
Searching...
No Matches
ball_streamobserver.h
Go to the documentation of this file.
1/// @file ball_streamobserver.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_streamobserver.h -*-C++-*-
8#ifndef INCLUDED_BALL_STREAMOBSERVER
9#define INCLUDED_BALL_STREAMOBSERVER
10
11/// @defgroup ball_streamobserver ball_streamobserver
12/// @brief Provide an observer that emits log records to a stream.
13/// @addtogroup bal
14/// @{
15/// @addtogroup ball
16/// @{
17/// @addtogroup ball_streamobserver
18/// @{
19///
20/// <h1> Outline </h1>
21/// * <a href="#ball_streamobserver-purpose"> Purpose</a>
22/// * <a href="#ball_streamobserver-classes"> Classes </a>
23/// * <a href="#ball_streamobserver-description"> Description </a>
24/// * <a href="#ball_streamobserver-log-record-formatting"> Log Record Formatting </a>
25/// * <a href="#ball_streamobserver-scheme-based-format-specifications"> Scheme-Based Format Specifications (Recommended) </a>
26/// * <a href="#ball_streamobserver-legacy-format-specifications"> Legacy Format Specifications </a>
27/// * <a href="#ball_streamobserver-thread-safety"> Thread Safety </a>
28/// * <a href="#ball_streamobserver-usage"> Usage </a>
29/// * <a href="#ball_streamobserver-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#ball_streamobserver-purpose}
32/// Provide an observer that emits log records to a stream.
33///
34/// # Classes {#ball_streamobserver-classes}
35///
36/// - ball::StreamObserver: observer that emits log records to a stream
37///
38/// @see ball_record, ball_context, ball_loggermanager
39///
40/// # Description {#ball_streamobserver-description}
41/// This component provides a concrete implementation of the
42/// `ball::Observer` protocol for receiving and processing log records:
43/// @code
44/// ,--------------------.
45/// ( ball::StreamObserver )
46/// `--------------------'
47/// | ctor
48/// | disablePublishInLocalTime
49/// | enablePublishInLocalTime
50/// | setFormat
51/// | setRecordFormatFunctor
52/// | getFormat
53/// | isPublishInLocalTimeEnabled
54/// V
55/// ,--------------.
56/// ( ball::Observer )
57/// `--------------'
58/// publish
59/// releaseRecords
60/// dtor
61/// @endcode
62/// `ball::StreamObserver` is a concrete class derived from `ball::Observer`
63/// that processes the log records it receives through its `publish` method by
64/// writing them to an output stream. Given its minimal functionality,
65/// `ball::StreamObserver` should be used with care in a production environment.
66/// It is not recommended to construct this observer with file-based streams due
67/// to lack of any file rotation functionality.
68///
69/// ## Log Record Formatting {#ball_streamobserver-log-record-formatting}
70///
71///
72/// By default, the output format of published log records is:
73/// @code
74/// DATE_TIME PID:THREAD-ID SEVERITY FILE:LINE CATEGORY MESSAGE USER-FIELDS
75/// @endcode
76/// where `DATE` and `TIME` are of the form `DDMonYYYY` and `HH:MM:SS.mmm`,
77/// respectively (`Mon` being the 3-letter abbreviation for the month). For
78/// example, a log record will have the following appearance when the default
79/// format is in effect (assuming that no user-defined fields are present):
80/// @code
81/// 18MAY2005_18:58:12.076 7959:1 WARN ball_streamobserver.t.cpp:404 TEST hello!
82/// @endcode
83/// For additional flexibility, the `setFormat` method can be called to
84/// configure the format of published records to the stream. The format
85/// specifications can be either scheme-tagged (recommended) or legacy
86/// `printf`-style format strings that results in a `RecordStringFormatter`
87/// being used.
88///
89/// ### Scheme-Based Format Specifications (Recommended) {#ball_streamobserver-scheme-based-format-specifications}
90///
91///
92/// The recommended way to specify log record formats is using URI-like
93/// scheme-tagged format configuration strings. A scheme-tagged format string
94/// begins with a scheme identifier followed by `://` and then a
95/// scheme-specific format specification:
96/// @code
97/// <scheme>://<format-specification>
98/// @endcode
99/// The scheme determines which formatter will be used and the syntax of the
100/// format specification. The following schemes are currently supported: text,
101/// json, qjson. See [Scheme-Based Formatters](@ref ball-scheme-based-formatters)
102/// for more details of the supported schemes and their accompanying format
103/// specification syntaxes.
104///
105/// For example, to log records to a file in JSON format with printf-style
106/// format specification:
107/// @code
108/// asyncFileObserver.setFormat("qjson://%d %p:%t %s %f:%l %c %m");
109/// @endcode
110///
111/// ### Legacy Format Specifications {#ball_streamobserver-legacy-format-specifications}
112///
113///
114/// For backward compatibility, format specifications that do not begin with a
115/// scheme tag are treated as legacy `printf`-style format strings. Such
116/// specifications are implicitly treated as if they had a `text://` prefix
117/// and use `ball::RecordStringFormatter`. For example, the following two
118/// calls are equivalent:
119/// @code
120/// streamObserver.setFormat("%d %p:%t %s %f:%l %c %m %a\n");
121/// streamObserver.setFormat("text://%d %p:%t %s %f:%l %c %m %a\n");
122/// @endcode
123/// These `%`-prefixed conversion specifications are defined in
124/// @ref ball_recordstringformatter .
125///
126/// ## Thread Safety {#ball_streamobserver-thread-safety}
127///
128///
129/// All methods of `ball::StreamObserver` are thread-safe, and can be called
130/// concurrently by multiple threads.
131///
132/// ## Usage {#ball_streamobserver-usage}
133///
134///
135/// This section illustrates intended use of this component.
136///
137/// ### Example 1: Basic Usage {#ball_streamobserver-example-1-basic-usage}
138///
139///
140/// The following snippets of code illustrate the basic usage of
141/// `ball::StreamObserver`.
142///
143/// First create a `ball::Record` object `record` and a `ball::Context` object
144/// `context`. Note that the default values for these objects (or their
145/// contained objects) are perfectly suitable for logging purposes.
146/// @code
147/// ball::RecordAttributes attributes;
148/// ball::UserFields fieldValues;
149/// ball::Context context;
150///
151/// bslma::Allocator *ga = bslma::Default::globalAllocator(0);
152/// const bsl::shared_ptr<const ball::Record>
153/// record(new (*ga) ball::Record(attributes, fieldValues, ga), ga);
154/// @endcode
155/// Next, create a stream observer `observer` with the `bsl::cout` as the output
156/// stream.
157/// @code
158/// ball::StreamObserver observer(&bsl::cout);
159/// @endcode
160/// Finally, publish `record` and `context` to `observer`.
161/// @code
162/// observer.publish(record, context);
163/// @endcode
164/// This will produce the following output on `stdout`:
165/// @code
166/// 01JAN0001_24:00:00.000 0 0 OFF 0
167/// @endcode
168/// @}
169/** @} */
170/** @} */
171
172/** @addtogroup bal
173 * @{
174 */
175/** @addtogroup ball
176 * @{
177 */
178/** @addtogroup ball_streamobserver
179 * @{
180 */
181
182#include <balscm_version.h>
183
185#include <ball_observer.h>
188
189#include <bsla_deprecated.h>
190
191#include <bslma_allocator.h>
192#include <bslma_bslallocator.h>
193
194#include <bslmt_mutex.h>
195
196#include <bsls_assert.h>
197#include <bsls_keyword.h>
198#include <bsls_review.h>
199
200#include <bsl_iosfwd.h>
201#include <bsl_functional.h>
202
203
204namespace ball {
205
206class Context;
207class Record;
208
209 // ====================
210 // class StreamObserver
211 // ====================
212
213/// This class provides a concrete implementation of the `Observer`
214/// protocol. The `publish` method of this class outputs the log records
215/// that it receives to an instance of `bsl::ostream` supplied at
216/// construction.
217///
218/// See @ref ball_streamobserver
219class StreamObserver : public Observer {
220 public:
221 // TYPES
222
223 /// `LogRecordFunctor` is an alias for the type of the functor used for
224 /// formatting log records to a stream.
227
229
230 private:
231 // PRIVATE TYPES
233
234 private:
235 // DATA
236 bsl::ostream *d_stream_p; // output sink for log
237 // records
238
239 mutable bslmt::Mutex d_mutex; // serializes concurrent
240 // calls to 'publish'
241
242 ObserverFormatterImp d_observerFormatterImp;
243 // formatter manager that
244 // handles all formatting
245 // operations
246
247 private:
248 // NOT IMPLEMENTED
250 StreamObserver& operator=(const StreamObserver&);
251
252 public:
253 // CREATORS
254
255 /// Create a stream observer that transmits log records to the specified
256 /// `stream`. Optionally specify an `allocator` (e.g., the address of a
257 /// `bslma::Allocator` object) to supply memory; otherwise, the default allocator is used.
258 ///
259 /// \note Note that a default record format is in effect
260 /// for stream logging (see `logRecordDefault`).
261 explicit
262 StreamObserver(bsl::ostream *stream,
263 const allocator_type& allocator = allocator_type());
264
265 /// Destroy this stream observer.
267
268 // MANIPULATORS
269
270 using Observer::publish; // Picks up the deprecated `publish` overload.
271
272 /// Process the specified log `record` having the specified publishing
273 /// `context`. Print `record` and `context` to the `bsl::ostream` supplied at construction.
274 ///
275 /// \pre The behavior is undefined if `record` or
276 /// `context` is modified during the execution of this method.
277 void publish(const bsl::shared_ptr<const Record>& record,
278 const Context& context)
280
281 /// Discard any shared reference to a `Record` object that was supplied
282 /// to the `publish` method, and is held by this observer.
283 ///
284 /// \note Note that this operation should be called if resources underlying the
285 /// previously provided shared-pointers must be released. This method
286 /// intentionally does nothing as such resources are held, we publish all
287 /// records immediately.
289
290 /// Disable publishing of the timestamp attribute of records in local
291 /// time by this stream observer; henceforth, timestamps will be in UTC
292 /// time. This method has no effect if publishing in local time is not
293 /// enabled.
295
296 /// Enable publishing of the timestamp attribute of records in local
297 /// time by this stream observer. By default, timestamps are published in UTC time.
298 ///
299 /// \note Note that this method also affects timestamps for
300 /// formatters that use them.
302
303 /// Set the formatting functor used when writing records to the stream of
304 /// this stream observer to the specified `formatter` functor.
305 ///
306 /// \note Note that a default format ("\n%d %p %t %s %f %l %c %m %u\n") is in effect until
307 /// this method or `setFormat` is called (see
308 /// @ref ball_recordstringformatter ). Also note that the observer emits
309 /// newline characters at the beginning and at the end of a log record
310 /// by default, so the user needs to add them explicitly to the format string to preserve this behavior.
311 ///
312 /// \note Note that this method is not
313 /// able to communicate the timezone default settings to the
314 /// `formatter`, prefer `setFormat`.
316
317 /// Set the formatting functor used when writing records to the stream of
318 /// this stream observer to a log file functor created according to the
319 /// specified, possibly URI-like scheme tagged, `format`. Return zero if
320 /// the setup with the specified arguments was successful and also save
321 /// the `format` to be later retrievable using `getFormat`. Otherwise (if
322 /// no matching scheme could be found or the configuration is invalid)
323 /// return a non-zero value and do not change the log record formatter used by this object.
324 ///
325 /// \note Note that a default format
326 /// ("\n%d %p %t %s %f %l %c %m %u\n") is in effect until this method or
327 /// `setRecordFormatFunctor` is called. Also, notice that the observer
328 /// emits newline characters at the beginning and at the end of a log
329 /// record by (the) default (format), so the user needs to add them
330 /// explicitly to (text) format strings to preserve that behavior.
331 int setFormat(const bsl::string_view& format);
332
333 // ACCESSORS
334
335 /// Return `true` if this observer writes the timestamp attribute of
336 /// records that it publishes in local time by default, and `false`
337 /// otherwise (in which case timestamps are written by default in UTC
338 /// time).
340
341 /// Return the format config of the last successful `setFormat` call.
342 const bsl::string& getFormat() const;
343};
344
345// ============================================================================
346// INLINE DEFINITIONS
347// ============================================================================
348
349 // --------------------
350 // class StreamObserver
351 // --------------------
352
353// MANIPULATORS
354inline
358
359} // close package namespace
360
361
362#endif
363
364// ----------------------------------------------------------------------------
365// Copyright 2017 Bloomberg Finance L.P.
366//
367// Licensed under the Apache License, Version 2.0 (the "License");
368// you may not use this file except in compliance with the License.
369// You may obtain a copy of the License at
370//
371// http://www.apache.org/licenses/LICENSE-2.0
372//
373// Unless required by applicable law or agreed to in writing, software
374// distributed under the License is distributed on an "AS IS" BASIS,
375// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
376// See the License for the specific language governing permissions and
377// limitations under the License.
378// ----------------------------- END-OF-FILE ----------------------------------
379
380/** @} */
381/** @} */
382/** @} */
Definition ball_context.h:297
Definition ball_observerformatterimp.h:398
Definition ball_observer.h:235
Definition ball_record.h:176
Definition ball_streamobserver.h:219
int setFormat(const bsl::string_view &format)
bool isPublishInLocalTimeEnabled() const
bsl::allocator< char > allocator_type
Definition ball_streamobserver.h:228
void disablePublishInLocalTime()
const bsl::string & getFormat() const
Return the format config of the last successful setFormat call.
RecordFormatterFunctor::Type RecordFormatFunctor
Definition ball_streamobserver.h:226
~StreamObserver() BSLS_KEYWORD_OVERRIDE
Destroy this stream observer.
void publish(const bsl::shared_ptr< const Record > &record, const Context &context) BSLS_KEYWORD_OVERRIDE
RecordFormatterFunctor::Type RecordFormatter
Definition ball_streamobserver.h:225
void setRecordFormatFunctor(const RecordFormatter &formatter)
void enablePublishInLocalTime()
void releaseRecords() BSLS_KEYWORD_OVERRIDE
Definition ball_streamobserver.h:355
StreamObserver(bsl::ostream *stream, const allocator_type &allocator=allocator_type())
Definition bslma_bslallocator.h:588
Forward declaration.
Definition bslstl_function.h:946
Definition bslmt_mutex.h:317
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition ball_administration.h:214
Definition bdlat_valuetypefunctions.h:939
Enum
Timezone setting for timestamps in log record formatters.
Definition ball_recordformattertimezone.h:114