<?xml version="1.0" encoding="ISO-8859-1"?>

<document>

   <properties>
      <title>HttpClient Logging Practices</title>
      <author email="dev@hc.apache.org">HttpComponents Team</author>
      <revision>$Id$</revision>
   </properties>

   <body>
      <section name="Logging Practices">
         <p>
            Being a library HttpClient is not to dictate which logging framework
            the user has to use. Therefore  <em>HttpClient</em> utilizes the logging 
            interface provided by the
            <a href="http://commons.apache.org/logging/">
            Commons Logging</a> package.  <em>Commons Logging</em> provides
            a simple and generalized 
            <a href="http://commons.apache.org/logging/commons-logging-1.0.4/docs/apidocs/">
            log interface</a> to various logging packages. By using
            <em>Commons Logging</em>, <em>HttpClient</em> can be configured
            for a variety of different logging behaviours. That means the user will have
            to make a choice which logging framework to use. By default <em>Commons Logging</em>
            supports the following logging frameworks:
            <ul>
              <li><a href="http://logging.apache.org/log4j/docs/index.html">Log4J</a></li>
              <li><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/package-summary.html">
                  java.util.logging</a></li>
              <li><a href="http://commons.apache.org/logging/commons-logging-1.0.4/docs/apidocs/org/apache/commons/logging/impl/SimpleLog.html">
                  SimpleLog</a> (internal to <em>Commons Logging</em>)</li>  
            </ul>
            By implementing some simple interfaces <em>Commons Logging</em> can be extended to support
            basically any other custom logging framework.
            <em>Commons Logging</em> tries to automatically discover the logging framework to use. If it
            fails to select the expected one, you must configure <em>Commons Logging</em> by hand. Please
            refer to the <em>Commons Logging</em> documentation for more information.
         </p><p>
            <em>HttpClient</em> performs two different kinds of logging: the standard
            context logging used within each class, and wire logging.            
         </p>
         <subsection name="Context Logging">
         <p>
            Context logging contains information about the internal operation
            of HttpClient as it performs HTTP requests.  Each class has its own
            log named according to the class's fully qualified name.  For example
            the class <code>HttpClient</code> has a log named 
            <code>org.apache.commons.httpclient.HttpClient</code>.  Since all classes
            follow this convention it is possible to configure context logging for 
            all classes using the single log named <code>org.apache.commons.httpclient</code>.
         </p>
         </subsection>
         <subsection name="Wire Logging">
         <p>
            The wire log is used to log all data transmitted to and from servers when
            executing HTTP requests.  This log should only be enabled to debug problems,
            as it will produce an extremely large amount of log data, some of it in binary
            format.
         </p>
         <p>
            Because the content of HTTP requests is usually less important for debugging 
            than the HTTP headers, these two types of data have been separated into 
            different wire logs.  The content log is <code>httpclient.wire.content</code> 
            and the header log is <code>httpclient.wire.header</code>.
         </p>
         </subsection>
      </section>
      <section name="Configuration Examples">
          <p>
             <em>Commons Logging</em> can delegate to a variety of loggers for processing 
             the actual output.  Below are configuration examples for <em>Commons Logging</em>, 
             <em>Log4j</em> and <em>java.util.logging</em>.
          </p>
          <subsection name="Commons Logging Examples">
              <p>
                 <em>Commons Logging</em> comes with a basic logger called 
                 <code>SimpleLog</code>.  This logger writes all logged messages to 
                 <code>System.err</code>. The following examples show how to  configure 
                 <em>Commons Logging</em> via system properties to use <code>SimpleLog</code>.
              </p>
              <p>
                <b>Note:</b> The system properties must be set before a reference to any 
                <em>Commons Logging</em> class is made.              
              </p>
              <p>
                <u>Enable header wire + context logging</u> - <b>Best for Debugging</b><br />
                <blockquote>
                 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire.header", "debug");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");<br />
                </blockquote>
              </p>          
              <p>
                <u>Enable full wire(header and content) + context logging</u><br />
                <blockquote>
                 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");<br />
                </blockquote>
              </p>
              <p>
                <u>Enable just context logging</u><br />
                <blockquote>
                 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");<br />
                 System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug");<br />
                </blockquote>
              </p>          
          </subsection>
          <subsection name="Log4j Examples">
            <p>
                The simplest way to configure <a href="http://logging.apache.org/log4j/">Log4j</a> 
                is via a <i>log4j.properties</i> file.  <em>Log4j</em> will automatically 
                read and configure itself using a file named <i>log4j.properties</i> when 
                it's present at the root of the application classpath.  Below are some 
                <em>Log4j</em> configuration examples.
            </p>
              <p>
                <b>Note:</b> <em>Log4j</em> is not included in the <em>HttpClient</em> distribution.              
              </p>
              <p>
                <u>Enable header wire + context logging</u> - <b>Best for Debugging</b><br />
                <blockquote>
                  log4j.rootLogger=INFO, stdout<br />
                  <br />
                  log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
                  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
                  log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n<br />
                  <br />
                  log4j.logger.httpclient.wire.header=DEBUG<br />
                  log4j.logger.org.apache.commons.httpclient=DEBUG<br />
                </blockquote>
              </p>          
              <p>
                <u>Enable full wire(header and content) + context logging</u><br />
                <blockquote>
                  log4j.rootLogger=INFO, stdout<br />
                  <br />
                  log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
                  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
                  log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n<br />
                  <br />
                  log4j.logger.httpclient.wire=DEBUG<br />
                  log4j.logger.org.apache.commons.httpclient=DEBUG<br />
                </blockquote>
              </p>
              <p>
                <u>Log wire to file + context logging</u><br />
                <blockquote>
                  log4j.rootLogger=INFO<br />
                  <br />
                  log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
                  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
                  log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n<br />
                  <br />
                  log4j.appender.F=org.apache.log4j.FileAppender<br />
                  log4j.appender.F.File=wire.log<br />
                  log4j.appender.F.layout=org.apache.log4j.PatternLayout<br />
                  log4j.appender.F.layout.ConversionPattern =%5p [%c] %m%n<br />
                  <br />
                  log4j.logger.httpclient.wire=DEBUG, F<br />
                  log4j.logger.org.apache.commons.httpclient=DEBUG, stdout<br />
                </blockquote>
              </p>
              <p>
                <u>Enable just context logging</u><br />
                <blockquote>
                  log4j.rootLogger=INFO, stdout<br />
                  <br />
                  log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />
                  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br />
                  log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n<br />
                  <br />
                  log4j.logger.org.apache.commons.httpclient=DEBUG<br />
                </blockquote>
             </p>          
             <p>Note that the default configuration for Log4J is very
             inefficient as it causes all the logging information to be
             generated but not actually sent anywhere.  The Log4J manual is the
             best reference for how to configure Log4J.  It is available at <a
             href="http://logging.apache.org/log4j/docs/manual.html">http://logging.apache.org/log4j/docs/manual.html</a>
             </p>
          </subsection>
          <subsection name="java.util.logging Examples">
            <p>
              Since JDK 1.4 there has been a package 
              <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/package-summary.html">
              java.util.logging</a> that provides a
              logging framework similar to <em>Log4J</em>. By default it reads a config file from
              <code>$JAVA_HOME/jre/lib/logging.properties</code> which looks like this
              (comments stripped):
              <blockquote>
                handlers=java.util.logging.ConsoleHandler<br/>
                .level=INFO<br/>
                java.util.logging.FileHandler.pattern = %h/java%u.log<br/>
                java.util.logging.FileHandler.limit = 50000<br/>
                java.util.logging.FileHandler.count = 1<br/>
                java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter<br/>
                java.util.logging.ConsoleHandler.level = INFO<br/>
                java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter<br/>
                com.xyz.foo.level = SEVERE<br/>         
              </blockquote>
              To customize logging a custom <code>logging.properties</code> file should be created
              in the project directory. The location of this file must be passed to the JVM as a
              system property. This can be done on the command line like so:
              <blockquote>
                $JAVA_HOME/java -Djava.util.logging.config.file=$HOME/myapp/logging.properties
                -classpath $HOME/myapp/target/classes com.myapp.Main
              </blockquote>
              Alternatively
              <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/LogManager.html#readConfiguration(java.io.InputStream)">
              LogManager#readConfiguration(InputStream)</a> can be used to pass it the desired
              configuration.
            </p>
            <p>
              <u>Enable header wire + context logging</u> - <b>Best for Debugging</b><br />
              <blockquote>
              .level=INFO<br/>
              <br />
              handlers=java.util.logging.ConsoleHandler<br/>
              java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter<br/>
              <br />
              httpclient.wire.header.level=FINEST<br />
              org.apache.commons.httpclient.level=FINEST<br />
              </blockquote>
            </p>          
            <p>
              <u>Enable full wire(header and content) + context logging</u><br />
              <blockquote>
              .level=INFO<br/>
              <br />
              handlers=java.util.logging.ConsoleHandler<br/>
              java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter<br/>
              <br />
              httpclient.wire.level=FINEST<br />
              org.apache.commons.httpclient.level=FINEST<br />
              </blockquote>
            </p>
            <p>
              <u>Enable just context logging</u><br />
              <blockquote>
              .level=INFO<br/>
              <br />
              handlers=java.util.logging.ConsoleHandler<br/>
              java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter<br/>
              <br />
              org.apache.commons.httpclient.level=FINEST<br />
              </blockquote>
           </p>      
           <p>
             More detailed information is available from the
             <a href="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html">
             Java Logging documentation</a>.
           </p>    
          </subsection>
      </section>
   </body>

</document>
