BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_observer.h
Go to the documentation of this file.
1/// @file ball_observer.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_observer.h -*-C++-*-
8#ifndef INCLUDED_BALL_OBSERVER
9#define INCLUDED_BALL_OBSERVER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_observer ball_observer
15/// @brief Define a protocol for receiving and processing log records.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_observer
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_observer-purpose"> Purpose</a>
25/// * <a href="#ball_observer-classes"> Classes </a>
26/// * <a href="#ball_observer-description"> Description </a>
27/// * <a href="#ball_observer-usage"> Usage </a>
28///
29/// # Purpose {#ball_observer-purpose}
30/// Define a protocol for receiving and processing log records.
31///
32/// # Classes {#ball_observer-classes}
33///
34/// - ball::Observer: protocol class for receiving and processing log records
35///
36/// @see ball_record, ball_loggermanager
37///
38/// # Description {#ball_observer-description}
39/// This component defines the base-level protocol,
40/// `ball::Observer`, for receiving and processing log records. Concrete types
41/// derived from this protocol, receive log records, and process them in a
42/// manner defined by the derived class author.
43///
44/// ## Usage {#ball_observer-usage}
45///
46///
47/// This example shows the definition and use of a simple concrete observer that
48/// writes three of the log record's fields, timestamp, process ID, and thread
49/// ID, to an `ostream` that is provided to the observer at construction. This
50/// (trivial) functionality suffices to demonstrate the requisite steps for
51/// having a working observer:
52///
53/// 1. Define a concrete class derived from `ball::Observer`.
54/// 2. Implement the pure virtual `publish` method.
55/// 3. Instantiate and use an object of the concrete type.
56///
57/// Note that the "publish attributes" object provided to the `publish` method
58/// indicates, among other properties, whether the log record to be published is
59/// a "solo" message or whether it is one of a sequence. In general, a useful
60/// observer object should incorporate the attributes information as part of
61/// the "publication" of the log record. In this example, the attributes
62/// information is used to generate an appropriate heading for each log record
63/// that is printed to the observer's `ostream`.
64///
65/// We first define the (derived) `my_OstreamObserver` class and implement its
66/// simple constructor inline (for convenience, directly within the
67/// derived-class definition):
68/// @code
69/// // my_ostreamobserver.h
70///
71/// class my_OstreamObserver : public ball::Observer {
72/// ostream& d_stream;
73///
74/// public:
75/// my_OstreamObserver(ostream& stream) : d_stream(stream) { }
76/// virtual ~my_OstreamObserver();
77/// using Observer::publish; // avoid hiding base class method
78/// virtual void publish(const ball::Record& record,
79/// const ball::Context& context);
80/// };
81/// @endcode
82/// Note, however, that we always implement a virtual destructor (non-inline)
83/// in the .cpp file (to indicate the *unique* location of the class's virtual
84/// table):
85/// @code
86/// // my_ostreamobserver.cpp
87///
88/// // ...
89///
90/// my_OstreamObserver::~my_OstreamObserver() { }
91/// @endcode
92/// We next implement the (virtual) `publish` method, which incorporates the
93/// "policy" of what it means for this observer to "publish" a log record. In
94/// this example, the policy is that three log record fields are written to an
95/// `ostream`, along with an appropriate heading, and the rest of the log record
96/// is ignored. Note that, in this implementation, the zero-based `index`
97/// attribute is incremented by one before it is written, which produces a more
98/// natural record count:
99/// @code
100/// // my_ostreamobserver.cpp
101///
102/// // ...
103///
104/// my_OstreamObserver::~my_OstreamObserver() { }
105///
106/// void my_OstreamObserver::publish(const ball::Record& record,
107/// const ball::Context& context)
108/// {
109/// using namespace std;
110///
111/// d_stream << endl; // skip a line
112///
113/// switch (context.transmissionCause()) {
114/// case ball::Transmission::PASSTHROUGH: {
115/// d_stream << "Single Pass-through Message:" << endl;
116/// } break;
117/// case ball::Transmission::TRIGGER_ALL: {
118/// d_stream << "Remotely "; // no 'break'; concatenated output
119/// }
120/// case ball::Transmission::TRIGGER: {
121/// d_stream << "Triggered Publication Sequence: Message "
122/// << context.recordIndex() + 1 // Account for 0-based
123/// // index.
124/// << " of " << context.sequenceLength()
125/// << ':' << endl;
126/// } break;
127/// default: {
128/// d_stream << "***ERROR*** Unknown Message Cause:" << endl;
129/// return;
130/// } break;
131/// }
132///
133/// d_stream << "\tTimestamp: " << record.fixedFields().timestamp()
134/// << endl;
135/// d_stream << "\tProcess ID: " << record.fixedFields().processID()
136/// << endl;
137/// d_stream << "\tThread ID: " << record.fixedFields().threadID()
138/// << endl;
139/// }
140/// @endcode
141/// We now want to use the `my_OstreamObserver` object and its `publish` method;
142/// we illustrate this use in the body of the otherwise-unrealistic function
143/// `recordPublisher`, which generates the relevant fields of four dummy
144/// records. The first record is published singly (i.e., as a "Pass-through"
145/// record). Note that we call the observer's `publish` method with a
146/// `ball::Context` object appropriately initialized for a "Pass-through". The
147/// last three records are published as a sequence of "Triggered" records. Note
148/// that, in the sequenced output, the `publish` method is called with a
149/// zero-based `index` attribute; in this example, the `publish` implementation
150/// will print a natural-number message count equal to index + 1:
151/// @code
152/// void recordPublisher()
153/// {
154/// my_OstreamObserver myObserver(bsl::cout);
155/// bdlt::Datetime now;
156/// ball::RecordAttributes fixed;
157/// ball::UserFields emptyList;
158///
159/// bdlt::EpochUtil::convertFromTimeT(&now, time(0));
160/// fixed.setTimestamp(now);
161/// fixed.setProcessID(100);
162/// fixed.setThreadID(0);
163/// myObserver.publish(ball::Record(fixed, emptyList),
164/// ball::Context(ball::Transmission::PASSTHROUGH,
165/// 0,
166/// 1));
167///
168/// const int NUM_MESSAGES = 3;
169/// for (int n = 0; n < NUM_MESSAGES; ++n) {
170/// bdlt::EpochUtil::convertFromTimeT(&now, time(0));
171/// fixed.setTimestamp(now);
172/// fixed.setProcessID(201 + n);
173/// fixed.setThreadID(31 + n);
174/// myObserver.publish(ball::Record(fixed, emptyList),
175/// ball::Context(ball::Transmission::TRIGGER,
176/// n,
177/// NUM_MESSAGES));
178/// }
179/// }
180/// @endcode
181/// `recordPublisher`, when invoked, prints the following to `stdout`:
182/// @code
183/// Single Pass-through Message:
184/// Timestamp: 15JAN2004_23:12:59.000
185/// Process ID: 100
186/// Thread ID: 0
187///
188/// Triggered Publication Sequence: Message 1 of 3:
189/// Timestamp: 15JAN2004_23:12:59.000
190/// Process ID: 201
191/// Thread ID: 31
192///
193/// Triggered Publication Sequence: Message 2 of 3:
194/// Timestamp: 15JAN2004_23:12:59.000
195/// Process ID: 202
196/// Thread ID: 32
197///
198/// Triggered Publication Sequence: Message 3 of 3:
199/// Timestamp: 15JAN2004_23:12:59.000
200/// Process ID: 203
201/// Thread ID: 33
202/// @endcode
203/// @}
204/** @} */
205/** @} */
206
207/** @addtogroup bal
208 * @{
209 */
210/** @addtogroup ball
211 * @{
212 */
213/** @addtogroup ball_observer
214 * @{
215 */
216
217#include <balscm_version.h>
218
219#include <bsl_memory.h>
220
221
222namespace ball {
223
224class Record;
225class Context;
226
227 // ==============
228 // class Observer
229 // ==============
230
231/// This class provides a protocol for receiving and processing log record
232/// output.
233///
234/// See @ref ball_observer
235class Observer {
236
237 public:
238 // CREATORS
239
240 /// Destroy this observer.
241 virtual ~Observer();
242
243 // MANIPULATORS
244
245 /// Process the specified log `record` having the specified publishing
246 /// `context`.
247 ///
248 /// @deprecated Use the alternative `publish` overload instead.
249 virtual void publish(const Record& record, const Context& context);
250
251 /// Process the specified log `record` having the specified publishing
252 /// `context`. The exact definition of publish depends on the
253 /// implementing class, though the intention is that the log `record`
254 /// (whose publication has occurred according to `context`) be
255 /// distributed in a human or machine readable form.
256 virtual void publish(const bsl::shared_ptr<const Record>& record,
257 const Context& context);
258
259 /// Discard any shared references to `Record` objects that were supplied
260 /// to the `publish` method, and are held by this observer. Note that
261 /// this operation should be called if resources underlying the
262 /// previously provided shared pointers must be released.
263 virtual void releaseRecords();
264};
265
266} // close package namespace
267
268
269#endif
270
271// ----------------------------------------------------------------------------
272// Copyright 2015 Bloomberg Finance L.P.
273//
274// Licensed under the Apache License, Version 2.0 (the "License");
275// you may not use this file except in compliance with the License.
276// You may obtain a copy of the License at
277//
278// http://www.apache.org/licenses/LICENSE-2.0
279//
280// Unless required by applicable law or agreed to in writing, software
281// distributed under the License is distributed on an "AS IS" BASIS,
282// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
283// See the License for the specific language governing permissions and
284// limitations under the License.
285// ----------------------------- END-OF-FILE ----------------------------------
286
287/** @} */
288/** @} */
289/** @} */
Definition ball_context.h:295
Definition ball_observer.h:235
virtual void releaseRecords()
virtual void publish(const bsl::shared_ptr< const Record > &record, const Context &context)
virtual void publish(const Record &record, const Context &context)
virtual ~Observer()
Destroy this observer.
Definition ball_record.h:178
Definition bslstl_sharedptr.h:1830
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition ball_administration.h:214