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 2011/09/09 20:34:14 UTC

Comments on HierarchyEventListener implementation details and other junk

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

Re: Comments on HierarchyEventListener implementation details and other junk

Posted by Curt Arnold <ca...@apache.org>.
On Sep 9, 2011, at 1:34 PM, Rhys Ulerich wrote:

> 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);
> };
> 


Will have to look into that and dredge into the history. You would think that it would not be necessary to have any log4cxx namespaces in scope, but might have been forced to by the compilers at the time. All very murky at the moment.

> 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.

If you'd like to put together a skeleton Wiki page with the questions that you'd like addressed and put TODO's or something where you don't know, I and possibly others would be willing to try to remember or research to find answers. But I don't see me ever looking at a blank sheet of paper and deciding that is what I want to spend my time on.

> 
> 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.

Any mismatch between signed chars and unsigned chars generally indicates that a character transcoder is missing (or there is one that you didn't expect) and would really not match if logchar was switched from char to wchar_t, things would be even more mismatched. Java property files are defined as ISO 8559-1 regardless of platform encoding, hence they work in bytes since they don't want someone else handling the translation from bytes to characters upstream.



> 
> 3) It appears there's no way to use DOMConfigurator without having a
> configuration file sitting on disk.
> 

APR did not expose any obvious mechanism for parsing byte streams hence log4cxx couldn't offer it. Looking at APR, doesn't look like that has changed.

> 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.

The doc is likely copied verbatim from log4j.

> 
> 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.

If you have ideas, file a bug report with or without a patch.

> 
> 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.

LogManager::getLoggerRepository()->setConfigured(true) should also suppress the message.

> 
> 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.

Thanks for the heads up.


> 
> 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