diff src/org/eclipse/jetty/server/handler/RequestLogHandler.java @ 856:ea1768c00d03

remove NCSARequestLog and RequestLog
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 21 Sep 2016 00:19:26 -0600
parents 22a4e93ed20e
children 23a57aad34c0
line wrap: on
line diff
--- a/src/org/eclipse/jetty/server/handler/RequestLogHandler.java	Tue Sep 20 21:38:44 2016 -0600
+++ b/src/org/eclipse/jetty/server/handler/RequestLogHandler.java	Wed Sep 21 00:19:26 2016 -0600
@@ -18,18 +18,28 @@
 
 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.RequestLog;
 import org.eclipse.jetty.server.Response;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.util.component.AbstractLifeCycle;
@@ -45,126 +55,315 @@
  */
 public class RequestLogHandler extends HandlerWrapper
 {
-    private static final Logger LOG = LoggerFactory.getLogger(RequestLogHandler.class);
+	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();
+	}
+
+
 
-    private RequestLog _requestLog;
-    
-    /* ------------------------------------------------------------ */
-    /* 
-     * @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 (_requestLog != null && baseRequest.getDispatcherType().equals(DispatcherType.REQUEST))
-            {
-                if (continuation.isAsync())
-                {
-                    if (continuation.isInitial())
-                        continuation.addContinuationListener(new ContinuationListener()
-                        {
+	// 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);
 
-                            public void onTimeout(Continuation continuation)
-                            {
+			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(" - [");
 
-                            public void onComplete(Continuation continuation)
-                            {
-                                _requestLog.log(baseRequest, (Response)response);
-                            }
-                        });
-                }
-                else
-                    _requestLog.log(baseRequest, (Response)response);
-            }
-        }
-    }
+			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");
 
-    /* ------------------------------------------------------------ */
-    public void setRequestLog(RequestLog requestLog)
-    {
-        //are we changing the request log impl?
-        try
-        {
-            if (_requestLog != null)
-                _requestLog.stop();
-        }
-        catch (Exception e)
-        {
-            LOG.warn ("",e);
-        }
-        
-        _requestLog = requestLog;
-        
-        //if we're already started, then start our request log
-        try
-        {
-            if (isStarted() && (_requestLog != null))
-                _requestLog.start();
-        }
-        catch (Exception e)
-        {
-            throw new RuntimeException (e);
-        }
-    }
+			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);
 
-    /* ------------------------------------------------------------ */
-    public RequestLog getRequestLog() 
-    {
-        return _requestLog;
-    }
+			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);
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* 
-     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStart()
-     */
-    @Override
-    protected void doStart() throws Exception
-    {
-        if (_requestLog==null)
-        {
-            LOG.warn("!RequestLog");
-            _requestLog=new NullRequestLog();
-        }
-        super.doStart();
-        _requestLog.start();
-    }
+	/* ------------------------------------------------------------ */
+	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('"');
+		}
+	}
 
-    /* ------------------------------------------------------------ */
-    /* 
-     * @see org.eclipse.jetty.server.server.handler.HandlerWrapper#doStop()
-     */
-    @Override
-    protected void doStop() throws Exception
-    {
-        super.doStop();
-        _requestLog.stop();
-        if (_requestLog instanceof NullRequestLog)
-            _requestLog=null;
-    }
+	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;
 
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    /* ------------------------------------------------------------ */
-    private static class NullRequestLog extends AbstractLifeCycle implements RequestLog
-    {
-        public void log(Request request, Response response)
-        {            
-        }
-    }
-    
+		_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;
+	}
+	
 }