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/09/20 00:09:10 UTC
cvs commit: jakarta-log4j/src/docbook architecture.xml faq.xml glossary.xml intro.xml
ceki 01/09/19 15:09:10
Modified: src/docbook architecture.xml faq.xml glossary.xml intro.xml
Log:
Several improvements to the docbook documentation.
Revision Changes Path
1.8 +140 -9 jakarta-log4j/src/docbook/architecture.xml
Index: architecture.xml
===================================================================
RCS file: /home/cvs/jakarta-log4j/src/docbook/architecture.xml,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- architecture.xml 2001/09/18 22:03:15 1.7
+++ architecture.xml 2001/09/19 22:09:10 1.8
@@ -319,10 +319,10 @@
</tgroup>
</table>
- <para>In example 4, the categories <varname>root</varname> and
+ <para>In example 4, the loggers <varname>root</varname> and
<varname>X</varname> and are assigned the priorities
<varname>Proot</varname> and <varname>DEBUG</varname>
- respectively. The categories <varname>X.Y</varname> and
+ respectively. The loggers <varname>X.Y</varname> and
<varname>X.Y.Z</varname> inherits their level (ERROR) from
their nearest parent <varname>X</varname> with an assigned
level.
@@ -676,7 +676,7 @@
<title>Imaginary orange rendering</title>
<programlisting>
- Orange orange = new Orange("89", "jaffa", date);
+ Orange orange = new Orange("89", "jaffa");
logger.debug("Here is how a rendered orange looks:");
logger.debug(orange);
</programlisting>
@@ -687,8 +687,7 @@
<screen>
4309 DEBUG [main] example.orange - Here is how a rendered orange looks:
- 4312 DEBUG [main] example.orange - brand=jaffa, weight=89 g., picking date=2001-09-14
-
+ 4312 DEBUG [main] example.orange - jaffa brand, weighing 89 grams.
</screen>
</example>
@@ -715,9 +714,141 @@
</sect1>
- <sect1>
- <title>Performance</title>
- <para></para>
- </sect1>
+ <sect1>
+ <title>Performance</title>
+
+ <para>One of the often-cited arguments against logging is its
+ computational cost. This is a legitimate concern as even
+ moderately sized applications can generate thousands of log
+ requests. Much effort was spent measuring and tweaking logging
+ performance. Log4j claims to be fast and flexible: speed first,
+ flexibility second.
+ </para>
+
+ <para>The user should be aware of the following performance
+ issues.</para>
+
+
+ <orderedlist>
+
+ <listitem>
+ <para>Logging performance when logging is turned off.</para>
+
+ <para>When logging is <ulink
+ url="api/org/apache/log4j/Hierarchy.html#disableAll()">turned
+ off entirely</ulink> or just for a <ulink
+ url="api/org/apache/log4j/Hierarchy.html#disable(org.apache.log4j.Priority)">set
+ of priorities</ulink>, the cost of a log request consists of a
+ method invocation plus an integer comparison. On a 233
+ MHz Pentium II machine this cost is typically in the 5 to
+ 50 nanosecond range.
+ </para>
+
+ <para>However, The method invocation involves the "hidden" cost of
+ parameter construction. </para>
+
+ <para>For example, for some logger <varname>x</varname> writing,
+ <programlisting>
+ x.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
+ </programlisting>
+
+ incurs the cost of constructing the message parameter, i.e.
+ converting both integer <varname>i</varname> and <varname>entry[i]</varname>
+ to a String, and concatenating intermediate strings,
+ regardless of whether the message will be logged or not.
+ </para>
+
+ <para>This cost of parameter construction can be quite high and it
+ depends on the size of the parameters involved.</para>
+
+
+ <para>To avoid the parameter construction cost write:
+ <programlisting>
+ if(x.isDebugEnabled() {
+ x.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
+ }
+ </programlisting>
+ </para>
+
+ <para>This will not incur the cost of parameter construction
+ if debugging is disabled. On the other hand, if the logger is
+ debug-enabled, it will incur twice the cost of evaluating
+ whether the logger is enabled or not: once in
+ <function>debugEnabled</function> and once in
+ <function>debug</function>. This is an insignificant
+ overhead because evaluating a logger takes about 1% of the
+ time it takes to actually log.
+ </para>
+
+ <para>In log4j, logging requests are made to instances of the Logger
+ class. Logger is a class and not an interface. This measurably
+ reduces the cost of method invocation at the cost of some
+ flexibility.</para>
+
+ <para>Certain users resort to preprocessing or compile-time
+ techniques to compile out all log statements. This leads to perfect
+ performance efficiency with respect to logging. However, since the
+ resulting application binary does not contain any log statements,
+ logging cannot be turned on for that binary. In my opinion this is
+ a disproportionate price to pay in exchange for a small performance
+ gain.</para>
+ </listitem>
+
+ <listitem>
+ <para>The performance of deciding whether to log or not to log when
+ logging is turned on.</para>
+
+ <para>This is essentially the performance of walking the logger
+ hierarchy. When logging is turned on, log4j still needs to compare
+ the priority of the log request with the priority of the request
+ logger. However, loggers may not have an assigned
+ priority; they can inherit them from the logger hierarchy. Thus,
+ before inheriting a priority, the logger may need to search its
+ ancestors.</para>
+
+ <para>There has been a serious effort to make this hierarchy
+ walk to be as fast as possible. For example, child
+ loggers link only to their existing ancestors. In the
+ <classname>BasicConfigurator</classname> example shown
+ earlier, the logger named
+ <classname>com.foo.Bar</classname> is linked directly to the
+ root logger, thereby circumventing the nonexistent
+ <classname>com</classname> or <classname>com.foo</classname>
+ loggers. This significantly improves the speed of the
+ walk, especially in "sparse" hierarchies.
+ </para>
+
+ <para>The typical cost of walking the hierarchy is typically 3
+ times slower than when logging is turned off entirely.</para>
+ </listitem>
+
+ <listitem>
+
+ <para>Actual logging.</para>
+
+ <para>This is the cost of formatting the log output and sending it to
+ its target destination. Here again, a serious effort was made to
+ make layouts (formatters) perform as quickly as possible. The same
+ is true for appenders. The typical cost of actually logging is
+ about 100 to 300 microseconds.</para>
+
+ <para>See <ulink
+ url="../api/org/apache/log4j/performance/Logging.html">org.apache.log4.performance.Logging</ulink>
+ for actual figures.</para>
+
+ </listitem>
+ </orderedlist>
+
+ <para>Although log4j has many features, its first design goal was
+ speed. Some log4j components have been rewritten many times to
+ improve performance. Nevertheless, contributors frequently come up
+ with new optimizations. You should be pleased to know that when
+ configured with the <ulink
+ url="../api/org/apache/log4j/SimpleLayout.html">SimpleLayout</ulink>
+ performance tests have shown log4j to log as quickly as
+ <function>System.out.println</function>.</para>
+
+
+ </sect1>
</chapter>
1.2 +54 -3 jakarta-log4j/src/docbook/faq.xml
Index: faq.xml
===================================================================
RCS file: /home/cvs/jakarta-log4j/src/docbook/faq.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- faq.xml 2001/09/10 10:51:47 1.1
+++ faq.xml 2001/09/19 22:09:10 1.2
@@ -17,9 +17,60 @@
<para>Is log4j thread safe?</para>
</question>
<answer>
- <para>Yes it is.</para>
+ <para>
+ Yes, log4j is thread-safe. In particular, when multiple
+ threads call the same appender, their requests are
+ synchronized within the doAppend method of <ulink url="../api/org/apache/log4j/AppenderSkeleton.html">AppenderSkeleton</ulink>
+ which is the super-class of all appenders in log4j.
+ </para>
</answer>
</qandaentry>
- </qandaset>
-
+
+ <qandaentry>
+ <question>
+ <para>How is log4j different from <link
+ linkend="gloss-jsr47"><classname>java.util.logging</classname></link>.
+ API?</para>
+ </question>
+ <answer>
+ <para>
+ The two APIs are very similar. As a result of <ulink
+ url="http://jakarta.apache.org/log4j/docs/critique.html">our
+ campaign</ulink> to influence and improve the JSR47 API, in
+ its next revision JSR47 will resemble log4j even more closely.
+ </para>
+
+ <para>
+ There are two critical differences between the APIs. First,
+ JSR47 requires JDK 1.4 whereas log4j is compatible with JDK
+ 1.1 and later. Second, log4j offers much more
+ functionality. It supports a rich configuration language, at
+ least a dozen appenders and layouts as well as many other
+ useful features.
+ </para>
+
+ </answer>
+ </qandaentry>
+
+
+ <qandaentry>
+ <question>
+ <para>Why was the <classname>Category</classname> class renamed
+ as <classname>Logger</classname> and the
+ <classname>Priority</classname> class to
+ <classname>Level</classname>?</para>
+ </question>
+ <answer>
+ <para>
+ The renaming was done essentially because that is how JSR47
+ names things. It is beneficial to adopt JSR47 terminology
+ because all those who know
+ <classname>java.util.logging</classname> will feel quickly at
+ home with log4j as well.
+ </para>
+ </answer>
+ </qandaentry>
+
+
+ </qandaset>
</chapter>
1.3 +9 -22 jakarta-log4j/src/docbook/glossary.xml
Index: glossary.xml
===================================================================
RCS file: /home/cvs/jakarta-log4j/src/docbook/glossary.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- glossary.xml 2001/09/08 17:57:38 1.2
+++ glossary.xml 2001/09/19 22:09:10 1.3
@@ -20,30 +20,17 @@
</glossentry>
- <glossentry id="xml">
- <glossterm>Extensible Markup Language</glossterm>
- <acronym>XML</acronym>
+ <glossentry id="gloss-jsr47">
+ <glossterm><classname>java.util.logging</classname> API</glossterm>
+ <acronym>JSR47</acronym>
<glossdef>
- <para>Some reasonable definition here.</para>
- <glossseealso otherterm="sgml">SGML</glossseealso>
- </glossdef>
- </glossentry>
-
- <glossentry><glossterm>SGML</glossterm>
- <glosssee otherterm="sgml"/>
- </glossentry>
-
+ <para>The logging API introduced in JDK 1.4. It is the result of
+ the <ulink
+ url="http://jcp.org/aboutJava/communityprocess/review/jsr047/index.html">JSR47</ulink>
+ effort.
- <glossentry id="sgml">
- <glossterm>Standard Generalized Markup Language</glossterm>
- <acronym>SGML</acronym>
- <abbrev>ISO 8879:1986</abbrev>
- <glossdef>
- <para>Some reasonable definition here.</para>
- <glossseealso otherterm="xml">XML</glossseealso>
+ </para>
</glossdef>
-
</glossentry>
-
-
+
</glossary>
1.6 +6 -1 jakarta-log4j/src/docbook/intro.xml
Index: intro.xml
===================================================================
RCS file: /home/cvs/jakarta-log4j/src/docbook/intro.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- intro.xml 2001/09/18 22:03:15 1.5
+++ intro.xml 2001/09/19 22:09:10 1.6
@@ -176,8 +176,13 @@
<screen>0 [main] DEBUG chapter1.MyApp2 - Hello world.</screen>
</para>
+ </sect1>
+
+ <sect1>
+ <title>Recipe for using log4j in your applications</title>
+
<procedure>
- <title>Using log4j</title>
+ <title></title>
<para>This is are the steps you must take in order to use log4j
in your applications.
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-cvs-help@jakarta.apache.org