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

Reply via email to