For an MPI-based application where I needed to broadcast a configuration from one MPI rank to all others, I have noticed the following gotchas about log4cxx's trunk innards. Not questions so much as requests for comments or to help some other soul searching this mailing list in the future...
0) Thank you for log4cxx. It is a great tool. 1) If one wants to write a custom HierarchyEventListener, at declaration time both 'using namespace log4cxx' and 'using namespace log4cxx::helpers' statements need to be in effect (I think) due to the Object hierarchy macros. For example, anyone #including a custom class like the following must (I think) necessarily pollute their names with log4cxx implementation details: class SubversiveASHEL : public virtual spi::HierarchyEventListener, public virtual ObjectImpl { public: DECLARE_LOG4CXX_OBJECT(SubversiveASHEL) BEGIN_LOG4CXX_CAST_MAP() LOG4CXX_CAST_ENTRY(SubversiveASHEL) LOG4CXX_CAST_ENTRY(HierarchyEventListener) END_LOG4CXX_CAST_MAP() virtual void removeAppenderEvent( const LoggerPtr&, const AppenderPtr&); virtual void addAppenderEvent( const LoggerPtr &logger, const AppenderPtr &appender); }; Documentation about how to write one's own class that descends from Object would be most helpful. Another possibility would be having an abstract HierarchyEventListener base class from which one could inherit. 2) A FileInputStream/ByteBuffer combination works in (unadorned) chars but a ByteArrayInputStream requires unsigned chars. This makes reading a configuration file into memory using File (as 'char' data) and then configuring via Properties::load (as 'unsigned char' data via ByteArrayInputStream) tricky. 3) It appears there's no way to use DOMConfigurator without having a configuration file sitting on disk. 4) The statement in LogManager's doxygen that "When the LogManager class is loaded into memory the default initialization procedure is initiated" should be clarified in some way. Maybe only when an instance is created? Merely using LogManager::getLoggerRepository() does not cause such an auto-configuration. 5) It would be helpful if the configuration file magic in defaultconfigurator.cpp was exposed so that one can retrieve the configpath to use for configuration. Currently the configuration-finding and configuration-loading logic seemed joined at the hip and one must extract it from that source. 6) LogLog::setQuietMode(true) followed by emitting a message followed by LogLog::setQuietMode(false) can be used to eliminate the "log4cxx: Please initialize the log4cxx system properly" message from appearing but only if the message is of a high enough level to hit an appender. 7) Finally, https://issues.apache.org/jira/browse/LOGCXX-385 contains a patch which could be directly applied to trunk by someone with committer access. Lastly, I plan to (at some point) write up a (possibly) sane implementation of getting log4cxx initialized in a scalable way for an MPI-based application. Without some monkeying, the auto-configuration process causes every rank to hit the filesystem multiple times as each rank gropes about for a configuration file. If you're interested in the details, feel free to email me off list. - Rhys