What is the use of the debug
method
expecting a String
array as one of its parameters?
How do I get the fully-qualified name of a class in a static block?
Can the outputs of multiple client request go to different log files?
Logger instances seem to be create only. Why isn't there a method to remove logger instances?
Is it possible to direct log output to different appenders by level?
Why can't log4j find my properties file in a J2EE or WAR application?
Is there a way to get log4j to automatically reload a configuration file if it changes?
Why should I donate my log4j extensions back to the project?
In case of problems with an application, it is helpful to enable
logging so that the problem can be located. With log4j it is possible
to enable logging at runtime without modifying the application binary.
The log4j package is designed so that log statements can remain in
shipped code without incurring a high performance cost. It
follows that the speed of logging (or rather not logging) is capital.
At the same time, log output can be so voluminous that it quickly
becomes overwhelming. One of the distinctive features of log4j is the
notion of hierarchical loggers. Using loggers it is
possible to selectively control which log statements are output at
arbitrary granularity.
log4j is designed with two distinct goals in mind: speed and
flexibility. There is a tight balance between these two
requirements. I believe that log4j strikes the right balance.
By fail-stop, we mean that log4j will not throw unexpected
exceptions at run-time potentially causing your application to
crash. If for any reason, log4j throws an uncaught exception,
please send an email to the log4j-user@jakarta.apache.org
mailing list. Uncaught exceptions are handled as serious bugs
requiring immediate attention.
Moreover, log4j will not revert to System.out or System.err
when its designated output stream is not opened, is not writable or
becomes full. This avoids corrupting an otherwise working program by
flooding the user's terminal because logging fails. However, log4j
will output a single message to System.err indicating that logging can
not be performed.
The DOMConfigurator.configure(String filename) method and its
variants require a JAXP compatible XML parser, for example Xerces or Sun's
parser. Compiling the DOMConfigurator requires the presence of a
JAXP parser in the classpath.
See the Here is an example output using PatternLayout with
the conversion pattern "%r [%t] %-5p %c{2} %x - %m%n"
The first field is the number of milliseconds elapsed since the
start of the program. The second field is the thread outputting the
log statement. The third field is the level of the log
statement. The fourth field is the rightmost two components of the
logger making the log request. The fifth field (just before the '-')
is the nested diagnostic context (NDC). Note the nested diagnostic
context may be empty as in the first two statements. The text after
the '-' is the message of the statement.
Loggers are assigned levels. A log statement is printed
depending on its level and its logger.
Make sure to read the log4j manual
for more information.
Log behavior can be set using configuration files which are parsed
at runtime. Using configuration files the programmer can define
loggers and set their levels.
The Configuration files can be specified in XML. See
See the various Layout and Appender components for specific
configuration options.
In addition to configuration files, the user may disable all
messages belonging to a set of levels. See next item.
For some logger incurs the cost of constructing the message parameter, that is
converting both integer If you are worried about speed, then write
This way you will not incur the cost of parameter construction if
debugging is disabled for logger Yes, there are.
You can name loggers by locality. It turns out
that instantiating a logger in each class, with the logger name
equal to the fully-qualified name of the class, is a useful and
straightforward approach of defining loggers. This approach has
many benefits:
However, this is not the only way for naming loggers. A common
alternative is to name loggers by functional
areas. For example, the "database" logger, "RMI" logger,
"security" logger, or the "XML" logger.
You may choose to name loggers by functionality and
subcategorize by locality, as in "DATABASE.com.foo.some.package.someClass" or
"DATABASE.com.foo.some.other.package.someOtherClass".
You are totally free in choosing the names of your
loggers. The log4j package merely allows you to manage your
names in a hierarchy. However, it is your responsibility to define
this hierarchy.
Note by naming loggers by locality one tends to name things by
functionality, since in most cases the locality relates closely to
functionality.
You can easily retrieve the fully-qualified name of a class in a
static block for class X, with the statement
Here is the suggested usage template:
Yes. Since release 0.7.0, you can extend the It is simpler to use a nested diagnostic context (NDC). Typically,
one would NDC.push() client specific information, such as the
client's hostname, ID or any other distinguishing information when
starting to handle the client's request. Thereafter, log output will
automatically include the nested diagnostic context so that you can
distinguish logs from different client requests even if they are
output to the same file.
See the For select applications, such as virtual hosting web-servers, the
NDC solution is not sufficient. As of version 0.9.0, log4j supports
multiple hierarchy trees. Thus, it is possible to log to different
targets from the same logger depending on the current context.
Thus, any setter method in Layouts options are also defined by their setter methods. Same goes
for most other log4j components.
Yes it is. Setting the Threshold option of any appender
extending AppenderSkeleton,
(most log4j appenders extend AppenderSkeleton) to filter out all log
events with lower level than the value of the threshold
option.
For example, setting the threshold of an appender to DEBUG also
allow INFO, WARN, ERROR and FATAL messages to log along with DEBUG
messages. This is usually acceptable as there is little use for DEBUG
messages without the surrounding INFO, WARN, ERROR and FATAL
messages. Similarly, setting the threshold of an appender to ERROR
will filter out DEBUG, INFO and WARN messages but not ERROR or FATAL
messages.
This policy usually best encapsulates what the user actually wants
to do, as opposed to her mind-projected solution.
See examples/sort4.lcf for an example threshold
configuration.
If you must filter events by exact level match, then you can
attach a LevelMatchFilter
to any appender to filter out logging events by exact level match.
You may have each process log to a
The timestamp is created when the logging event is created. That is
so say, when the While this is the intended behavior, it only recently became so due to
a bug discovery between version 1.0.4 and 1.1b1. Versions 1.0.4 and before
had their timestamp regenerated in the converter. In this case the timestamps
seen in the log file would all appear in order, generated at the time they
arrived at the log server host according to its local clock.
The long answer (and what to do about it): J2EE or Servlet containers
utilize Java's class loading system. Sun changed the way classloading
works with the release of Java 2. In Java 2, classloaders are
arranged in a hierarchial parent-child relationship. When a child
classloader needs to find a class or a resource, it first delegates
the request to the parent.
Log4j only uses the default So, if you're having problems, try loading the class or resource
yourself. If you can't find it, neither will log4j. ;)
Yes. Both the DOMConfigurator and the PropertyConfigurator support
automatic reloading through the The NT Event Viewer relies on message resource DLLs to
properly view an event message. The NTEventLogAppender.dll contains
these message resources, but that DLL must be copied to
%SYSTEMROOT%\SYSTEM32 for it to work properly.
Unfotunately, the logger names are hardcoded within the message
resource DLL (see previous question about NTEventLogAppender), so
there isn't any easy way to override those dynamically... in fact, I
don't think it's possible to do it, as you'd have to modify the DLL
resources for every application. Since most native applications don't
use the Logger column anyway...
We are very careful not to change the log4j client API so that
newer log4j releases are backward compatible with previous
versions. We are a lot less scrupulous with the internal log4j
API. Thus, if your extension is designed to work with log4j version
If your extensions are useful then someone will eventually write an
extension providing the same or very similar functionality. Your
development effort will be wasted. Unless the proprietary log4j
extension is business critical, there is little reason for not
donating your extensions back to the project.
There is nothing more irritating than finding the bugs in
debugging (i.e. logging) code. Writing a test case takes some
effort but is crucial for a widely used library such as
log4j. Writing a test case will go a long way in earning you the
respect of fellow developers. See the tests/ directory for exiting
test cases.
Alternating between indentation styles makes it hard to
understand the source code. Make it hard on yourself but easier
on others. Log4j follows the Code Conventions for
the JavaTM Programming Language.
One of the important advantages of log4j is its compatibility with
JDK 1.1.x.
It's all about the application not about logging.
Authoring software is very much like running a marathon. It
takes time and endurance.
The log4j project is hosted at http://jakarta.apache.org/log4j/.
What is log4j?
log4j is a tool to help the programmer output log statements to a
variety of output targets.
Is log4j a reliable logging system?
No. log4j is not reliable. It is a best-effort and fail-stop
logging system.
What are the prerequisites for log4j?
org.apache.log4j.net.SMTPAppender
relies
on the JavaMail
API. It has been tested with JavaMail API version 1.2. The
JavaMail API requires the JavaBeans
Activation Framework package.
org.apache.log4j.net.JMSAppender
requires
the presence of the JMS API as well as JNDI.
Is there example code for using log4j?
examples/
directory.
What are the features of log4j?
java.io.OutputStream
, java.io.Writer
,
a remote server using TCP, a remote Unix Syslog daemon, to a
remote listener using JMS, to the NT EventLog or even send e-mail.
Is log4j thread-safe?
Yes, log4j is thread-safe.
What does log output look like?
The log output can be customized in many ways. Moreover, one can completely
override the output format by implementing one's own Layout.
176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
225 [main] INFO examples.SortAlgo - Entered the sort method.
262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop.
276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0
290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.
304 [main] INFO SortAlgo.DUMP - Dump of interger array:
317 [main] INFO SortAlgo.DUMP - Element [0] = 0
331 [main] INFO SortAlgo.DUMP - Element [1] = 1
343 [main] INFO examples.Sort - The next log statement should be an error message.
346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.
at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
at org.log4j.examples.Sort.main(Sort.java:64)
467 [main] INFO examples.Sort - Exiting main method.
What are Loggers?
Lggers lie at the heart of log4j. Loggers define a hierarchy and give
the programmer run-time control on which statements are
printed or not.
How can I change log behavior at runtime?
PropertyConfigurator
defines a particular format
of a configuration file. See also the examples/Sort.java
example and associated configuration files.
log4j.dtd
and
org.log4j.xml.DOMConfigurator
for more details.
What is the fastest way of (not) logging?
l
, writing,
l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
i
and entry[i]
to a
String, and concatenating intermediate strings. This, regardless of
whether the message will be logged or not.
if(l.isDebugEnabled()) {
l.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
l
. On the other
hand, if the logger is debug enabled, you will incur the cost of
evaluating whether the logger is enabled or not, twice: once in
debugEnabled
and once in debug
. This is an
insignificant overhead since evaluating a logger takes less than 1%
of the time it takes to actually log a statement.
Are there any suggested ways for naming
loggers?
How do I get the fully-qualified name of a class
in a static block?
X.class.getName()
. Note that X
is the class
name and not an instance. The X.class
statement does
not create a new instance of class X
.
package a.b.c;
public class Foo {
static Logger logger = Logger.getLogger(Foo.class);
... other code
}
Can the log output format be customized?
Layout
class to create you own customized log format. Appenders can be
parameterized to use the layout of your choice.
Can the outputs of multiple client request go to
different log files?
Many developers are confronted with the problem of distinguishing the
log output originating from the same class but different client
requests. They come up with ingenious mechanisms to fan out the log
output to different files. In most cases, this is not the right
approach.
NDC
and the PatternLayout
classes
for more information. The NumberCruncher
example shows
how the NDC can be used to distinguish the log output from multiple
clients even if they share the same log file.
What are the configurable options for
FooBarAppender?
Log4j uses JavaBeans style configuration.
FooBarAppender
corresponds
to a configurable option. For example, in RollingFileAppender
the setMaxBackupIndex(int
maxBackups) method corresponds to the maxBackupIndex
option. The first letter of the option can be upper case, i.e.
MaxBackupIndex
and maxBackupIndex
are
equivalent but not MAXBACKUPIndex
nor
mAXBackupIndex
.
Logger instances seem to be create only. Why isn't
there a method to remove logger instances?
It is quite nontrivial to define the semantics of a "removed" logger
which is still referenced by the user. Future releases may
include a remove method in the Logger class.
Is it possible to direct log output to
different appenders by level?
How do I get multiple process to log to the same file?
SocketAppender
.
The receiving
SocketServer
(or
SimpleSocketServer
)
can receive all the events and send them to a single
log file.
If I have many processes across multiple hosts
(possibly across multiple timezones) logging to the same file using the
method above, what happens to timestamps?
debug
, info
, warn
,
error
or fatal
method is invoked.
This is unaffected by the time at which they may arrive at a remote
socket server. Since the timestamps are stored in UTC format inside
the event, they all appear in the same timezone as the host creating the
logfile. Since the clocks of various machines may not be synchronized,
this may account for time interval inconsistencies between events generated
on different hosts.
Why can't log4j find my properties file in a J2EE
or WAR application?
The short answer: the log4j classes and the properties file are not
within the scope of the same classloader.Class.forName()
mechanism
for loading classes. Resources are handled similarly. See the
documentation for java.lang.ClassLoader
for more details.
Is there a way to get log4j to
automatically reload a configuration file if it changes?
configureAndWatch
APIs.
See the API documentation for more details.
What does the Windows NT Event
Viewer complain about missing descriptions for my event messages when
I use the NTEventLogAppender?
Why can't I map my logger names
to the loggers that appear in the NT Event Log when I use the
NTEventLogAppender?
Why should I donate my extensions to log4j back to the
project?
Contrary to the GNU Public License (GPL) the Apache Software License
does not make any claims over your extensions. By extensions, we mean
totally new code that invokes existing log4j classes. You are free
to do whatever you wish with your proprietary log4j extensions.
In particular, you may choose to never release your extensions to the
wider public.
n
, then when log4j release version n+1
comes
out, you will probably need to adapt your proprietary extensions to
the new release.
Thus, you will be forced to spend precious resources in order to keep
up with log4j changes. This is commonly referred to as the
"stupid-tax." By donating the code and making it part of the standard
distribution, you save yourself the unnecessary maintenance work.
What should I keep in mind when contributing
code?
Where can I find the latest distribution of log4j?