Return-Path: Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: (qmail 11132 invoked from network); 29 Oct 2008 21:42:04 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 29 Oct 2008 21:42:04 -0000 Received: (qmail 76723 invoked by uid 500); 29 Oct 2008 21:42:05 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 76652 invoked by uid 500); 29 Oct 2008 21:42:05 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 76641 invoked by uid 99); 29 Oct 2008 21:42:05 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 29 Oct 2008 14:42:05 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 29 Oct 2008 21:40:59 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id DA88823888A5; Wed, 29 Oct 2008 14:41:09 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r709018 - in /tomcat/trunk/java/org/apache/juli: AsyncFileHandler.java FileHandler.java Date: Wed, 29 Oct 2008 21:41:09 -0000 To: dev@tomcat.apache.org From: fhanik@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20081029214109.DA88823888A5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fhanik Date: Wed Oct 29 14:41:09 2008 New Revision: 709018 URL: http://svn.apache.org/viewvc?rev=709018&view=rev Log: Add asynchronous log handling, feature not yet complete. Need to figure out when to stop the logger thread (possible when there are no loggers) and also make sure the thread sleep/wakeup is bullet proof Added: tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java Modified: tomcat/trunk/java/org/apache/juli/FileHandler.java Added: tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java?rev=709018&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java (added) +++ tomcat/trunk/java/org/apache/juli/AsyncFileHandler.java Wed Oct 29 14:41:09 2008 @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.juli; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.LogRecord; +/** + * + * @author Filip Hanik + * + */ +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 RECORD_BATCH_COUNT = Integer.parseInt(System.getProperty("org.apache.juli.AsyncRecordBatchCount","100")); + + protected static ConcurrentLinkedQueue handlers = new ConcurrentLinkedQueue(); + protected static SignalAtomicLong recordCounter = new SignalAtomicLong(); + protected static LoggerThread logger = new LoggerThread(); + + static { + logger.start(); + } + + protected LogQueue queue = new LogQueue(); + protected boolean closed = false; + + public AsyncFileHandler() { + this(null,null,null); + } + + public AsyncFileHandler(String directory, String prefix, String suffix) { + super(directory, prefix, suffix); + open(); + } + + @Override + public void close() { + closed = true; + // TODO Auto-generated method stub + super.close(); + handlers.remove(this); + } + + @Override + protected void open() { + closed = false; + // TODO Auto-generated method stub + super.open(); + handlers.add(this); + } + + + @Override + public void publish(LogRecord record) { + if (!isLoggable(record)) { + return; + } + this.queue.offer(record); + } + + protected void publishInternal(LogRecord record) { + recordCounter.addAndGet(-1); + super.publish(record); + } + + @Override + protected void finalize() throws Throwable { + // TODO Auto-generated method stub + super.finalize(); + } + + public int getMaxRecords() { + return this.queue.max; + } + + public void setMaxRecords(int maxRecords) { + this.queue.max = maxRecords; + } + + public int getOverflowAction() { + return this.queue.type; + } + + public void setOverflowAction(int type) { + this.queue.type = type; + } + + protected static class SignalAtomicLong { + AtomicLong delegate = new AtomicLong(0); + ReentrantLock lock = new ReentrantLock(); + Condition cond = lock.newCondition(); + + public long addAndGet(long i) { + long prevValue = delegate.getAndAdd(i); + if (prevValue<=0 && i>0) { + lock.lock(); + try { + cond.signalAll(); + } finally { + lock.unlock(); + } + } + return delegate.get(); + } + + public void sleepUntilPositive() throws InterruptedException { + if (delegate.get()>0) return; + lock.lock(); + try { + if (delegate.get()>0) return; + cond.await(); + } finally { + lock.unlock(); + } + } + + public long get() { + return delegate.get(); + } + + } + + protected static class LoggerThread extends Thread { + protected boolean run = true; + public LoggerThread() { + this.setDaemon(true); + this.setName("AsyncFileHandlerWriter-"+System.identityHashCode(this)); + } + + public void run() { + while (run) { + try { + AsyncFileHandler.recordCounter.sleepUntilPositive(); + } catch (InterruptedException x) { + this.interrupted(); + continue; + } + AsyncFileHandler[] handlers = AsyncFileHandler.handlers.toArray(new AsyncFileHandler[0]); + for (int i=0; run && i { + protected int max = DEFAULT_MAX_RECORDS; + protected int type = OVERFLOW_DROP_LAST; + protected ConcurrentLinkedQueue delegate = new ConcurrentLinkedQueue(); + + public boolean offer(E e) { + if (delegate.size()>=max) { + switch (type) { + case OVERFLOW_DROP_LAST: + return false; + case OVERFLOW_DROP_FIRST: { + this.poll(); + if (delegate.offer(e)) { + recordCounter.addAndGet(1); + return true; + } else { + return false; + } + } + default: + return false; + } + } else { + if (delegate.offer(e)) { + recordCounter.addAndGet(1); + return true; + } else { + return false; + } + + } + } + + public E peek() { + return delegate.peek(); + } + + public E poll() { + // TODO Auto-generated method stub + return delegate.poll(); + } + + } + + +} Modified: tomcat/trunk/java/org/apache/juli/FileHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/juli/FileHandler.java?rev=709018&r1=709017&r2=709018&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/juli/FileHandler.java (original) +++ tomcat/trunk/java/org/apache/juli/FileHandler.java Wed Oct 29 14:41:09 2008 @@ -56,7 +56,7 @@ this.prefix = prefix; this.suffix = suffix; configure(); - open(); + openWriter(); } @@ -117,9 +117,9 @@ if (!date.equals(tsDate)) { synchronized (this) { if (!date.equals(tsDate)) { - close(); + closeWriter(); date = tsDate; - open(); + openWriter(); } } } @@ -154,6 +154,10 @@ * Close the currently open log file (if any). */ public void close() { + closeWriter(); + } + + protected void closeWriter() { try { if (writer == null) @@ -193,7 +197,7 @@ String tsString = ts.toString().substring(0, 19); date = tsString.substring(0, 10); - String className = FileHandler.class.getName(); + String className = this.getClass().getName(); //allow classes to override ClassLoader cl = Thread.currentThread().getContextClassLoader(); @@ -250,7 +254,11 @@ /** * Open the new log file for the date specified by date. */ - private void open() { + protected void open() { + openWriter(); + } + + protected void openWriter() { // Create the directory if necessary File dir = new File(directory); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org