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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]