BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_recordattributes

Detailed Description

Outline

Purpose

Provide a container for a fixed set of fields suitable for logging.

Classes

See also
ball_record

Description

This component defines a container for aggregating a fixed set of fields intrinsically appropriate for logging. Using ball::RecordAttributes, a logger can transmit log message text together with relevant auxiliary information (e.g., timestamp, filename, line number, etc.) as a single instance, rather than passing around individual attributes separately.

The attributes held by ball::RecordAttributes are given in the following table:

Attribute Type Description Default
---------- ------------- ------------------------------ --------
timestamp bdlt::Datetime creation date and time (*Note*)
processID int process id of creator 0
threadID Uint64 thread id of creator 0
fileName string file where created (__FILE__) ""
lineNumber int line number in file (__LINE__) 0
category string category of logged record ""
severity int severity of logged record 0
message string log message text ""
Definition bdlt_datetime.h:331

Note: The default value given to the timestamp attribute is implementation defined. (See the bdlt_datetime component-level documentation for more information.)

Cached Stream State: Although a RecordAttributes object is nominally a value-semantic attribute type whose attributes are described in the table above, for performance and convenience a RecordAttributes object provides access to internal instances of bdlsb::MemOutStreamBuf and bsl::ostream objects (via messageStreamBuf and messageStream accessors, respectively) that allow users to build the message directly without having to construct any I/O stream objects independently. This is useful because ball::Record objects and their RecordAttributes are cached for performance. Note that it's possible for two equal instances of RecordAttributes objects to have different stream states. Resetting the message will clear most stream state, except for the locale, installed callbacks, and any pword/iword data.

For each attribute, there is a method to access its value and a method to change its value. E.g., for the timestamp attribute, there is the timestamp accessor and the setTimestamp manipulator. Note that for the message attribute, there is a message accessor which is deprecated; use the messageRef accessor instead. The class also provides the ability to stream an object (whose class must support the operator<<) into the message attribute using messageStreamBuf method (see the usage example-2).

Alternately, an object can be streamed directly into the message attribute via the stream exposed by the messageStream method: in that case, the messageStreamBuf should not also be used simultaneously. More precisely, use of the references returned by the messageStreamBuf and messageStream methods to build a message results in undefined behavior if interleaved with each other, or if interspersed with calls to setMessage, clearMessage, operator=, or message (but not messageRef). In other words, streaming an object into the message attribute must be done in one uninterrupted sequence of operations.

The default values listed in the table above are the values given to the respective attributes by the default constructor of ball::RecordAttributes.

Usage

This section illustrates intended use of this component.

Example 1: Syntax

The ball::RecordAttributes class holds sufficient information on which to base a rudimentary logging, tracing, or reporting facility. The following code fragments illustrate the essentials of working with these attributes.

Assume that our example is part of a financial application using categories and message severities as follows:

const char *Category[] = { "Bonds", "Equities", "Futures" };
enum { INFO, WARN, BUY, SELL };

First define a ball::RecordAttributes object with each attribute initialized to its default value:

Definition ball_recordattributes.h:274

Next set each of the attributes to some meaningful value:

attributes.setTimestamp(now); // current time
attributes.setProcessID(getpid());
attributes.setThreadID((bsls::Types::Uint64) pthread_self());
attributes.setFileName(__FILE__);
attributes.setLineNumber(__LINE__);
attributes.setCategory(Category[2]); // "Futures"
attributes.setSeverity(WARN);
attributes.setMessage("sugar up (locust infestations on the rise)");
void setCategory(const char *category)
Definition ball_recordattributes.h:544
void setProcessID(int processID)
Definition ball_recordattributes.h:562
void setTimestamp(const bdlt::Datetime &timestamp)
Definition ball_recordattributes.h:580
void setThreadID(bsls::Types::Uint64 threadID)
Definition ball_recordattributes.h:574
void setLineNumber(int lineNumber)
Definition ball_recordattributes.h:556
void setSeverity(int severity)
Definition ball_recordattributes.h:568
void setFileName(const char *fileName)
Definition ball_recordattributes.h:550
void setMessage(const char *message)
static Datetime convertFromTimeT(bsl::time_t time)
Definition bdlt_epochutil.h:383
unsigned long long Uint64
Definition bsls_types.h:137

The message in this example briefly informs that something interesting may be happening with respect to sugar futures. In general, the message attribute can contain an arbitrary amount of information.

Now that the sample ball::RecordAttributes object has been populated with the desired information, it can be passed to a function, stored in a database, cached in a container of ball::RecordAttributes objects, etc. For the purposes of this illustration, we'll simply format and stream selected attributes to a specified ostream using the following function:

void printMessage(ostream& stream,
const ball::RecordAttributes& attributes)
{
using namespace std;
stream << "\tTimestamp: " << attributes.timestamp() << endl;
stream << "\tCategory: " << attributes.category() << endl;
stream << "\tMessage: " << attributes.messageRef() << endl;
stream << endl;
}
bslstl::StringRef messageRef() const
const bdlt::Datetime & timestamp() const
Return the timestamp attribute of this record attributes object.
Definition ball_recordattributes.h:635
const char * category() const
Return the category attribute of this record attributes object.
Definition ball_recordattributes.h:587
Definition bdldfp_decimal.h:5188

The following call:

printMessage(bsl::cout, attributes);

prints these attributes to stdout:

Timestamp: 19JAN2004_23:07:38.000
Category: Futures
Message: sugar up (locust infestations on the rise)

Example 2: Streaming Data Into a Message Attribute

Following example demonstrates how an object of a class supporting ostream operation (operator<<) can be streamed into the message attribute. Suppose we want to stream objects of the following class.

class Information
{
private:
bsl::string d_heading;
bsl::string d_contents;
public:
Information(const char *heading, const char *contents);
const bsl::string& heading() const;
const bsl::string& contents() const;
};
Definition bslstl_string.h:1281

The component containing the Information must provide operator<<. Here is a possible implementation.

bsl::ostream& operator<<(bsl::ostream& stream,
const Information& information)
{
stream << information.heading() << endl;
stream << '\t';
stream << information.contents() << endl;
return stream;
}
bsl::ostream & operator<<(bsl::ostream &stream, const bdlat_AttributeInfo &attributeInfo)

The following function streams an Information object into the message attribute of a ball::RecordAttributes object.

void streamInformationIntoMessageAttribute(
const Information& information)
{
// First clear the message attributes.
attributes.clearMessage();
// Create an 'ostream' from message stream buffer.
bsl::ostream os(&attributes.messageStreamBuf());
// Now stream the information object into the created ostream.
// This will set the message attribute of 'attributes' to the
// streamed contents.
os << information;
}
void clearMessage()
Definition ball_recordattributes.h:514
bdlsb::MemOutStreamBuf & messageStreamBuf()
Definition ball_recordattributes.h:532