alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*   
 *  Copyright 1999-2004 The Apache Sofware Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.tomcat.modules.loggers;


import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

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;


/** 

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 server.xml:

*
 *   <RequestInterceptor
 *     className="org.apache.tomcat.logging.AccessLogInterceptor"
 *     logFile="logs/AccessLog" format="combined"/>
 * 
*

Possible attributes of the above XML element are: * * * * * * * * * * * * * *
logFileName of the logfile being generated. Defaults to "logs/AccessLog". * Tomcat.home is prepended, if the file name is relative.
flushAn 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. *
format * 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 *
 *         '%h %l %u %t "%r" %>s %b "%{Referer}" "%{User-Agent}"'
 *         '%h %l %u %t "%r" %>s %b'
 *       
* (The above examples are used when "combined" or "common" * format is requested.) Possible patterns are: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * . * * *
%%The percent character itself
%{var}The value of request.getHeader("var") or * empty string for null. *
%bThe value of response.getContentLength().
%hThe value of request.getRemoteHost().
%lShould be the remote users name, as indicated by an * identd lookup. Currently it is always "-".
%rFirst line of the request submitted by the client, for * example *
 *               GET /index.html?frame=main HTTP/1.0
 *             
* The first line is rebuilt from the values of * request.getMethod(), * request.getRequestURI(), * request.getQueryString() and * request.getProtocol(). It should probably * better be recorded while reading the headers. *
%sThe value of response.getStatus().
%>sThe value of response.getStatus(). * Should differ between different internal requests, as * Apache httpd does, but this is currently not supported.
%tThe current time and date in the format *
 *               [20/Apr/2001:19:45:23 0200]
 *             
*
%uThe value of request.getRemoteUser() or * "-" for null.
*
*

* * @author Jochen Wiedmann, jochen.wiedmann@softwareag.com */ 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 FileWriter fw = null; private static String fileName = "logs/AccessLog"; private static boolean useFlush = false; private static String logformat = LOGFORMAT_COMBINED; private static DateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss"); private static String crlf = System.getProperty("line.separator"); /** Creates a new AccessLogInterceptor */ public AccessLogInterceptor() {} /**

Sets the logfile name.

*/ public static void setLogFile(String logFile) { synchronized (AccessLogInterceptor.class) { fileName = logFile; } } /**

Enables (true) or disables (false, default) flushing * the log file after any request.

*/ public static void setFlush(boolean flush) { synchronized (AccessLogInterceptor.class) { useFlush = flush; } } /**

Sets the logfile format.

*/ 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; } } } /**

This method must be called while * synchronizing on AccessLogIntercepror.class!

*/ private FileWriter getFileWriter() { if (fw != null) { return fw; } if (fileName != null) { try { File f = new File(fileName); if (!f.isAbsolute()) { f=new File( cm.getHome()); f=new File( f, fileName ); //f = cm.getAbsolute(f); } fw = new FileWriter(f.getAbsolutePath(), true); } catch (IOException e) { e.printStackTrace(System.err); } } return fw; } /**

This method is actually creating an entry in the log file.

*/ public int postRequest(Request request, Response response) { synchronized (AccessLogInterceptor.class) { 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': if( request.remoteHost().toString() != null ) fw.write(request.remoteHost().toString()); else fw.write( "DEFAULT" ); break; case 'l': fw.write('-'); break; // identd not supported case 'u': String user = request.getRemoteUser(); fw.write(user == null ? "-" : user); break; case 't': Calendar cal = Calendar.getInstance(); fw.write('['); fw.write(df.format(cal.getTime())); fw.write(' '); long millis = cal.get(Calendar.ZONE_OFFSET) + cal.get(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.method().toString()); fw.write(' '); fw.write(request.requestURI().toString()); String q = request.queryString().toString(); if (q != null && q.length() > 0) { fw.write('?'); fw.write(q); } fw.write(' '); fw.write(request.protocol().toString().trim()); break; case 'b': String cl; if(response.getStatus() == 201) { cl = request.getHeader("Content-Length"); } else { cl = response.getMimeHeaders(). getHeader("Content-Length"); } if(cl != null && !"0".equals(cl)) { fw.write(cl); } else { fw.write("-"); } 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(crlf); if (useFlush) { fw.flush(); } } catch (IOException e) { } } } return 0; } public void engineShutdown(ContextManager cm) throws TomcatException { // From: Mike Schrag try { getFileWriter().flush(); getFileWriter().close(); } catch (IOException e) { e.printStackTrace(); } } }
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.