[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch master updated. v_0.9.30-43-ge3e03a7

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Tue Oct 25 20:32:10 CEST 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, master has been updated
       via  e3e03a7dc7882acb47d724f4a53853ac1dfb3abf (commit)
      from  4fadcb4ae7e8bac392524a37e9ab1a3a8159b6fe (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=e3e03a7dc7882acb47d724f4a53853ac1dfb3abf
http://github.com/ceki/logback/commit/e3e03a7dc7882acb47d724f4a53853ac1dfb3abf

commit e3e03a7dc7882acb47d724f4a53853ac1dfb3abf
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Tue Oct 25 20:31:47 2011 +0200

    Context now offers an execution service

diff --git a/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java b/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
index e1a6edc..20e17c7 100644
--- a/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
+++ b/logback-access/src/main/java/ch/qos/logback/access/tomcat/LogbackValve.java
@@ -19,6 +19,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.*;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -86,6 +87,11 @@ public class LogbackValve extends ValveBase implements Lifecycle, Context,
   boolean started;
   boolean alreadySetLogbackStatusManager = false;
 
+    // 0 idle threads, 2 maximum threads, no idle waiting
+  ExecutorService executorService = new ThreadPoolExecutor(0, 2,
+          0L, TimeUnit.MILLISECONDS,
+          new LinkedBlockingQueue<Runnable>());
+
   public LogbackValve() {
     putObject(CoreConstants.EVALUATOR_MAP, new HashMap());
   }
@@ -262,6 +268,10 @@ public class LogbackValve extends ValveBase implements Lifecycle, Context,
     return fai.getFilterChainDecision(event);
   }
 
+  public ExecutorService getExecutorService() {
+    return  executorService;
+  }
+
   public String getName() {
     return name;
   }
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
index 9ffa390..3565e60 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeFilter.java
@@ -122,7 +122,7 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
   // reader lock.
   private void detachReconfigurationToNewThread() {
     addInfo("Detected change in [" + configurationWatchList.getCopyOfFileWatchList() + "]");
-    new ReconfiguringThread().start();
+    context.getExecutorService().submit(new ReconfiguringThread());
   }
 
   void updateNextCheck(long now) {
@@ -150,7 +150,7 @@ public class ReconfigureOnChangeFilter extends TurboFilter {
     this.refreshPeriod = refreshPeriod;
   }
 
-  class ReconfiguringThread extends Thread {
+  class ReconfiguringThread implements Runnable {
     public void run() {
       if (mainConfigurationURL == null) {
         addInfo("Due to missing top level configuration file, skipping reconfiguration");
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
index 0f39071..0fdf203 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
@@ -118,6 +119,10 @@ public class SMTPAppender_GreenTest {
     return (MimeMultipart) mm.getContent();
   }
 
+  void waitUntilEmailIsSent() throws InterruptedException {
+    lc.getExecutorService().shutdown();
+    lc.getExecutorService().awaitTermination(1000, TimeUnit.MILLISECONDS);
+  }
   @Test
   public void smoke() throws Exception {
     buildSMTPAppender();
@@ -127,6 +132,11 @@ public class SMTPAppender_GreenTest {
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
 
+     waitUntilEmailIsSent();
+//    synchronized (smtpAppender) {
+//      smtpAppender.wait();
+//    }
+
     StatusPrinter.print(lc);
     MimeMultipart mp = verify(TEST_SUBJECT);
     String body = GreenMailUtil.getBody(mp.getBodyPart(0));
@@ -145,6 +155,7 @@ public class SMTPAppender_GreenTest {
     MDC.clear();
     logger.error("en error", new Exception("an exception"));
 
+    waitUntilEmailIsSent();
     MimeMultipart mp = verify(TEST_SUBJECT);
     String body = GreenMailUtil.getBody(mp.getBodyPart(0));
     assertTrue(body.startsWith(HEADER.trim()));
@@ -160,6 +171,8 @@ public class SMTPAppender_GreenTest {
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
+
+    waitUntilEmailIsSent();
     MimeMultipart mp = verify(TEST_SUBJECT);
 
     // verify strict adherence to xhtml1-strict.dtd
@@ -188,6 +201,7 @@ public class SMTPAppender_GreenTest {
     }
     logger.error("en error", new Exception("an exception"));
 
+     waitUntilEmailIsSent();
     MimeMultipart mp = verify(TEST_SUBJECT);
 
     // verify strict adherence to xhtml1-strict.dtd
@@ -214,6 +228,7 @@ public class SMTPAppender_GreenTest {
     String msg2 = "world";
     logger.debug(msg2);
     logger.debug("invisible");
+    waitUntilEmailIsSent();
     MimeMultipart mp = verify(this.getClass().getName() + " - " + msg2);
     String body = GreenMailUtil.getBody(mp.getBodyPart(0));
     assertEquals("helloworld", body);
@@ -228,6 +243,7 @@ public class SMTPAppender_GreenTest {
     logger.debug("invisible2");
     String msg = "hello";
     logger.error(msg);
+    waitUntilEmailIsSent();
     MimeMultipart mp = verify(this.getClass().getName() + " - " + msg);
     String body = GreenMailUtil.getBody(mp.getBodyPart(0));
     assertEquals(msg, body);
@@ -243,8 +259,7 @@ public class SMTPAppender_GreenTest {
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
 
-    StatusPrinter.print(lc);
-
+    waitUntilEmailIsSent();
     MimeMessage[] mma = greenMail.getReceivedMessages();
     assertNotNull(mma);
     assertEquals(3, mma.length);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
index 13b9604..446fafb 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_SubethaSMTPTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertTrue;
 import java.io.ByteArrayOutputStream;
 import java.util.List;
 import java.util.Random;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import javax.mail.Part;
 import javax.mail.internet.MimeMessage;
@@ -57,7 +59,7 @@ public class SMTPAppender_SubethaSMTPTest {
   Wiser wiser;
 
   SMTPAppender smtpAppender;
-  LoggerContext lc = new LoggerContext();
+  LoggerContext loggerContext = new LoggerContext();
 
   static final String TEST_SUBJECT = "test subject";
   static final String HEADER = "HEADER\n";
@@ -75,7 +77,7 @@ public class SMTPAppender_SubethaSMTPTest {
 
   void buildSMTPAppender() throws Exception {
     smtpAppender = new SMTPAppender();
-    smtpAppender.setContext(lc);
+    smtpAppender.setContext(loggerContext);
     smtpAppender.setName("smtp");
     smtpAppender.setFrom("user at host.dom");
     smtpAppender.setSMTPHost("localhost");
@@ -118,7 +120,12 @@ public class SMTPAppender_SubethaSMTPTest {
       throw new RuntimeException(e);
     }
   }
-  
+
+  void waitUntilEmailIsSent() throws Exception {
+    loggerContext.getExecutorService().shutdown();
+    loggerContext.getExecutorService().awaitTermination(1000, TimeUnit.MILLISECONDS);
+  }
+
   private static String getBody(Part msg) {
     String all = getWholeMessage(msg);
     int i = all.indexOf("\r\n\r\n");
@@ -127,12 +134,15 @@ public class SMTPAppender_SubethaSMTPTest {
 
   @Test
   public void smoke() throws Exception {
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
+
+    waitUntilEmailIsSent();
+    System.out.println("*** "+((ThreadPoolExecutor)loggerContext.getExecutorService()).getCompletedTaskCount());
     List<WiserMessage> wiserMsgList = wiser.getMessages();
     
     assertNotNull(wiserMsgList);
@@ -151,13 +161,13 @@ public class SMTPAppender_SubethaSMTPTest {
 
   @Test
   public void html() throws Exception {
-    smtpAppender.setLayout(buildHTMLLayout(lc));
+    smtpAppender.setLayout(buildHTMLLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
-    
+    waitUntilEmailIsSent();
     List<WiserMessage> wiserMsgList = wiser.getMessages();
     
     assertNotNull(wiserMsgList);
@@ -185,14 +195,15 @@ public class SMTPAppender_SubethaSMTPTest {
    * the generated output will be rather short.
    */
   public void htmlLong() throws Exception {
-    smtpAppender.setLayout(buildHTMLLayout(lc));
+    smtpAppender.setLayout(buildHTMLLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     for (int i = 0; i < CoreConstants.TABLE_ROW_LIMIT * 3; i++) {
       logger.debug("hello " + i);
     }
     logger.error("en error", new Exception("an exception"));
+    waitUntilEmailIsSent();
     List<WiserMessage> wiserMsgList = wiser.getMessages();
     
     assertNotNull(wiserMsgList);
@@ -218,13 +229,13 @@ public class SMTPAppender_SubethaSMTPTest {
     smtpAppender.setUsername("x");
     smtpAppender.setPassword("x");
     
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
-
+    waitUntilEmailIsSent();
     List<WiserMessage> wiserMsgList = wiser.getMessages();
 
     assertNotNull(wiserMsgList);
@@ -252,14 +263,14 @@ public class SMTPAppender_SubethaSMTPTest {
     smtpAppender.setUsername("xx");
     smtpAppender.setPassword("xx");    
   
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
 
-    StatusPrinter.print(lc);
+    waitUntilEmailIsSent();
     List<WiserMessage> wiserMsgList = wiser.getMessages();
 
     assertNotNull(wiserMsgList);
@@ -277,14 +288,14 @@ public class SMTPAppender_SubethaSMTPTest {
     smtpAppender.setUsername("XXX at gmail.com");
     smtpAppender.setPassword("XXX");    
   
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("authenticatedGmailSTARTTLS");
+    Logger logger = loggerContext.getLogger("authenticatedGmailSTARTTLS");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
 
-    StatusPrinter.print(lc);
+    StatusPrinter.print(loggerContext);
   }
   
   @Test
@@ -298,25 +309,26 @@ public class SMTPAppender_SubethaSMTPTest {
     smtpAppender.setUsername("XXX at gmail.com");
     smtpAppender.setPassword("XXX");    
   
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.start();
-    Logger logger = lc.getLogger("authenticatedGmail_SSL");
+    Logger logger = loggerContext.getLogger("authenticatedGmail_SSL");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
 
-    StatusPrinter.print(lc);
+    StatusPrinter.print(loggerContext);
   }
 
   @Test
   public void testMultipleTo() throws Exception {
-    smtpAppender.setLayout(buildPatternLayout(lc));
+    smtpAppender.setLayout(buildPatternLayout(loggerContext));
     smtpAppender.addTo("Test <test at example.com>, other-test at example.com");
     smtpAppender.start();
-    Logger logger = lc.getLogger("test");
+    Logger logger = loggerContext.getLogger("test");
     logger.addAppender(smtpAppender);
     logger.debug("hello");
     logger.error("en error", new Exception("an exception"));
+    waitUntilEmailIsSent();
     List<WiserMessage> wiserMsgList = wiser.getMessages();
 
     assertNotNull(wiserMsgList);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
index d1df796..fd3247f 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/turbo/ReconfigureOnChangeTest.java
@@ -160,30 +160,6 @@ public class ReconfigureOnChangeTest {
     verify(expectedReconfigurations, mustBeErrorFree);
   }
 
-  // chose a test at random. These tests are rather long...
-  // check for deadlocks
-  @Test(timeout = 20000)
-  public void randomTest() throws JoranException, IOException, InterruptedException {
-    Random rand = new Random(System.currentTimeMillis());
-    switch (rand.nextInt(5)) {
-      case 0:
-        scan1();
-        break;
-      case 1:
-        scanWithFileInclusion();
-        break;
-      case 2:
-        scanWithResourceInclusion();
-        break;
-      case 3:
-        scan_lbclassic154();
-        break;
-      case 4:
-        gscan1();
-        break;
-    }
-  }
-
   // Tests whether ConfigurationAction is installing ReconfigureOnChangeFilter
   @Test
   public void scan1() throws JoranException, IOException, InterruptedException {
diff --git a/logback-core/src/main/java/ch/qos/logback/core/Context.java b/logback-core/src/main/java/ch/qos/logback/core/Context.java
index 463e4b7..cacfa2f 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/Context.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Context.java
@@ -14,6 +14,8 @@
 package ch.qos.logback.core;
 
 import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
 
 import ch.qos.logback.core.spi.PropertyContainer;
 import ch.qos.logback.core.status.StatusManager;
@@ -103,4 +105,13 @@ public interface Context extends PropertyContainer {
    */
   public Object getConfigurationLock();
 
+
+  /**
+   * Every context has an ExecutorService which be invoked to execute certain
+   * tasks in a separate thread.
+   *
+   * @return the executor for this context.
+   * @since 1.0.0
+   */
+  public ExecutorService getExecutorService();
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java b/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
index 4588344..0f61df4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/ContextBase.java
@@ -15,8 +15,10 @@ package ch.qos.logback.core;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.*;
 
 import ch.qos.logback.core.status.StatusManager;
+
 import static ch.qos.logback.core.CoreConstants.CONTEXT_NAME_KEY;
 
 public class ContextBase implements Context {
@@ -33,6 +35,11 @@ public class ContextBase implements Context {
 
   Object configurationLock = new Object();
 
+  // 0 idle threads, 2 maximum threads, no idle waiting
+  ExecutorService executorService = new ThreadPoolExecutor(0, 2,
+          0L, TimeUnit.MILLISECONDS,
+          new LinkedBlockingQueue<Runnable>());
+
   public StatusManager getStatusManager() {
     return sm;
   }
@@ -41,12 +48,11 @@ public class ContextBase implements Context {
    * Set the {@link StatusManager} for this context. Note that by default this
    * context is initialized with a {@link BasicStatusManager}. A null value for
    * the 'statusManager' argument is not allowed.
-   *
+   * <p/>
    * <p> A malicious attacker can set the status manager to a dummy instance,
    * disabling internal error reporting.
    *
-   * @param statusManager
-   *                the new status manager
+   * @param statusManager the new status manager
    */
   public void setStatusManager(StatusManager statusManager) {
     // this method was added in response to http://jira.qos.ch/browse/LBCORE-35
@@ -72,8 +78,8 @@ public class ContextBase implements Context {
    * @return
    */
   public String getProperty(String key) {
-    if(CONTEXT_NAME_KEY.equals(key))
-          return getName();
+    if (CONTEXT_NAME_KEY.equals(key))
+      return getName();
 
     return (String) this.propertyMap.get(key);
   }
@@ -103,15 +109,14 @@ public class ContextBase implements Context {
    * current name is the default context name, namely "default", or if the
    * current name and the old name are the same.
    *
-   * @throws IllegalStateException
-   *                 if the context already has a name, other than "default".
+   * @throws IllegalStateException if the context already has a name, other than "default".
    */
   public void setName(String name) throws IllegalStateException {
     if (name != null && name.equals(this.name)) {
       return; // idempotent naming
     }
     if (this.name == null
-        || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
+            || CoreConstants.DEFAULT_CONTEXT_NAME.equals(this.name)) {
       this.name = name;
     } else {
       throw new IllegalStateException("Context has been already given a name");
@@ -125,4 +130,8 @@ public class ContextBase implements Context {
   public Object getConfigurationLock() {
     return configurationLock;
   }
+
+  public ExecutorService getExecutorService() {
+    return  executorService;
+  }
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java b/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
index 1eec119..6e92600 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/helpers/CyclicBuffer.java
@@ -48,6 +48,15 @@ public class CyclicBuffer<E> {
     init(maxSize);
   }
 
+  public CyclicBuffer(CyclicBuffer<E> other) {
+   this.maxSize = other.maxSize;
+   ea = (E[]) new Object[maxSize];
+   System.arraycopy(other.ea, 0, this.ea, 0, maxSize);
+   this.last = other.last;
+   this.first = other.first;
+   this.numElems = other.numElems;
+  }
+
   @SuppressWarnings("unchecked")
   private void init(int maxSize) {
     this.maxSize = maxSize;
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index e6790a2..494afdb 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -177,12 +177,16 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
 
     String key = discriminator.getDiscriminatingValue(eventObject);
     long now = System.currentTimeMillis();
-    CyclicBuffer<E> cb = cbTracker.getOrCreate(key, now);
+    final CyclicBuffer<E> cb = cbTracker.getOrCreate(key, now);
     subAppend(cb, eventObject);
 
+    cb.asList();
+
     try {
       if (eventEvaluator.evaluate(eventObject)) {
-        sendBuffer(cb, eventObject);
+        // perform actual sending asynchronously
+        SenderRunnable senderRunnable = new SenderRunnable(new CyclicBuffer<E>(cb), eventObject);
+        context.getExecutorService().execute(senderRunnable);
       }
     } catch (EvaluationException ex) {
       errorCount++;
@@ -583,4 +587,17 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
     this.layout = layout;
   }
 
+  class SenderRunnable implements Runnable {
+
+    final  CyclicBuffer<E> cyclicBuffer;
+    final E e;
+
+    SenderRunnable(CyclicBuffer<E> cyclicBuffer, E e) {
+      this.cyclicBuffer = cyclicBuffer;
+      this.e = e;
+    }
+    public void run() {
+      sendBuffer(cyclicBuffer, e);
+    }
+  }
 }
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index 4334f4e..0d997d7 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -1696,9 +1696,10 @@ public interface TriggeringPolicy<E> extends LifeCycle {
    href="../xref/ch/qos/logback/classic/net/SMTPAppender.html"><code>SMTPAppender</code></a>
    accumulates logging events in one or more fixed-size buffers and
    sends the contents of the appropriate buffer in an email after a
-   user-specified event occurs.  By default, the email transmission is
-   triggered by a logging event of level ERROR or higher. Moreover, by
-   default, a single buffer is used for all events.
+   user-specified event occurs.  SMTP email transmission (sending) is
+   performed asynchronously. By default, the email transmission is
+   triggered by a logging event of level ERROR. Moreover, by default,
+   a single buffer is used for all events.
    </p>
 		
    <p>The various properties for <code>SMTPAppender</code> are
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index fa96c57..452d37f 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -54,6 +54,8 @@
     Alexandre Garnier.
     </p>
 
+    <p><code>SMTPAppender</code> now sends emails asynchronously.</p>
+
     <p>Investigation of <a
     href="http://jira.qos.ch/browse/LBCORE-224">LBCORE-224</a>
     reported by Cesar Alvarez Nunez points to bug in the JVM rather
diff --git a/pom.xml b/pom.xml
index 592a633..95d9c69 100755
--- a/pom.xml
+++ b/pom.xml
@@ -31,7 +31,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <!-- slf4j.version property is used below, in
          logback-classic/pom.xml and in setClasspath.cmd -->
-    <slf4j.version>1.6.2</slf4j.version>
+    <slf4j.version>1.6.3</slf4j.version>
     <junit.version>4.8.2</junit.version>
     <janino.version>2.5.10</janino.version>
     <scala.version>2.9.1</scala.version>

-----------------------------------------------------------------------

Summary of changes:
 .../ch/qos/logback/access/tomcat/LogbackValve.java |   10 +++
 .../classic/turbo/ReconfigureOnChangeFilter.java   |    4 +-
 .../classic/net/SMTPAppender_GreenTest.java        |   19 ++++++-
 .../classic/net/SMTPAppender_SubethaSMTPTest.java  |   60 ++++++++++++--------
 .../classic/turbo/ReconfigureOnChangeTest.java     |   24 --------
 .../src/main/java/ch/qos/logback/core/Context.java |   11 ++++
 .../main/java/ch/qos/logback/core/ContextBase.java |   25 ++++++---
 .../ch/qos/logback/core/helpers/CyclicBuffer.java  |    9 +++
 .../ch/qos/logback/core/net/SMTPAppenderBase.java  |   21 ++++++-
 logback-site/src/site/pages/manual/appenders.html  |    7 +-
 logback-site/src/site/pages/news.html              |    2 +
 pom.xml                                            |    2 +-
 12 files changed, 128 insertions(+), 66 deletions(-)


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list