You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-user@logging.apache.org by Rhys Ulerich <rh...@gmail.com> on 2009/12/18 23:08:10 UTC
Using log4cxx::logstream in generic programming
Hi all,
I'd like to be able to use log4cxx::logstream instances within generic
programming. My goal is pass log4cxx::logstream instances into
templated code expecting basic_ostream instances and have everything
work out.
I've run into two problems.
First, there's no generic way to use std::endl for both
log4cxx::logstream and std::basic_ostream. Here's a test case against
log4cxx 0.10.0 that illustrates the difficulty:
#include <iostream>
#include <log4cxx/logger.h>
#include <log4cxx/stream.h>
template< typename OStream >
void test_it(OStream & os)
{
// std::endl<Elem,Tr> can be deduced for std::cout argument
// std::endl<Elem,Tr> cannot be deduced for log4cxx::logstream argument
os << "Foo" << std::endl;
// std::endl<char,std::traits<char> > works for std::cout and
// log4cxx::logstream
os << "Bar" << std::endl<char, std::char_traits<char> >;
// std::endl<typename OStream::char_type, std::char_traits<typename
// OStream::char_type> works for std::cout but does not work for
// log4cxx::logstream due to no char_type typedef
os << "Baz" << std::endl<typename OStream::char_type,
std::char_traits<typename OStream::char_type> >;
}
int main(int argc, char* argv[]) {
test_it(std::cout);
log4cxx::LoggerPtr logger = log4cxx::Logger::getRootLogger();
log4cxx::logstream logstream(logger, log4cxx::Level::getInfo());
test_it(logstream);
return 0;
}
I expect that at least the "Baz" line works for both std::cout and
log4cxx::logbase, and ideally the "Foo' line would too. At least for
the "Baz" case it occurs because log4cxx::logstream lacks typedefs a
la basic_ostream
(http://www.dinkumware.com/manuals/default.aspx?manual=compleat&page=ostream.html#basic_ostream).
I'm not sure if the "Foo" case could be made to work. If the "Baz"
case worked it might just require adding a template declarations to
log4cxx/stream.h that attempts to use the char_type and traits_type
typedef to fix the appropriate std::endl template.
Second, even if the first part did work, it seems that without the
magic log4cxx_base::endmsg manipulator that the messages are never
written. This is much less than generic, and I'd like to have
std::endl take the role of log4stream_base::endmsg whenever it is
encountered. From looking at Stroustrup's C++ programming language
section 21.4.6 I don't see how to intercept the single std::endl
manipulator and cause it to insert a log4stream_base::endmsg. I could
be missing something.
Any help appreciated,
Rhys