403570 Asynchronous Request Logging

This commit is contained in:
Greg Wilkins 2013-03-18 10:48:06 +11:00
parent 7ba6bb92b0
commit 63f2719938
4 changed files with 163 additions and 12 deletions

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.deploy.providers.ContextProvider;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.AsyncNCSARequestLog;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.NCSARequestLog;
@ -154,13 +155,13 @@ public class LikeJettyXml
login.setConfig(jetty_home + "/etc/realm.properties");
server.addBean(login);
NCSARequestLog requestLog = new NCSARequestLog(jetty_home + "/logs/jetty-yyyy_mm_dd.log");
NCSARequestLog requestLog = new AsyncNCSARequestLog();
requestLog.setFilename(jetty_home + "/logs/jetty-yyyy_mm_dd.log");
requestLog.setExtended(false);
requestLogHandler.setRequestLog(requestLog);
server.setStopAtShutdown(true);
server.setSendServerVersion(true);
server.start();

View File

@ -15,6 +15,7 @@
<Arg>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
<Set name="requestLog">
<!-- Use AsyncNCSARequestLog for improved request latency -->
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Set name="filename"><Property name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>

View File

@ -0,0 +1,130 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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 org.eclipse.jetty.util.BlockingArrayQueue;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/* ------------------------------------------------------------ */
/**
* An asynchronously writing NCSA Request Log
*/
public class AsyncNCSARequestLog extends NCSARequestLog
{
private static final Logger LOG = Log.getLogger(AsyncNCSARequestLog.class);
private final BlockingQueue<String> _queue;
private transient WriterThread _thread;
private boolean _warnedFull;
public AsyncNCSARequestLog()
{
this(null,null);
}
public AsyncNCSARequestLog(BlockingQueue<String> queue)
{
this(null,queue);
}
public AsyncNCSARequestLog(String filename)
{
this(filename,null);
}
public AsyncNCSARequestLog(String filename,BlockingQueue<String> queue)
{
super(filename);
if (queue==null)
queue=new BlockingArrayQueue<String>(1024);
_queue=queue;
}
private class WriterThread extends Thread
{
WriterThread()
{
setName("AsyncNCSARequestLog@"+Integer.toString(AsyncNCSARequestLog.this.hashCode(),16));
}
@Override
public void run()
{
while (isRunning())
{
try
{
String log = _queue.poll(10,TimeUnit.SECONDS);
if (log!=null)
AsyncNCSARequestLog.super.write(log);
while(!_queue.isEmpty())
{
log=_queue.poll();
if (log!=null)
AsyncNCSARequestLog.super.write(log);
}
}
catch (IOException e)
{
LOG.warn(e);
}
catch (InterruptedException e)
{
LOG.ignore(e);
}
}
}
}
@Override
protected synchronized void doStart() throws Exception
{
super.doStart();
_thread = new WriterThread();
_thread.start();
}
@Override
protected void doStop() throws Exception
{
_thread.interrupt();
_thread.join();
super.doStop();
_thread=null;
}
@Override
protected void write(String log) throws IOException
{
if (!_queue.offer(log))
{
if (_warnedFull)
LOG.warn("Log Queue overflow");
_warnedFull=true;
}
}
}

View File

@ -53,6 +53,14 @@ import org.eclipse.jetty.util.log.Logger;
public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
{
private static final Logger LOG = Log.getLogger(NCSARequestLog.class);
private static ThreadLocal<StringBuilder> _buffers = new ThreadLocal<StringBuilder>()
{
@Override
protected StringBuilder initialValue()
{
return new StringBuilder(256);
}
};
private String _filename;
private boolean _extended;
@ -461,7 +469,8 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
if (_fileOut == null)
return;
StringBuilder buf= new StringBuilder(256);
StringBuilder buf= _buffers.get();
buf.setLength(0);
if (_logServer)
{
@ -577,22 +586,29 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
}
buf.append(StringUtil.__LINE_SEPARATOR);
String log = buf.toString();
synchronized(this)
{
if (_writer==null)
return;
_writer.write(log);
_writer.flush();
}
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.
@ -662,7 +678,10 @@ public class NCSARequestLog extends AbstractLifeCycle implements RequestLog
else
_ignorePathMap = null;
_writer = new OutputStreamWriter(_out);
synchronized(this)
{
_writer = new OutputStreamWriter(_out);
}
super.doStart();
}