Mercurial Hosting > luan
view src/org/eclipse/jetty/server/NCSARequestLog.java @ 855:fa6158f29c45
remove BufferDateCache and DateCache
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 20 Sep 2016 21:38:44 -0600 |
parents | 359012f4e797 |
children |
line wrap: on
line source
// // ======================================================================== // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.server; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.io.File; import java.io.FileOutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; import javax.servlet.http.Cookie; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This {@link RequestLog} implementation outputs logs in the pseudo-standard * NCSA common log format. Configuration options allow a choice between the * standard Common Log Format (as used in the 3 log format) and the Combined Log * Format (single log format). This log format can be output by most web * servers, and almost all web log analysis software can understand these * formats. * * @org.apache.xbean.XBean element="ncsaLog" */ /* ------------------------------------------------------------ */ /** */ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog { private static final Logger LOG = LoggerFactory.getLogger(NCSARequestLog.class); private String _filename; private boolean _extended; public long retainTime = 1000L*60*60*24*31; // 31 days private boolean _closeOut; private boolean _preferProxiedForAddress; private String _logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z"; private Locale _logLocale = Locale.getDefault(); public TimeZone timeZone = TimeZone.getTimeZone("GMT"); private boolean _logLatency = false; private boolean _logCookies = false; private boolean _logServer = false; private boolean _logDispatch = false; private transient OutputStream _out; private transient DateFormat dateFormat; private transient Writer _writer; /* ------------------------------------------------------------ */ /** * Create request log object with default settings. */ public NCSARequestLog() { _extended = true; } /* ------------------------------------------------------------ */ /** * Create request log object with specified output file name. * * @param filename the file name for the request log. * This may be in the format expected * by {@link RolloverFileOutputStream} */ public NCSARequestLog(String filename) { _extended = true; setFilename(filename); } /* ------------------------------------------------------------ */ /** * Set the output file name of the request log. * The file name may be in the format expected by * {@link RolloverFileOutputStream}. * * @param filename file name of the request log * */ public void setFilename(String filename) { if (filename != null) { filename = filename.trim(); if (filename.length() == 0) filename = null; } _filename = filename; } /* ------------------------------------------------------------ */ /** * Retrieve the output file name of the request log. * * @return file name of the request log */ public String getFilename() { return _filename; } /* ------------------------------------------------------------ */ /** * Set the timestamp format for request log entries in the file. * If this is not set, the pre-formated request timestamp is used. * * @param format timestamp format string */ public void setLogDateFormat(String format) { _logDateFormat = format; } /* ------------------------------------------------------------ */ /** * Retrieve the timestamp format string for request log entries. * * @return timestamp format string. */ public String getLogDateFormat() { return _logDateFormat; } /* ------------------------------------------------------------ */ /** * Set the locale of the request log. * * @param logLocale locale object */ public void setLogLocale(Locale logLocale) { _logLocale = logLocale; } /* ------------------------------------------------------------ */ /** * Retrieve the locale of the request log. * * @return locale object */ public Locale getLogLocale() { return _logLocale; } /* ------------------------------------------------------------ */ /** * Set the extended request log format flag. * * @param extended true - log the extended request information, * false - do not log the extended request information */ public void setExtended(boolean extended) { _extended = extended; } /* ------------------------------------------------------------ */ /** * Retrieve the extended request log format flag. * * @return value of the flag */ public boolean isExtended() { return _extended; } /* ------------------------------------------------------------ */ /** * Controls logging of the request cookies. * * @param logCookies true - values of request cookies will be logged, * false - values of request cookies will not be logged */ public void setLogCookies(boolean logCookies) { _logCookies = logCookies; } /* ------------------------------------------------------------ */ /** * Retrieve log cookies flag * * @return value of the flag */ public boolean getLogCookies() { return _logCookies; } /* ------------------------------------------------------------ */ /** * Controls logging of the request hostname. * * @param logServer true - request hostname will be logged, * false - request hostname will not be logged */ public void setLogServer(boolean logServer) { _logServer = logServer; } /* ------------------------------------------------------------ */ /** * Retrieve log hostname flag. * * @return value of the flag */ public boolean getLogServer() { return _logServer; } /* ------------------------------------------------------------ */ /** * Controls logging of request processing time. * * @param logLatency true - request processing time will be logged * false - request processing time will not be logged */ public void setLogLatency(boolean logLatency) { _logLatency = logLatency; } /* ------------------------------------------------------------ */ /** * Retrieve log request processing time flag. * * @return value of the flag */ public boolean getLogLatency() { return _logLatency; } /* ------------------------------------------------------------ */ /** * Controls whether the actual IP address of the connection or * the IP address from the X-Forwarded-For header will be logged. * * @param preferProxiedForAddress true - IP address from header will be logged, * false - IP address from the connection will be logged */ public void setPreferProxiedForAddress(boolean preferProxiedForAddress) { _preferProxiedForAddress = preferProxiedForAddress; } /* ------------------------------------------------------------ */ /** * Retrieved log X-Forwarded-For IP address flag. * * @return value of the flag */ public boolean getPreferProxiedForAddress() { return _preferProxiedForAddress; } /* ------------------------------------------------------------ */ /** * Controls logging of the request dispatch time * * @param value true - request dispatch time will be logged * false - request dispatch time will not be logged */ public void setLogDispatch(boolean value) { _logDispatch = value; } /* ------------------------------------------------------------ */ /** * Retrieve request dispatch time logging flag * * @return value of the flag */ public boolean isLogDispatch() { return _logDispatch; } /* ------------------------------------------------------------ */ /** * Writes the request and response information to the output stream. * * @see org.eclipse.jetty.server.RequestLog#log(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response) */ public void log(Request request, Response response) { try { if (_out == null) return; StringBuilder buf = new StringBuilder(256); if (_logServer) { buf.append(request.getServerName()); buf.append(' '); } String addr = null; if (_preferProxiedForAddress) { addr = request.getHeader(HttpHeaders.X_FORWARDED_FOR); } if (addr == null) addr = request.getRemoteAddr(); buf.append(addr); buf.append(" - ["); synchronized(dateFormat) { buf.append(dateFormat.format(request.getTimeStamp())); } buf.append("] \""); buf.append(request.getMethod()); buf.append(' '); buf.append(request.getUri().toString()); buf.append(' '); buf.append(request.getProtocol()); buf.append("\" "); if (request.getAsyncContinuation().isInitial()) { int status = response.getStatus(); if (status <= 0) status = 404; buf.append((char)('0' + ((status / 100) % 10))); buf.append((char)('0' + ((status / 10) % 10))); buf.append((char)('0' + (status % 10))); } else buf.append("Async"); long responseLength = response.getContentCount(); if (responseLength >= 0) { buf.append(' '); if (responseLength > 99999) buf.append(responseLength); else { if (responseLength > 9999) buf.append((char)('0' + ((responseLength / 10000) % 10))); if (responseLength > 999) buf.append((char)('0' + ((responseLength / 1000) % 10))); if (responseLength > 99) buf.append((char)('0' + ((responseLength / 100) % 10))); if (responseLength > 9) buf.append((char)('0' + ((responseLength / 10) % 10))); buf.append((char)('0' + (responseLength) % 10)); } buf.append(' '); } else buf.append(" - "); if (_extended) logExtended(request, response, buf); if (_logCookies) { Cookie[] cookies = request.getCookies(); if (cookies == null || cookies.length == 0) buf.append(" -"); else { buf.append(" \""); for (int i = 0; i < cookies.length; i++) { if (i != 0) buf.append(';'); buf.append(cookies[i].getName()); buf.append('='); buf.append(cookies[i].getValue()); } buf.append('\"'); } } if (_logDispatch || _logLatency) { long now = System.currentTimeMillis(); if (_logDispatch) { long d = request.getDispatchTime(); buf.append(' '); buf.append(now - (d==0 ? request.getTimeStamp():d)); } if (_logLatency) { buf.append(' '); buf.append(now - request.getTimeStamp()); } } buf.append('\n'); String log = buf.toString(); write(log); } catch (IOException e) { LOG.warn("",e); } } /* ------------------------------------------------------------ */ protected void write(String log) throws IOException { synchronized(this) { if (_writer==null) return; _writer.write(log); _writer.flush(); } } /* ------------------------------------------------------------ */ /** * Writes extended request and response information to the output stream. * * @param request request object * @param response response object * @param b StringBuilder to write to * @throws IOException */ protected void logExtended(Request request, Response response, StringBuilder b) throws IOException { String referer = request.getHeader(HttpHeaders.REFERER); if (referer == null) b.append("\"-\" "); else { b.append('"'); b.append(referer); b.append("\" "); } String agent = request.getHeader(HttpHeaders.USER_AGENT); if (agent == null) b.append("\"-\" "); else { b.append('"'); b.append(agent); b.append('"'); } } /* ------------------------------------------------------------ */ /** * Set up request logging and open log file. * * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() */ @Override protected synchronized void doStart() throws Exception { dateFormat = new SimpleDateFormat(_logDateFormat,_logLocale); dateFormat.setTimeZone(timeZone); if (_filename != null) { File file = new File(_filename); if( file.exists() ) { File old = new File(_filename+".old"); if( old.exists() && file.lastModified() - old.lastModified() > retainTime ) old.delete(); if( !old.exists() ) file.renameTo(old); } _out = new FileOutputStream(file,true); _closeOut = true; LOG.info("Opened " + _filename); } else _out = System.err; synchronized(this) { _writer = new OutputStreamWriter(_out); } super.doStart(); } /* ------------------------------------------------------------ */ /** * Close the log file and perform cleanup. * * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop() */ @Override protected void doStop() throws Exception { synchronized (this) { super.doStop(); try { if (_writer != null) _writer.flush(); } catch (IOException e) { LOG.trace("",e); } if (_closeOut) try { _out.close(); } catch (IOException e) { LOG.trace("",e); } _out = null; _closeOut = false; dateFormat = null; _writer = null; } } }