Quoting [EMAIL PROTECTED]:

> Please send the source file - you attached a .class :-)

So sorry - here it is. :-)


Thank you,

Jochen

package org.apache.tomcat.logging;

import org.apache.tomcat.core.BaseInterceptor;
import org.apache.tomcat.core.ContextManager;
import org.apache.tomcat.core.Request;
import org.apache.tomcat.core.Response;
import org.apache.tomcat.core.TomcatException;


/** <p>This is a TomCat RequestInterceptor that creates log files
 * in the style of the Apache servers "AccessLog". It used by
 * embedding a line like the following into <code>server.xml</code>:</p>
 * <pre>
 *   &lt;RequestInterceptor
 *     className="org.apache.tomcat.logging.AccessLogInterceptor"
 *     logFile="logs/AccessLog" format="combined"/&gt;
 * </pre>
 * <p>Possible attributes of the above XML element are:
 * <table>
 *   <tr>
 *     <th valign="top">logFile</th>
 *     <td>Name of the logfile being generated. Defaults to "logs/AccessLog".
 *       Tomcat.home is prepended, if the file name is relative.</td>
 *   </tr>
 *   <tr>
 *     <th valign="top">flush</th>
 *     <td>An optional boolean attribute, that enables (value = "true")
 *       or disables (value="false", default) flushing the log file
 *       after every request. For performance reasons, you should
 *       not enable flushing unless you are debugging this class.
 *     </td>
 *   </tr>
 *   <tr>
 *     <th valign="top">format</th>
 *     <td>
 *       A string describing the logfile format. Possible values are
 *       "combined" (Apache httpd combined format, default), "common"
 *       (Apache httpd common format) or a format string like
 *       <pre>
 *         '%h %l %u %t "%r" %>s %b "%{Referer}" "%{User-Agent}"'
 *         '%h %l %u %t "%r" %>s %b'
 *       </pre>
 *       (The above examples are used when "combined" or "common"
 *       format is requested.) Possible patterns are:
 *       <table>
 *         <tr><th valign="top">%%</th>
 *           <td>The percent character itself</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%{var}</th>
 *           <td>The value of <code>request.getHeader("var")</code> or
 *             empty string for null.<td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%b</th>
 *           <td>The value of <code>response.getContentLength()</code>.</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%h</th>
 *           <td>The value of <code>request.getRemoteHost()</code>.</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%l</th>
 *           <td>Should be the remote users name, as indicated by an
 *             identd lookup. Currently it is always "-".</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%r</th>
 *           <td>First line of the request submitted by the client, for
 *             example
 *             <pre>
 *               GET /index.html?frame=main HTTP/1.0
 *             </pre>
 *             The first line is rebuilt from the values of
 *             <code>request.getMethod()</code>,
 *             <code>request.getRequestURI()</code>,
 *             <code>request.getQueryString()</code> and
 *             <code>request.getProtocol()</code>. It should probably
 *             better be recorded while reading the headers.
 *           </td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%s</th>
 *           <td>The value of <code>response.getStatus()</code>.</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%>s</th>
 *           <td>The value of <code>response.getStatus()</code>.
 *             Should differ between different internal requests, as
 *             Apache httpd does, but this is currently not supported.</td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%t</th>
 *           <td>The current time and date in the format
 *             <pre>
 *               [20/Apr/2001:19:45:23 0200]
 *             </pre>
 *           </td>
 *         </tr>
 *         <tr>
 *           <th valign="top">%u</th>
 *           <td>The value of <code>request.getRemoteUser()</code> or
 *             "-" for null.</td>.
 *         </tr>
 *         <tr>
 *       </table>
 *     </td>
 *   </tr> 
 * </table>
 * </p>
 *
 * @author  Jochen Wiedmann, [EMAIL PROTECTED]
 */
public class AccessLogInterceptor extends BaseInterceptor {
  private static final String LOGFORMAT_COMBINED = "%h %l %u %t \"%r\" %>s %b 
\"%{Referer}\" \"%{User-Agent}\"";
  private static final String LOGFORMAT_COMMON = "%h %l %u %t \"%r\" %>s %b";
  private static java.io.FileWriter fw = null;
  private static String fileName = "logs/AccessLog";
  private static boolean useFlush = false;
  private static String logformat = LOGFORMAT_COMBINED;
  private static java.text.DateFormat df = new 
java.text.SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss");

