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> * <RequestInterceptor * className="org.apache.tomcat.logging.AccessLogInterceptor" * logFile="logs/AccessLog" format="combined"/> * </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; } }