You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2009/09/14 20:53:28 UTC
svn commit: r814775 - in /tomcat/trunk:
java/org/apache/juli/AsyncFileHandler.java
webapps/docs/config/systemprops.xml
Author: fhanik
Date: Mon Sep 14 18:53:27 2009
New Revision: 814775
URL: http://svn.apache.org/viewvc?rev=814775&view=rev
Log:
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
Modified:
tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java
tomcat/trunk/webapps/docs/config/systemprops.xml
Modified: tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java?rev=814775&r1=814774&r2=814775&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java (original)
+++ tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java Mon Sep 14 18:53:27 2009
@@ -30,7 +30,10 @@
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<FileHandler> handlers = new ConcurrentLinkedQueue<FileHandler>();
@@ -42,7 +45,7 @@
}
protected LogQueue<LogRecord> queue = new LogQueue<LogRecord>();
- protected boolean closed = false;
+ protected volatile boolean closed = false;
public AsyncFileHandler() {
this(null,null,null);
@@ -55,14 +58,18 @@
@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 @@
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 @@
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 @@
protected static class LogQueue<E> {
protected int max = DEFAULT_MAX_RECORDS;
- protected int type = OVERFLOW_DROP_LAST;
+ protected int type = OVERFLOW_DROP_TYPE;
protected ConcurrentLinkedQueue<E> delegate = new ConcurrentLinkedQueue<E>();
public boolean offer(E e) {
@@ -188,6 +215,19 @@
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;
}
Modified: tomcat/trunk/webapps/docs/config/systemprops.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/systemprops.xml?rev=814775&r1=814774&r2=814775&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/systemprops.xml (original)
+++ tomcat/trunk/webapps/docs/config/systemprops.xml Mon Sep 14 18:53:27 2009
@@ -325,6 +325,37 @@
</section>
+<section name="Logging">
+
+ <properties>
+
+ <property name="org.apache.juli.AsyncOverflowDropType">
+ <p>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:
+ <ul>
+ <li><code>int OVERFLOW_DROP_LAST = 1</code> - the record that caused the overflow will be dropped and not logged</li>
+ <li><code>int OVERFLOW_DROP_FIRST = 2</code> - the record that is next in line to be logged will be dropped to make room for the latest record on the queue</li>
+ <li><code>int OVERFLOW_DROP_FLUSH = 3</code> - suspend the thread while the queue empties out and flushes the entries to the write buffer</li>
+ </ul>
+ Default value is <code>1</code> (OVERFLOW_DROP_LAST).
+ </p>
+ </property>
+
+ <property name="org.apache.juli.AsyncMaxRecordCount">
+ <p>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 <code>org.apache.juli.AsyncOverflowDropType</code> setting.
+ The default value is <code>1000</code> records
+ </p>
+ </property>
+
+ <property name="org.apache.juli.AsyncRecordBatchCount">
+ <p>
+ </p>
+ </property>
+
+ </properties>
+
+</section>
<section name="Other">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org