July 7, 2025
Introducing BALL_FMT: BALL Logger Support for std::format-style Text Formatting
BDE 4.26.0 introduced the ball_fmt component that provides logging macros that accept a
format specifications and substitution parameters mirroring those introduced in
standard C++20 facility bsl::format (see the article Introducing bsl::format):
BALL_LOG_SET_CATEGORY("EXAMPLE.CATEGORY");
BALL_FMT_TRACE("Examining record number {}...", recNumber);
BALL_FMT_ERROR("Endpoint '{}' is not in the allowed list", endPoint);
Logging is a place where the benefits of the new standard formatting facilities really shine, allowing developers to more easily craft log messages that output in a desired format, while being more readable in source code.
Of course, it is also possible to log within a block into the same record as we can with the streaming log macros:
bsl::vector<int> myVector(4, 328);
BALL_LOG_TRACE_BLOCK {
BALL_FMT("myVector = [ ");
unsigned int position = 0;
for (bsl::vector<int>::const_iterator it = myVector.begin(),
end = myVector.end();
it != end;
++it, ++position) {
BALL_FMT("{}:{} ", position, *it);
}
BALL_FMT("]");
}
Many existing types do not (and may never) provide bsl::formatter
specializations, and rely on the ostream insert operator<< to generate
a text description. To overcome this gap, clients can use the new
bslfmt::streamed wrapper (also released in BDE 4.26):
BALL_LOG_SET_CATEGORY("EXAMPLE.CATEGORY");
BALL_FMT_FATAL("Item {:>010} does not exist.", bslfmt::streamed(id));
For more details read the bslfmt::streamed Introduction and bslfmt::streamed.