Tommi Maekitalo wrote:
I personally feel, that the whole logstream-concept is broken by design. I use streams heavily, but don't use logstream. I have a macro, which encapsulates this whole formatting-stuff. I instantiate a ostringstream, when loging is enabled. Here is my macro-definition:

#define CXXTOOLS_LOG(level, expr) \
  do { \
    if (getLogger()->isEnabledFor(::log4cxx::Level::level)) \
    { \
      std::ostringstream msg; \
      msg << expr; \
      getLogger()->log( \
        ::log4cxx::Level::level, \
        msg.str(), \
        LOG4CXX_LOCATION); \
    } \
  } while (false)

#define log_fatal(expr)  CXXTOOLS_LOG(FATAL, expr)
#define log_error(expr)  CXXTOOLS_LOG(ERROR, expr)
#define log_warn(expr)  CXXTOOLS_LOG(WARN, expr)
#define log_info(expr)  CXXTOOLS_LOG(INFO, expr)
#define log_debug(expr)  CXXTOOLS_LOG(DEBUG, expr)


In my program I use:

log_debug("the value is " << value << " hex=" << std::hex << value);

I have the guarantee to get a fresh stream every time and when logging is disabled there is no stream-overhead at all.

What you are doing is the original behavior I was intending to encapsulate with logging streams. If you look at my implementation it has nearly the same effect, except that the stream is allocated on the heap, and that it is not necessarily destroyed after the logging even is sent (although the original implementation did have this as well). I set this up based on what I feel was excellent feedback from Curt, as the cost of constructing the ostream for each logging event is a bit on the high side, and you'll want to mitigate it as much as possible.


For log4cxx the best way to go is to offer a real ostream for users, who wants to use it. Everything else has its limitations. The standard-library is responsable for the overhead and not log4cxx.

Both Curt and I use the standard library for our streams (although I wrote mine such that one could use one's own streams instead, something that could also be done with Curt's if we wanted to).


--Chris

Reply via email to