Mercurial Hosting > luan
view src/org/eclipse/jetty/server/handler/RequestLogHandler.java @ 862:2bb375e94f64
simplify jetty.util.IO
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 02 Oct 2016 05:17:11 -0600 |
parents | ea1768c00d03 |
children | 23a57aad34c0 |
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.handler; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; import javax.servlet.DispatcherType; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.continuation.Continuation; import org.eclipse.jetty.continuation.ContinuationListener; import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.server.AsyncContinuation; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * RequestLogHandler. * This handler can be used to wrap an individual context for context logging. * * @org.apache.xbean.XBean */ public class RequestLogHandler extends HandlerWrapper { private static final Logger LOG = LoggerFactory.getLogger(RequestLogHandler.class); /* ------------------------------------------------------------ */ /* * @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) */ @Override public void handle(String target, final Request baseRequest, HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { AsyncContinuation continuation = baseRequest.getAsyncContinuation(); if (!continuation.isInitial()) { baseRequest.setDispatchTime(System.currentTimeMillis()); } try { super.handle(target, baseRequest, request, response); } finally { if (baseRequest.getDispatcherType().equals(DispatcherType.REQUEST)) { if (continuation.isAsync()) { if (continuation.isInitial()) continuation.addContinuationListener(new ContinuationListener() { public void onTimeout(Continuation continuation) { } public void onComplete(Continuation continuation) { log(baseRequest, (Response)response); } }); } else log(baseRequest, (Response)response); } } } /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStart() */ @Override protected void doStart() throws Exception { super.doStart(); startLog(); } /* ------------------------------------------------------------ */ /* * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStop() */ @Override protected void doStop() throws Exception { super.doStop(); stopLog(); } // from NCSARequestLog public String filename = null; private boolean extended = false; public long retainTime = 1000L*60*60*24*31; // 31 days private boolean _closeOut; public boolean preferProxiedForAddress = false; public String logDateFormat = "dd/MMM/yyyy:HH:mm:ss Z"; public Locale logLocale = Locale.getDefault(); public TimeZone timeZone = TimeZone.getTimeZone("GMT"); public boolean logLatency = false; public boolean logCookies = false; public boolean logServer = false; public boolean logDispatch = false; private transient OutputStream _out; private transient DateFormat dateFormat; private transient Writer _writer; /* ------------------------------------------------------------ */ /** * 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 synchronized void write(String log) throws IOException { 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('"'); } } private synchronized void startLog() 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; _writer = new OutputStreamWriter(_out); } private synchronized void stopLog() throws Exception { 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; } }