Outline
Purpose
Define a protocol for receiving and processing log records.
Classes
- ball::Observer: protocol class for receiving and processing log records
- See also
- ball_record, ball_loggermanager
Description
This component defines the base-level protocol, ball::Observer
, for receiving and processing log records. Concrete types derived from this protocol, receive log records, and process them in a manner defined by the derived class author.
Usage
This example shows the definition and use of a simple concrete observer that writes three of the log record's fields, timestamp, process ID, and thread ID, to an ostream
that is provided to the observer at construction. This (trivial) functionality suffices to demonstrate the requisite steps for having a working observer:
- Define a concrete class derived from
ball::Observer
.
- Implement the pure virtual
publish
method.
- Instantiate and use an object of the concrete type.
Note that the "publish attributes" object provided to the publish
method indicates, among other properties, whether the log record to be published is a "solo" message or whether it is one of a sequence. In general, a useful observer object should incorporate the attributes information as part of the "publication" of the log record. In this example, the attributes information is used to generate an appropriate heading for each log record that is printed to the observer's ostream
.
We first define the (derived) my_OstreamObserver
class and implement its simple constructor inline (for convenience, directly within the derived-class definition):
ostream& d_stream;
public:
my_OstreamObserver(ostream& stream) : d_stream(stream) { }
virtual ~my_OstreamObserver();
using Observer::publish;
};
Definition ball_context.h:295
Definition ball_observer.h:235
virtual void publish(const Record &record, const Context &context)
Definition ball_record.h:178
Note, however, that we always implement a virtual destructor (non-inline) in the .cpp file (to indicate the unique location of the class's virtual table):
my_OstreamObserver::~my_OstreamObserver() { }
We next implement the (virtual) publish
method, which incorporates the "policy" of what it means for this observer to "publish" a log record. In this example, the policy is that three log record fields are written to an ostream
, along with an appropriate heading, and the rest of the log record is ignored. Note that, in this implementation, the zero-based index
attribute is incremented by one before it is written, which produces a more natural record count:
my_OstreamObserver::~my_OstreamObserver() { }
void my_OstreamObserver::publish(
const ball::Record& record,
{
d_stream << endl;
case ball::Transmission::PASSTHROUGH: {
d_stream << "Single Pass-through Message:" << endl;
} break;
case ball::Transmission::TRIGGER_ALL: {
d_stream << "Remotely ";
}
case ball::Transmission::TRIGGER: {
d_stream << "Triggered Publication Sequence: Message "
<< ':' << endl;
} break;
default: {
d_stream << "***ERROR*** Unknown Message Cause:" << endl;
return;
} break;
}
<< endl;
<< endl;
<< endl;
}
Transmission::Cause transmissionCause() const
Return the transmission cause attribute of this context object.
Definition ball_context.h:501
int recordIndex() const
Return the record index attribute of this context object.
Definition ball_context.h:507
int sequenceLength() const
Return the sequence length attribute of this context object.
Definition ball_context.h:513
const bdlt::Datetime & timestamp() const
Return the timestamp attribute of this record attributes object.
Definition ball_recordattributes.h:635
bsls::Types::Uint64 threadID() const
Return the threadID attribute of this record attributes object.
Definition ball_recordattributes.h:617
int processID() const
Return the processID attribute of this record attributes object.
Definition ball_recordattributes.h:605
RecordAttributes & fixedFields()
Return the modifiable fixed fields of this log record.
Definition ball_record.h:396
Definition bdldfp_decimal.h:5188
We now want to use the my_OstreamObserver
object and its publish
method; we illustrate this use in the body of the otherwise-unrealistic function recordPublisher
, which generates the relevant fields of four dummy records. The first record is published singly (i.e., as a "Pass-through" record). Note that we call the observer's publish
method with a ball::Context
object appropriately initialized for a "Pass-through". The last three records are published as a sequence of "Triggered" records. Note that, in the sequenced output, the publish
method is called with a zero-based index
attribute; in this example, the publish
implementation will print a natural-number message count equal to index + 1:
void recordPublisher()
{
my_OstreamObserver myObserver(bsl::cout);
0,
1));
const int NUM_MESSAGES = 3;
for (int n = 0; n < NUM_MESSAGES; ++n) {
n,
NUM_MESSAGES));
}
}
Definition ball_recordattributes.h:274
void setProcessID(int processID)
Definition ball_recordattributes.h:562
void setTimestamp(const bdlt::Datetime ×tamp)
Definition ball_recordattributes.h:580
void setThreadID(bsls::Types::Uint64 threadID)
Definition ball_recordattributes.h:574
Definition ball_userfields.h:136
Definition bdlt_datetime.h:331
static Datetime convertFromTimeT(bsl::time_t time)
Definition bdlt_epochutil.h:383
recordPublisher
, when invoked, prints the following to stdout
:
Single Pass-through Message:
Timestamp: 15JAN2004_23:12:59.000
Process ID: 100
Thread ID: 0
Triggered Publication Sequence: Message 1 of 3:
Timestamp: 15JAN2004_23:12:59.000
Process ID: 201
Thread ID: 31
Triggered Publication Sequence: Message 2 of 3:
Timestamp: 15JAN2004_23:12:59.000
Process ID: 202
Thread ID: 32
Triggered Publication Sequence: Message 3 of 3:
Timestamp: 15JAN2004_23:12:59.000
Process ID: 203
Thread ID: 33