📄 logfilter.java
字号:
// LogFilter.java// $Id: LogFilter.java,v 1.4 2000/08/16 21:37:37 ylafon Exp $// (c) COPYRIGHT MIT and INRIA, 1996.// Please first read the full copyright statement in file COPYRIGHT.htmlpackage org.w3c.jigsaw.filters;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.util.Enumeration;import org.w3c.tools.resources.Attribute;import org.w3c.tools.resources.AttributeRegistry;import org.w3c.tools.resources.FileAttribute;import org.w3c.tools.resources.FramedResource;import org.w3c.tools.resources.ProtocolException;import org.w3c.tools.resources.ReplyInterface;import org.w3c.tools.resources.RequestInterface;import org.w3c.tools.resources.ResourceFilter;import org.w3c.tools.resources.StringArrayAttribute;import org.w3c.www.http.HeaderDescription;import org.w3c.www.http.HeaderValue;import org.w3c.www.http.HttpMessage;import org.w3c.www.http.HttpReplyMessage;import org.w3c.www.http.HttpRequestMessage;import org.w3c.jigsaw.http.Reply;import org.w3c.jigsaw.http.Request;import org.w3c.tools.resources.ProtocolException;/** * This filter provides a very flexible logger. * It is not designed as a logger, in order to be plugable only on * a sub-tree of the URL space (a logger would log all site accesses). * It provides as much details as you want, and uses a very simple format: * each log entry (or <em>record</em> is made of several lines having * the folowing format: * <pre>variable=value</pre> * A record starts with the special <code>url</code> variable value which * provides the requested URL. The for each header that is to be logged, * a variable is added in the record, prefixed by its <em>scope</em>. The * scope can be either: * <dl><dt>request<dd> to specify a request header, * <dt>reply<dd> to specify a reply header, * <dt>server<dd> to specify global server samples. * </dl> * As an example, if you configure that filter to log the request's referer * and the reply content length, a sample record will look like: * <pre> * url=http://www.w3.org/pub/WWW/Jigsaw/ * request.referer=http://www.w3.org/pub/WWW * reply.content-length=10 * </pre> */public class LogFilter extends ResourceFilter { /** * Name of the state that when set on the request will prevent logging. */ public static final String DONT_LOG = "org.w3c.jigsaw.filters.LogFilter.nolog"; /** * Attribute index - The HTTP request headers to dump */ protected static int ATTR_REQUEST_HEADERS = -1; /** * Attribute index - The HTTP reply headers to dump */ protected static int ATTR_REPLY_HEADERS = -1; /** * Attribute index - The log file to use to emit log record. */ protected static int ATTR_LOGFILE = -1; static { Class c = null; Attribute a = null; try { c = Class.forName("org.w3c.jigsaw.filters.LogFilter"); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } // Register the request headers to be logged: a = new StringArrayAttribute("request-headers" , null , Attribute.EDITABLE); ATTR_REQUEST_HEADERS = AttributeRegistry.registerAttribute(c, a); // Register the reply headers to be logged: a = new StringArrayAttribute("reply-headers" , null , Attribute.EDITABLE); ATTR_REPLY_HEADERS = AttributeRegistry.registerAttribute(c, a); // Register the log file name: a = new FileAttribute("logfile" , null , Attribute.EDITABLE); ATTR_LOGFILE = AttributeRegistry.registerAttribute(c, a); } /** * Compiled index of the request headers to dump. */ protected HeaderDescription reqheaders[] = null; /** * Compiled index of the reply headers to dump. */ protected HeaderDescription repheaders[] = null; /** * Open log descriptor, to write to the log. */ protected RandomAccessFile log = null; /** * Compile the given set of header names into header indexes. * @param kind An instance of the class whose headers are to be dumped. * @param headers The name of headers to compile. * @return An array of header description, which will allow fast fetch * of header values. */ protected HeaderDescription[] compileHeaders(HttpMessage kind , String headers[]) { Enumeration e = kind.enumerateHeaderDescriptions(true); HeaderDescription r[] = new HeaderDescription[headers.length]; while ( e.hasMoreElements() ) { HeaderDescription d = (HeaderDescription) e.nextElement(); if ( d == null ) continue; for (int i = 0 ; i < headers.length ; i++) { if (headers[i].equals(d.getName())) { r[i] = d; break; } } } return r; } /** * Write the given string to the log file. * @param record The string to write. */ protected synchronized void writelog(String record) { try { if ( log != null ) log.writeBytes(record); } catch (IOException ex) { FramedResource target = (FramedResource) getTargetResource(); if (target != null) { String msg = ("IO error while writing to log file \""+ ex.getMessage() + "\"."); target.getServer().errlog(this, msg); } } } /** * Open the log stream, and make it available through <code>log</code>. * If opening the stream failed, an appropriate error message is emitted * and <code>log</code> remains set to <strong>null</strong>. If a log * stream was already opened, it is first closed. */ protected synchronized void openLog() { // Close first if needed: if ( log != null ) { try { log.close(); } catch (IOException ex) { } log = null; } // Try opening the log: File logfile = getLogfile(); try { if (logfile != null) { log = new RandomAccessFile(logfile, "rw"); log.seek(log.length()); } } catch (Exception ex) { } // If failed, emit error message: if ( log == null ) { FramedResource target = (FramedResource) getTargetResource(); if (target != null) { String msg = ("unable to open log file \""+ logfile + "\"."); target.getServer().errlog(this, msg); } } } /** * Get the log file. * @return A File instance, or <strong>null</strong> if not set. */ public File getLogfile() { return (File) getValue(ATTR_LOGFILE, null); } /** * Get the list of request headers to dump. * @return An array of String containing the name of headers to dump, or * <strong>null</strong> if undefined. */ public String[] getRequestHeaders() { return (String[]) getValue(ATTR_REQUEST_HEADERS, null); } /** * Get the list of reply headers to dump. * @return An array of String containing the name of headers to dump, * or <strong>null</strong> if undefined. */ public String[] getReplyHeaders() { return (String[]) getValue(ATTR_REPLY_HEADERS, null); } /** * Traop setValue calls. * We maintain a compiled version of both the <code>request-headers</code> * and the <code>reply-headers</code> attributes, make sure they stay in * sync even when modified. */ public void setValue(int idx, Object value) { super.setValue(idx, value); if ( idx == ATTR_REQUEST_HEADERS ) { synchronized(this) { reqheaders = compileHeaders(new HttpRequestMessage() , (String[]) value); } } else if (idx == ATTR_REPLY_HEADERS ) { synchronized(this) { repheaders = compileHeaders(new HttpReplyMessage() , (String[]) value); } } else if (idx == ATTR_LOGFILE ) { openLog(); } } /** * Log the given request/reply transaction. * Dump a record for the given transaction. * @param request The request to log. * @param reply It's associated reply. */ protected void log(Request request, Reply reply) { StringBuffer sb = new StringBuffer(); // Start a new log record: sb.append("url="); sb.append(request.getURL().toString()); sb.append('\n'); // Then log all request headers: if ( reqheaders != null ) { for (int i = 0 ; i < reqheaders.length ; i++) { HeaderDescription d = reqheaders[i]; if ( d == null ) continue; HeaderValue v = request.getHeaderValue(d); if ( v != null ) { sb.append("request."); sb.append(d.getName()); sb.append('='); sb.append(v.toString()); sb.append('\n'); } } } // The log all reply headers: if ( repheaders != null ) { for (int i = 0 ; i < repheaders.length ; i++) { HeaderDescription d = repheaders[i]; if ( d == null ) continue; HeaderValue v = reply.getHeaderValue(d); if ( v != null ) { sb.append("reply."); sb.append(d.getName()); sb.append('='); sb.append(v.toString()); sb.append('\n'); } } } writelog(sb.toString()); } /** * Log the request. * @param request The request that has been handled. * @param reply It's associated reply. * @exception org.w3c.tools.resources.ProtocolException * If processing should be interrupted, because an abnormal situation * occured. */ public ReplyInterface outgoingFilter(RequestInterface req, ReplyInterface rep) throws ProtocolException { Reply reply = (Reply) rep; Request request = (Request) req; if ( ! reply.hasState(DONT_LOG) ) log(request, reply); return null; } /** * Initialize the filter. */ public void initialize(Object values[]) { super.initialize(values); // Open the log file, ready for working: if ( log == null ) openLog(); // Compile request and reply headers to dump: if ( reqheaders == null ) { String headers[] = getRequestHeaders(); if ( headers != null ) reqheaders = compileHeaders(new HttpRequestMessage(), headers); } if ( repheaders == null ) { String headers[] = getReplyHeaders(); if ( headers != null ) repheaders = compileHeaders(new HttpReplyMessage(), headers); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -