BDE 4.39.x Production Release
Loading...
Searching...
No Matches
ball_recordformatterregistryutil

Detailed Description

Provide utilities for creating log record formatters by scheme.

Outline

Purpose

Provide utilities for creating log record formatters by scheme.

Classes

See also
ball_recordstringformatter, ball_recordjsonformatter

Description

This component provides a utility struct, ball::RecordFormatterRegistryUtil, that defines a namespace for functions to create log record formatters based on URI-like scheme identifiers. The primary function, createRecordFormatter, interprets a format string beginning with a scheme (e.g., "text://", "json://", "qjson://") and delegates to the appropriate specialized formatter factory. This allows for flexible configuration of log output formats using a single, scheme-based interface.

The component supports the following schemes:

The scheme determines which formatter will be used and the syntax of the format specification. The following schemes are currently supported: text, json, qjson. See Scheme-Based Formatters for more details of the supported schemes and their accompanying format specification syntaxes.

Behavior with Invalid Formats

Trying to create a formatter with an invalid format string or an unknown scheme will result in a non-zero error code being returned. If the result formatter is not empty the method assumes that it is loaded with a reasonable (default or otherwise) format and will not change it. In case result is an empty bsl::function createRecordFormatter will return a non-zero error code and loads a default/fallback formatter into the result parameter. Said fallback formatter will be a sensible default for the given scheme if the scheme is recognized, or a default/fallback text formatter if the scheme is not one of the supported ones.

An example with an unknown scheme:

bsl::string unknownScheme = "xml://some-format";
ball::RecordFormatterFunctor::Type fallbackFormatter; // empty formatter
&fallbackFormatter,
unknownScheme,
options);
assert(0 != rc); // Returns error code for unknown scheme
Definition bslstl_string.h:1252
Forward declaration.
Definition bslstl_function.h:946
static int createRecordFormatter(RecordFormatterFunctor::Type *result, const bsl::string_view &format, const RecordFormatterOptions &formatOptions)

fallbackFormatter is still usable as it was loaded with a sensible default text formatter, allowing the application to continue logging even when the configuration is incorrect.

bsl::ostringstream fallbackOss;
fallbackFormatter(fallbackOss, record);
assert(!fallbackOss.str().empty()); // Fallback formatter still works:
basic_ostringstream< char, char_traits< char >, allocator< char > > ostringstream
Definition bslstl_iosfwd.h:97

The output of the above code will look something like:

27AUG2007_16:09:46.161 2040:1 WARN adir/src.cpp:97 CATEGORY Log message\n

Currently the text formatter just ignores errors in its format string so only the "json://" and "qjson://" schemes perform some form of validation. That means that a meaningless "text://" format will succeed and may not produce any useful log output, while some invalid "json://" or "qjson://" formats will fall back to a reasonable default with a non-zero return code.

bsl::string unknownScheme = "test://%73\n";
ball::RecordFormatterFunctor::Type fallbackFormatter; // empty formatter
&fallbackFormatter,
unknownScheme,
options);
assert(0 == rc); // The text scheme never reports an error
fallbackFormatter(oss, record);
assert("%73\n" == oss.str()); // Gibberish output due to set format

Usage

This section illustrates intended use of this component.

Example 1: Creating Formatters from Various Scheme URIs

Suppose we have configuration entries that define log record formatters using URI-like schemes, and we need to create the corresponding formatters. This component supports "text://", "json://", and "qjson://" schemes.

First, we create formatter options and a test record:

ball::Record record = createTestRecord();
Definition ball_recordformatteroptions.h:112
Definition ball_record.h:176
@ e_UTC
Definition ball_recordformattertimezone.h:115

Now, we demonstrate creating formatters with different schemes. For text output, we use the "text://" scheme with printf-style format specifiers:

bsl::string textFormat = "text://%d %p:%t %s %f:%l %c %m\n";
&textFormatter,
textFormat,
options);
assert(0 == rc);

For structured JSON output, we use the "json://" scheme with a JSON array specifying which fields to include:

bsl::string jsonFormat = "json://[\"tid\",\"severity\",\"message\"]";
&jsonFormatter,
jsonFormat,
options);
assert(0 == rc);

For simplified JSON using printf-style specifiers, we use the "qjson://" scheme:

bsl::string qjsonFormat = "qjson://%i %s %c %m";
&qjsonFormatter,
qjsonFormat,
options);
assert(0 == rc);

Each formatter can then be used to format log records:

bsl::ostringstream textOss, jsonOss, qjsonOss;
textFormatter(textOss, record);
jsonFormatter(jsonOss, record);
qjsonFormatter(qjsonOss, record);
assert(textOss.str().find("Test message") != bsl::string::npos);
assert(jsonOss.str().find("\"message\"") != bsl::string::npos);
assert(qjsonOss.str().find("Test message") != bsl::string::npos);
static const size_type npos
Definition bslstl_string.h:1793