You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-cvs@jakarta.apache.org by ce...@apache.org on 2001/06/13 00:24:17 UTC
cvs commit: jakarta-log4j/docs critique.html manual.html
ceki 01/06/12 15:24:17
Modified: docs manual.html
Added: docs critique.html
Log:
Added a dedication to my grandfather in manual.html.
critique.html is a critique of JSR47.
Revision Changes Path
1.21 +12 -6 jakarta-log4j/docs/manual.html
Index: manual.html
===================================================================
RCS file: /home/cvs/jakarta-log4j/docs/manual.html,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- manual.html 2001/06/07 21:10:01 1.20
+++ manual.html 2001/06/12 22:24:16 1.21
@@ -8,22 +8,28 @@
<center>
<h1>Short introduction to log4j</h1>
- "Ceki Gülcü"
-
- June 2001 <br><br>
+ <font size="+2">Ceki Gülcü</font>
+ <br><br>
+ June 2001
+ <br>
</center>
+<br>
+<hr>
+This manual as well as my contribution to the log4j project is
+dedicated to my grandfather, Leon Bahar, of blessed memory.
<hr>
-This manual is based on the article <a
+
+<p>This document is based on the article <a
href="http://www.javaworld.com/jw-11-2000/jw-1122-log4j.html">"Log4j
delivers control over logging"</a> published in November 2000 edition
of <a href="http://www.javaworld.com">JavaWorld</a>. However, the
present article contains more detailed and up to date information.
-<hr>
+
<h2>Abstract</h2>
-<p>This article describes the log4j API, its unique features and
+<p>This document describes the log4j API, its unique features and
design rationale. Log4j is an open source project based on the work of
many authors. It allows the developer to control which log statements
are output with arbitrary granularity. It is fully configurable at
1.1 jakarta-log4j/docs/critique.html
Index: critique.html
===================================================================
<HTML>
<document>
<HEAD>
</HEAD>
<body>
<CENTER>
<H1>JSR47 vs. log4j</H1>
<font size="+2">Ceki Gülcü</font>
</CENTER>
<hr>
<p>I consider it quite distasteful to criticize other people's work,
especially in public. However, since the logging API included in JDK
1.4 will be potentially considered as the "standard", I feel compelled
to react.
<p>The JDK 1.4 logging API is a result of the <a
href="http://jcp.org/aboutJava/communityprocess/review/jsr047/index.html">JSR47
process</a>, led by Graham Hamilton. We will refer to it as the JSR47
API for the remainder of this document.
<p>Before delving into the details, some historical perspective is in
order. I participated in the specification of the JSR47 API although
not as an expert. In 1999, I was still working for IBM and big blue
had already Chris Barlock as a member in the JSR47 experts
group. Chris is the author of <a
href="http://www.alphaworks.ibm.com/tech/loggingtoolkit4j">IBM's
logging toolkit for Java</a>.
<p>On the surface, his toolkit has heavily influenced the JSR47
API. In particular, the two share the same basic componets, namely
loggers, levels, handlers and formatters. In log4j, these components
are called categories, priorities, appenders and layouts
respectively. Pairwise, they are similar in purpose.
<p>Despite the difference in their names, pairwise, these components
share the same purpose. As such, the log4j and JSR47 APIs are
<em>extremely</em> similar. They are the only logging APIs which are
based on a named hiearchy. If you understand one API, then
understanding the other is quite trivial. There are differences
however.
<h2>Parents vs. Children</h2>
<p>In JSR47, a parent logger knows about its direct descendants but
not the other way around. Children do know know about their
parents. For example, the logger named <code>"com.foo"</code> knows
about <code>"com.foo.bar1"</code> and
<code>"com.foo.bar2"</code>. However, <code>"com.foo.bar1"</code> has
no links to its parent <code>"com.foo"</code>.
<p>In log4j, it is exactly the other way around. A log4j category
contains a link to its parent but a parent does not have links to its
children.
<p>At first glance, this might look like a trivial implementation
detail but it is actually quite fundamental.
<ol>
<p><b><li>Configutation order matters</b>
<p>In JSR47, when you set the level of a logger, say
<code>wombat</code>, JSR47 traverses the tree below
<code>wombat</code>. In other words, the levels for all the loggers
descending from <code>wombat</code> are overwritten. This can be a
very expensive operation for large trees. In particular, for the most
common case where one sets the level of the root logger.
<p>In log4j, changing the priority of a category involves the change
of a single field. Children categories dynamically inherit the
priority of their parent by traversing the hierarchy tree upwards.
<p>It follows that if you configure the level for logger
"com.foo.bar1" before configuring the level for "com.foo", then the
latter instruction will overwrite the first. It will be as if the
first instruction for configuring "com.foo.bar1" never existed. This
is not an insourmountable problem but it will bite you time and again.
<p>In log4j, categories can be configured in any order.
<p><b><li>Limited inheritance</b>
<p>In JSR47, a logger does not walk the hiearchy to inherit its level
but possesses a copy of it. In fact, levels are a particular type of
an an ineherited property.
<p>Unfortunately, in the JSR47 API, handlers cannot be inherited
because it would be prohibitely expensive (and unmanageable) to let
each logger to contain a Vector of all inherited handlers, especially
in large trees.
<p>To circumvent this problem by JSR47 defines global handlers. A
logger logs to global handlers and to the handlers attached to itself
directly. <em>It does not inherit any handlers from the
hierarchy.</em>
<p>In log4j, appenders are inherited additively from the hierachy. A
category will log to the appenders attached to itself as well as the
appenders attached to its ancestors.
<p>This might not seem like much until the day you need handler
inheritance.
<p>Similarly, in log4j resource bundles are inherited from the
hierarchy. In JSR47, a resource bundle must be attached to one logger
at a time making resource bundles and hence internationalization quite
unmanageable.
<h2>Limited functionality</h2>
<p>Log4j has appenders capable of logging to the console, to files, to
Unix Syslog daemons, to Microsoft NT EventLoggers, remote servers, to
JMS channels, etc. It can roll log files by size or date and log
asyncronously.
<p>JSR47 can log to the console, to files and to a memory buffer.
<p>Log4j has an extensible and powerful layout called the
PatternLayout. JSR47 offers the much weaker
<code>SimpleFormatter</code> as an alternative.
<p>Log4j supports configuration through property files as well as XML
documents. JSR47 currently admits only property files. Moreover, the
language of JSR47 configuration files is very weak. For example, you
can only configure one instance of a given handler class. <em>This
means that you can log to one file at a time.</em>
<p>There are many other details in which log4j differs from
JSR47. Even if the log4j core is small, the project contains a total
of over 30'000 lines of well-tested code. JSR47 contains about 5'000
lines of code.
<h2>Performance</h2>
<p>In log4j, caller localization information is optional. In JSR47 it
is always extracted. Since the extraction of caller localication is
slow, in the commen case where caller information is not needed, log4j
will log the same information at least 4 times faster.
</body>
</HTML>
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-cvs-help@jakarta.apache.org