You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by hieu nguyen <hv...@hotmail.com> on 2002/07/27 00:31:07 UTC

Eleminate multiple intialization

Hello, I need help to solve this problem. My application is using multiple 
3rd party packages that each initializes it own log4j configuration. At the 
end of the run, I have multiple log files. I want to have only one log file, 
one format but when I made changes to the appender output to a single file 
didn't solve the problem. It seems whoever initialized last, will dictate 
the format of the output. I also don't want to modify each package 
configuration file. Thx in advance.





_________________________________________________________________
Join the world’s largest e-mail service with MSN Hotmail. 
http://www.hotmail.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Eleminate multiple intialization

Posted by Ceki Gülcü <ce...@qos.ch>.

The following text, intended for library developers that use log4j, is
from the complete manual. Please make sure to send this to the owners
of the third-party libraries you are using:

Embedded Libraries using log4j

Configuring log4j is the responsibility of the end-user or generally
the application deployer. Whenever possible, a library should not try
to configure logging but leave it to the deployer. After all, logging
output is useful only if someone will take the time to look at
them. If the end-user wishes to log then she should control the
logging configuration. Nevertheless, it is helpful for the library
developer to provide documentation on logging, preferably with
complete and working examples. The names of the loggers that the
library uses are prime candidates to include in such documentation.

One rub with this policy, assuming the user does not configure log4j,
is the dreaded warning message log4j outputs on the console on the
first log call in your library.

log4j:WARN No appenders could be found for logger (some.logger.name).
log4j:WARN Please initialize the log4j system properly.

We have already encountered this message in Chapter 1. It is log4j's
way of letting you that it is not been configured. As legitimate as it
is, this message may unnecessarily alarm the end-user, inducing her to
believe that there is an anomaly in your library or in the enclosing
software being deployed.

Let Spookz Inc. be a company specialized in cryptographic
software. The flagship product of Spookz Inc. is an unbreakable
encryption algorithm packaged within their CryptoLib library.
CryptoLib uses log4j for its logging. All loggers in CryptoLib are
children of the "com.spookz.cryptolib" logger. In line with our policy
of letting the end-user configure log4j, the engineers at Spookz
decide to initially turn off all logging from within their library.

void turnOffCryptoLogging() {
   Logger.getInstance("com.spookz.cryptolib").setLevel(Level.OFF);
}

This method is invoked very early in the game before other code in
CryptoLib has a chance to issue log requests. As long as the end-user
does not configure log4j, all logging requests in cryptolib will be
suppressed, including the oppressive "Please initialize log4j" warning
message.

If on the contrary, the user decides to configure log4j, then there
are two possible outcomes depending in the order of log4j
configuration by the user and cryptolib turning off its logging.

If log4j configuration occurs after CryptoLib invokes
turnOffCryptoLogging(), then the configuration established by the
deployer will be determining. The user can easily turn on logging in
CryptoLib, either programmatically or in a configuration script.  This
can accomplished by including the following directive in a
configuration file (properties format)

log4j.com.spookz.cryptolib=INHERITED

The same in XML is written as:

<logger name="com.spookz.cryptolib">
    <level name="INHERITED"/>
</logger>

These directives set the level of the "com.spookz.cryptolib" logger to
null causing it and its children to inherit their level from higher up
in the logger hierarchy. The deployer obviously has the possibility to
configure the "com.spookz.cryptolib" logger in other ways as with any
other logger.

In a less favorable turn of events, log4j configuration occurs
before turnOffCryptoLogging method is called. In this case, CryptoLib
effectively overrides the deployer's intended logging
configuration. This outcome is likely to occasion some confusion and
construed as unfriendly behavior. Fortunately, we can avoid this
undesired interference with a small modification to the
turnOffCryptoLogging method.

static void turnOffCryptoLogging() {
   Logger root = Logger.getRootLogger();
   boolean rootIsConfigured = root.getAllAppenders().hasMoreElements();
   if(!rootIsConfigured) {
     Logger.getInstance("com.spookz.cryptolib").setLevel(Level.OFF);
   }
}

In this modified version of turnOffCryptoLogging, we essentially check
if log4j has been already configured by inspecting the root logger to
see whether it contains any appenders. If it does, we consider log4j
to be already configured and skip the step of turning off logging for
the "com.spookz.cryptolib" logger.

The inspection of the root logger is based on the documented
properties of the getAllAppenders method. The Logger.getAllAppenders
method returns all the appenders attached to a logger as an
Enumeration.  In case there are no attached appenders, it returns a
NullEnumeration which contains no elements and whose hasMoreElements
method always returns false whereas non-empty Enumerations are
guaranteed to return true the first time their hasMoreElements method
is called.

This technique ensures that the configuration of log4j and turning off
logging can be called in any order without interfering with each
other. However, it assumes that any configuration necessarily adds one
or more appenders to the root logger which theoretically is not
always the case. In the unlikely circumstance where log4j is
configured without adding at least one appender to the root logger,
the appenders-in-root test will not be effective. There is not much
that can be done to prevent this, except documenting your working
assumptions, namely that at least one appender is assumed to be added
to the root logger. In the worst case, the CryptoLib will not produce
any logging output even if the deployer's configuration has enabled
CryptoLib logging. As a workaround, she can add a NullAppender to the
root logger. NullAppenders, as the name indicates, merely exist but
do not output anything to any device.

The examples for this chapter contain the java files
examples/chapter3/CryptoLib.java and
examples/chapter3/CryptoUser.java. These examples show how a library
can coordinate its logging settings with those configured by the
end-user. The XML configurations user1.xml and user2.xml are also
included.

At 22:31 26.07.2002 +0000, hieu nguyen wrote:
>Hello, I need help to solve this problem. My application is using multiple 
>3rd party packages that each initializes it own log4j configuration. At 
>the end of the run, I have multiple log files. I want to have only one log 
>file, one format but when I made changes to the appender output to a 
>single file didn't solve the problem. It seems whoever initialized last, 
>will dictate the format of the output. I also don't want to modify each 
>package configuration file. Thx in advance.

--
Ceki


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>