  /** Creates a new AccessLogInterceptor */
  public AccessLogInterceptor() {}

  /** <p>Sets the logfile name.</p>
   */
  public static void setLogFile(String logFile) {
    synchronized (AccessLogInterceptor.class) {
      fileName = logFile;
    }
  }

  /** <p>Enables (true) or disables (false, default) flushing
   * the log file after any request.</p>
   */
  public static void setFlush(boolean flush) {
    synchronized (AccessLogInterceptor.class) {
      useFlush = flush;
    }
  }

  /** <p>Sets the logfile format.</p>
   */
  public static void setFormat(String format) {
    synchronized (AccessLogInterceptor.class) {
      if (format.equalsIgnoreCase("combined")) {
        logformat = LOGFORMAT_COMBINED;
      } else if (format.equalsIgnoreCase("common")) {
        logformat = LOGFORMAT_COMMON;
      } else {
        logformat = format;
      }
    }
  }

  /** <p>This method <strong>must</strong> be called while
   * synchronizing on <code>AccessLogIntercepror.class</code>!</p>
   */
  private java.io.FileWriter getFileWriter() {
    if (fw != null) {
      return fw;
    }
    if (fileName != null) {
      try {
        java.io.File f = new java.io.File(fileName);
        if (!f.isAbsolute()) {
          f = cm.getAbsolute(f);
        }
        fw = new java.io.FileWriter(f.getAbsolutePath(), true);
      } catch (java.io.IOException e) {
        e.printStackTrace(System.err);
      }
    }
    return fw;
  }

  /** <p>This method is actually creating an entry in the log file.</p>
   */
  public int beforeCommit(Request request, Response response) {
    synchronized (AccessLogInterceptor.class) {
      java.io.FileWriter fw = getFileWriter();
      if (fw != null) {
        try {
          for (int i = 0;  i < logformat.length();  i++) {
            char c = logformat.charAt(i);
            if (c == '%'  &&  ++i < logformat.length()) {
              c = logformat.charAt(i);
              switch (c) {
                case 'h': fw.write(request.getRemoteHost()); break;
                case 'l': fw.write('-'); break; // identd not supported
                case 'u':
                  String user = request.getRemoteUser();
                  fw.write(user == null ? "-" : user);
                  break;
                case 't':
                  java.util.Calendar cal = java.util.Calendar.getInstance();
                  fw.write('[');
                  fw.write(df.format(cal.getTime()));
                  fw.write(' ');
                  long millis = cal.get(java.util.Calendar.ZONE_OFFSET) +
                                cal.get(java.util.Calendar.DST_OFFSET);
                  String msecstr = Long.toString((millis+60*500)/(60*1000));
                  for (int j = msecstr.length();  j < 4;  j++) {
                    fw.write('0');
                  }
                  fw.write(msecstr);
                  fw.write(']');
                  break;
                case 'r':
                  fw.write(request.getMethod());
                  fw.write(' ');
                  fw.write(request.getRequestURI());
                  String q = request.getQueryString();
                  if (q != null) {
                    fw.write('?');
                    fw.write(q);
                  }
                  fw.write(' ');
                  fw.write(request.getProtocol().trim());
                  break;
                case 'b':
                  int len = response.getContentLength();
                  fw.write(Integer.toString(len));
                  break;
                case 's':
                  fw.write(Integer.toString(response.getStatus()));
                  break;
                case '>':
                  if (++i < logformat.length()) {
                    c = logformat.charAt(i);
                    if (c == 's') {
                      fw.write(Integer.toString(response.getStatus()));
                    } else {
                      fw.write('>');
                      fw.write(c);
                    }
                  } else {
                    fw.write(c);
                  }
                  break;
                case '{':
                  int offset = logformat.indexOf('}', i);
                  if (offset == -1) {
                    fw.write(c);
                  } else {
                    String var = logformat.substring(i+1, offset);
                    String val = request.getHeader(var);
                    if (val != null) {
                      fw.write(val);
                    }
                    i = offset;
                  }
                  break;
                default:  fw.write(c); break;
              } 
            } else {
              fw.write(c);
            }
          }
          fw.write('\n');
          if (useFlush) {
            fw.flush();
          }
        } catch (java.io.IOException e) {
        }
      }
    }
    return 0;
  }
}

Reply via email to