On Oct 4, 2004, at 6:44 PM, Christopher Smith wrote:

Once again, as a former log4cpp user, I've identified something that log4cxx appears to be missing but which I'd like to have: LoggingStreams (or CategoryStreams as they are called in log4cpp).

These are streams that are tied to a particular Logger and priority level. This allows you to do something like:

LoggingStream foo(logger, WARN);
foo << "We got: " << anInt << " for a total of: " << anotherInt;
foo << " and an average of: " << aFloat << endl;

The advantage being that you don't need to an explicit "if (logger.isEnabled(WARN)) { ... }" wrapper around the formatting code. If the priority is disabled, then the LoggingStream just turns all operator<<()'s into noops, while otherwise it writes to a buffer, which it then flushes and sends on an endl or equivalent io manipulator. You get the efficiency of using the if() to check things, but the logging code doesn't have to take up as much screen realestate now.

I've written up my own implementation of this for log4cxx. It's not perfect, but it's getting there. I wanted to know what everyone else though about this idea.


Per the previous discussion on iostream-free log4cxx, this alternative API should be completely optional. Ideally included in its own header (log4cxx/loggingstream.h?) and delegating to the primary API.


A couple of issues:

1. It would be good that logging streams weren't limited to one character type, so having a template like:

template<class Elem, class Tr = char_traits<Elem>> class log4cxx::basic_logging_stream : std::basic_ostream<Elem, Tr> {
}


would be good, though there might be a log4cxx::stream and log4cxx::wstream expansions of that template.

2. The LOG4CXX_.* macros provide context values (__FILE__ and __LINE__ currently, may be expanded to include __func__). How would you see adding that information into the logging stream?

3. What would trigger the creation of a logging event? My initial take is that it should be a call to flush() or close().

4. Would a logging stream be able to create multiple logging events?

5. When would the level be checked to determine if the stream is enabled. My take would be on stream creation and after calls to flush. If it were checked on each insertion operation, messages could look pretty funky if the configuration was modified while a message was being assembled.

6. Would the level of a logging stream be able to be modified? It might be convenient, however you would not be able to change the level mid-way through construction of a message since earlier parts might have been no-op'd. My take is that inserting a LevelPtr would imply a flush.



Reply via email to