From: fhanik Date: Mon, 14 Sep 2009 18:53:27 +0000 (+0000) Subject: Add in behavior and properties around async logging. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=a03710f697e2f0fc9b4a5732a085f3781d260818;p=tomcat7.0 Add in behavior and properties around async logging. Thinking about it, I think the exact same functionality can be achieved in a much simpler manner by just using a blocking queue. Will attempt that refactor next git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@814775 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/juli/AsyncFileHandler.java b/java/org/apache/juli/AsyncFileHandler.java index 8c13e1df2..8668b5335 100644 --- a/java/org/apache/juli/AsyncFileHandler.java +++ b/java/org/apache/juli/AsyncFileHandler.java @@ -30,7 +30,10 @@ public class AsyncFileHandler extends FileHandler { public static final int OVERFLOW_DROP_LAST = 1; public static final int OVERFLOW_DROP_FIRST = 2; - public static final int DEFAULT_MAX_RECORDS = 1000; + public static final int OVERFLOW_DROP_FLUSH = 3; + + public static final int OVERFLOW_DROP_TYPE = Integer.parseInt(System.getProperty("org.apache.juli.AsyncOverflowDropType","1")); + public static final int DEFAULT_MAX_RECORDS = Integer.parseInt(System.getProperty("org.apache.juli.AsyncMaxRecordCount","1000")); public static final int RECORD_BATCH_COUNT = Integer.parseInt(System.getProperty("org.apache.juli.AsyncRecordBatchCount","100")); protected static ConcurrentLinkedQueue handlers = new ConcurrentLinkedQueue(); @@ -42,7 +45,7 @@ public class AsyncFileHandler extends FileHandler { } protected LogQueue queue = new LogQueue(); - protected boolean closed = false; + protected volatile boolean closed = false; public AsyncFileHandler() { this(null,null,null); @@ -55,14 +58,18 @@ public class AsyncFileHandler extends FileHandler { @Override public void close() { + if (closed) return; closed = true; // TODO Auto-generated method stub super.close(); handlers.remove(this); + //empty the queue of log entries for this log + while (queue.poll()!=null) recordCounter.addAndGet(-1); } @Override protected void open() { + if(!closed) return; closed = false; // TODO Auto-generated method stub super.open(); @@ -108,14 +115,22 @@ public class AsyncFileHandler extends FileHandler { protected static class SignalAtomicLong { AtomicLong delegate = new AtomicLong(0); ReentrantLock lock = new ReentrantLock(); - Condition cond = lock.newCondition(); + Condition sleepUntilPositiveCond = lock.newCondition(); + Condition sleepUntilEmpty = lock.newCondition(); public long addAndGet(long i) { long prevValue = delegate.getAndAdd(i); if (prevValue<=0 && i>0) { lock.lock(); try { - cond.signalAll(); + sleepUntilPositiveCond.signalAll(); + } finally { + lock.unlock(); + } + } else if (prevValue>0 && delegate.get()<=0) { + lock.lock(); + try { + sleepUntilEmpty.signalAll(); } finally { lock.unlock(); } @@ -128,12 +143,24 @@ public class AsyncFileHandler extends FileHandler { lock.lock(); try { if (delegate.get()>0) return; - cond.await(); + sleepUntilPositiveCond.await(); } finally { lock.unlock(); } } + public void sleepUntilEmpty() throws InterruptedException { + if (delegate.get()<=0) return; + lock.lock(); + try { + if (delegate.get()<=0) return; + sleepUntilPositiveCond.await(); + } finally { + lock.unlock(); + } + + } + public long get() { return delegate.get(); } @@ -171,7 +198,7 @@ public class AsyncFileHandler extends FileHandler { protected static class LogQueue { protected int max = DEFAULT_MAX_RECORDS; - protected int type = OVERFLOW_DROP_LAST; + protected int type = OVERFLOW_DROP_TYPE; protected ConcurrentLinkedQueue delegate = new ConcurrentLinkedQueue(); public boolean offer(E e) { @@ -188,6 +215,19 @@ public class AsyncFileHandler extends FileHandler { return false; } } + case OVERFLOW_DROP_FLUSH: { + try { + recordCounter.sleepUntilEmpty(); + }catch (InterruptedException x) { + //no op - simply continue the operation + } + if (delegate.offer(e)) { + recordCounter.addAndGet(1); + return true; + } else { + return false; + } + } default: return false; } diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml index b024f3978..d32d19e73 100644 --- a/webapps/docs/config/systemprops.xml +++ b/webapps/docs/config/systemprops.xml @@ -325,6 +325,37 @@ +
+ + + + +

When the memory limit of records has been reached the system needs to determine what action to take. + Currently there are three actions that can be taken: +

    +
  • int OVERFLOW_DROP_LAST = 1 - the record that caused the overflow will be dropped and not logged
  • +
  • int OVERFLOW_DROP_FIRST = 2 - the record that is next in line to be logged will be dropped to make room for the latest record on the queue
  • +
  • int OVERFLOW_DROP_FLUSH = 3 - suspend the thread while the queue empties out and flushes the entries to the write buffer
  • +
+ Default value is 1 (OVERFLOW_DROP_LAST). +

+
+ + +

The max number of log records that the async logger will keep in memory. When this limit is reached and a new record is being logged by the + JULI framework the system will take an action based on the org.apache.juli.AsyncOverflowDropType setting. + The default value is 1000 records +

+
+ + +

+

+
+ +
+ +