[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.20-12-g5e93537

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Thu May 6 21:24:33 CEST 2010


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  5e93537ed06b334bd3f57f577f0545d598caae13 (commit)
      from  ad6b18f0229d4d221e284d0176484a52f9f00f49 (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=5e93537ed06b334bd3f57f577f0545d598caae13
http://github.com/ceki/logback/commit/5e93537ed06b334bd3f57f577f0545d598caae13

commit 5e93537ed06b334bd3f57f577f0545d598caae13
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Mon May 3 21:58:01 2010 +0200

    - upgrade to SLF4J 1.6.0-alpha2
    - added GEventEvaluator

diff --git a/logback-classic/pom.xml b/logback-classic/pom.xml
index 032c8c9..045663f 100644
--- a/logback-classic/pom.xml
+++ b/logback-classic/pom.xml
@@ -115,6 +115,14 @@
     </dependency>
 
     <dependency>
+      <groupId>org.codehaus.groovy</groupId>
+      <artifactId>groovy-all</artifactId>
+      <scope>compile</scope>
+      <optional>true</optional>
+    </dependency>
+
+
+    <dependency>
       <groupId>ch.qos.logback</groupId>
       <artifactId>logback-core</artifactId>
       <type>test-jar</type>
@@ -178,8 +186,18 @@
   </dependencies>
 
   <build>
-    <plugins>
 
+    <resources>
+      <resource>
+        <directory>src/main/groovy</directory>
+        <includes>
+          <include>**/EvaluatorTemplate.groovy</include>
+        </includes>
+      </resource>
+    </resources>
+
+  
+    <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
@@ -190,6 +208,21 @@
       </plugin>
 
       <plugin>
+        <groupId>org.codehaus.groovy.maven</groupId>
+        <artifactId>gmaven-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generateStubs</goal>
+              <goal>compile</goal>
+              <goal>generateTestStubs</goal>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-jar-plugin</artifactId>
         <configuration>
@@ -289,15 +322,14 @@ org.slf4j.test_osgi
                  config files). They won't be found by Bnd's analysis
                  of java code. -->
 
-            <!-- importing ch.qos.logback.classic.util is strange but
-                 is required for the OSGi integration tests to pass
-                 -->
             <Import-Package>
               sun.reflect;resolution:=optional, 
               javax.*;resolution:=optional,
               org.xml.*;resolution:=optional,
               ch.qos.logback.core.rolling, 
-              ch.qos.logback.core.rolling.helper,           
+              ch.qos.logback.core.rolling.helper,
+              org.codehaus.groovy.*;resolution:=optional,
+              groovy.lang.*;resolution:=optional,
               *
             </Import-Package>
 
diff --git a/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy b/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
new file mode 100644
index 0000000..a090124
--- /dev/null
+++ b/logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
@@ -0,0 +1,40 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.boolex
+
+import ch.qos.logback.classic.spi.ILoggingEvent
+
+import static ch.qos.logback.classic.Level.TRACE;
+import static ch.qos.logback.classic.Level.DEBUG;
+import static ch.qos.logback.classic.Level.INFO;
+import static ch.qos.logback.classic.Level.WARN;
+import static ch.qos.logback.classic.Level.ERROR;
+
+// WARNING
+// If this file is renamed, this should be reflected in
+// logback-classic/pom.xml  resources section.
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+public class EvaluatorTemplate implements IEvaluator {
+
+
+  boolean doEvaluate(ILoggingEvent event) {
+    ILoggingEvent e = event;
+    //EXPRESSION
+  }
+
+
+}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
new file mode 100644
index 0000000..72a7bad
--- /dev/null
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
@@ -0,0 +1,86 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+
+package ch.qos.logback.classic.boolex;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.boolex.EvaluationException;
+import ch.qos.logback.core.boolex.EventEvaluator;
+import ch.qos.logback.core.boolex.EventEvaluatorBase;
+import ch.qos.logback.core.util.FileUtil;
+import groovy.lang.*;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+/**
+ * @author Ceki G&uuml;lc&uuml;
+ */
+public class GEventEvaluator extends EventEvaluatorBase<ILoggingEvent> {
+
+  String expression;
+
+  IEvaluator delegateEvaluator;
+  Script script;
+
+  public String getExpression() {
+    return expression;
+  }
+
+  public void setExpression(String expression) {
+    this.expression = expression;
+  }
+
+  public void start() {
+    if (expression == null || expression.length() == 0) {
+      addError("Empty expression");
+      return;
+    } else {
+      addInfo("Expression to evaluate [" + expression + "]");
+    }
+
+
+    ClassLoader classLoader = getClass().getClassLoader();
+    String currentPackageName = this.getClass().getPackage().getName();
+    currentPackageName = currentPackageName.replace('.', '/');
+
+    String scriptText = FileUtil.resourceAsString(this, classLoader, currentPackageName + "/EvaluatorTemplate.groovy");
+    if(scriptText == null) {
+      return;
+    }
+
+    // insert the expression into script text
+    scriptText = scriptText.replace("//EXPRESSION", expression);
+
+    GroovyClassLoader gLoader = new GroovyClassLoader(classLoader);
+    try {
+      Class scriptClass = gLoader.parseClass(scriptText);
+
+      GroovyObject goo = (GroovyObject) scriptClass.newInstance();
+      delegateEvaluator = (IEvaluator) goo;
+
+    } catch (CompilationFailedException cfe) {
+      addError("Failed to compile expression [" + expression + "]", cfe);
+    } catch (Exception e) {
+      addError("Failed to compile expression [" + expression + "]", e);
+    }
+  }
+
+  public boolean evaluate(ILoggingEvent event) throws NullPointerException, EvaluationException {
+    if(delegateEvaluator == null) {
+      return false;
+    }
+    return delegateEvaluator.doEvaluate(event);
+  }
+
+
+}
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java
new file mode 100644
index 0000000..db79bf8
--- /dev/null
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/boolex/IEvaluator.java
@@ -0,0 +1,26 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2010, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.classic.boolex;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+
+/**
+ * An <b>internal</b> interface used by the GEventEvaluator.
+ * 
+ * @author Ceki G&uuml;c&uuml;
+ */
+public interface IEvaluator {
+  public boolean doEvaluate(ILoggingEvent event);
+}
+ 
\ No newline at end of file
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
index b6edbdb..a550040 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/ILoggingEvent.java
@@ -69,8 +69,15 @@ public interface ILoggingEvent extends DeferredProcessingAware {
 
   public Marker getMarker();
 
+  /**
+   * Returns the MDC map.
+   */
   public Map<String, String> getMDCPropertyMap();
 
+  /**
+   * Synonym for [@link #getMDCPropertyMap}.
+   */
+  public Map<String, String> getMdc();
   public long getTimeStamp();
 
   public void prepareForDeferredProcessing();
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
index 774c5fd..8cbf883 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java
@@ -312,6 +312,10 @@ public class LoggingEvent implements ILoggingEvent {
     return mdcPropertyMap;
   }
 
+  public Map<String, String> getMdc() {
+    return mdcPropertyMap;
+  }
+
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
index c55b281..d8228d2 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEventVO.java
@@ -149,7 +149,10 @@ public class LoggingEventVO implements ILoggingEvent, Serializable {
   public Map<String, String> getMDCPropertyMap() {
     return mdcPropertyMap;
   }
-
+  public Map<String, String> getMdc() {
+    return mdcPropertyMap;
+  }
+  
   public void prepareForDeferredProcessing() {
   }
 
diff --git a/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
index 9e6ee66..fe80bb7 100644
--- a/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
+++ b/logback-classic/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
@@ -40,7 +40,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
    * against. The value of this field is usually modified with each release.
    */
   // to avoid constant folding by the compiler, this field must *not* be final
-  public static String REQUESTED_API_VERSION = "1.5.11"; // !final
+  public static String REQUESTED_API_VERSION = "1.6"; // !final
 
   final static String NULL_CS_URL = CoreConstants.CODES_URL + "#null_CS";
 
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
new file mode 100644
index 0000000..5fe551f
--- /dev/null
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java
@@ -0,0 +1,147 @@
+package ch.qos.logback.classic.boolex;
+
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.boolex.EvaluationException;
+import ch.qos.logback.core.status.StatusChecker;
+import ch.qos.logback.core.util.StatusPrinter;
+import org.junit.Test;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+import org.slf4j.helpers.BogoPerf;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Ceki G&uuml;c&uuml;
+ */
+
+public class GEventEvaluatorTest {
+
+  LoggerContext context = new LoggerContext();
+  StatusChecker statusChecker = new StatusChecker(context);
+  int LEN = 100 * 1000;
+
+  Logger logger = context.getLogger(this.getClass());
+  Marker markerA = MarkerFactory.getMarker("A");
+
+  LoggingEvent makeEvent(String msg) {
+    return makeEvent(Level.DEBUG, msg, null, null);
+  }
+
+  LoggingEvent makeEvent(Level level, String msg, Throwable t, Object[] argArray) {
+    return new LoggingEvent(this.getClass().getName(), logger, level, msg, t, argArray);
+  }
+
+  void doEvaluateAndCheck(String expression, ILoggingEvent event, boolean expected) throws EvaluationException {
+    GEventEvaluator gee = new GEventEvaluator();
+    gee.setContext(context);
+    gee.setExpression(expression);
+    gee.start();
+
+    StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+    assertTrue(statusChecker.isErrorFree());
+
+
+    boolean result = gee.evaluate(event);
+    assertEquals(expected, result);
+  }
+
+  @Test
+  public void smoke() throws EvaluationException {
+    doEvaluateAndCheck("1==1", null, true);
+  }
+
+  @Test
+  public void event() throws EvaluationException {
+    ILoggingEvent event = makeEvent("x");
+    event.getLoggerContextVO();
+    doEvaluateAndCheck("e.message == 'x'", event, true);
+  }
+
+  @Test
+  public void msgRegex() throws EvaluationException {
+    LoggingEvent event = makeEvent("Hello world");
+    // partial match
+    doEvaluateAndCheck("e.message =~ /xyz|wor/", event, true);
+    // full match
+    doEvaluateAndCheck("e.message ==~ /xyz|wor/", event, false);
+  }
+
+  @Test
+  public void level() throws EvaluationException {
+    LoggingEvent event = makeEvent("x");
+    doEvaluateAndCheck("e.level == DEBUG", event, true);
+  }
+
+
+  @Test
+  public void nullMarker() throws EvaluationException {
+    LoggingEvent event = makeEvent("x");
+    doEvaluateAndCheck("e.marker?.name == 'YELLOW'", event, false);
+  }
+
+  @Test
+  public void marker() throws EvaluationException {
+    LoggingEvent event = makeEvent("x");
+    event.setMarker(markerA);
+    doEvaluateAndCheck("e.marker?.name == 'A'", event, true);
+  }
+
+  @Test
+  public void nullMDC() throws EvaluationException {
+    LoggingEvent event = makeEvent("x");
+    doEvaluateAndCheck("e.mdc?.get('key') == 'val'", event, false);
+  }
+
+  @Test
+  public void mdc() throws EvaluationException {
+    MDC.put("key", "val");
+    LoggingEvent event = makeEvent("x");
+    doEvaluateAndCheck("e.mdc['key'] == 'val'", event, true);
+    MDC.clear();
+  }
+
+
+  @Test
+  public void callerData() throws EvaluationException {
+    LoggingEvent event = makeEvent("x");
+    doEvaluateAndCheck("e.callerData.find{ it.className =~ /junit/ }", event, true);
+  }
+
+
+  double loop(GEventEvaluator gee) throws EvaluationException {
+    long start = System.nanoTime();
+    ILoggingEvent event = makeEvent("x");
+    for (int i = 0; i < LEN; i++) {
+      gee.evaluate(event);
+    }
+    long end = System.nanoTime();
+    return (end - start) / LEN;
+  }
+
+  @Test
+  public void perfTest() throws EvaluationException {
+    GEventEvaluator gee = new GEventEvaluator();
+    gee.setContext(context);
+    gee.setExpression("event.timeStamp < 100 && event.message != 'xx' ");
+    gee.start();
+
+    loop(gee);
+    loop(gee);
+    double avgDuration = loop(gee);
+
+    long referencePerf = 500;
+    BogoPerf.assertDuration(avgDuration, referencePerf,
+            CoreConstants.REFERENCE_BIPS);
+    System.out.println("Average duration " + avgDuration);
+  }
+
+}
\ No newline at end of file
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
index 68d17e3..57d293b 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/spi/PubLoggingEventVO.java
@@ -124,6 +124,10 @@ public class PubLoggingEventVO implements ILoggingEvent, Serializable {
     return mdcPropertyMap;
   }
 
+  public Map<String, String> getMdc() {
+    return mdcPropertyMap;
+  }
+
   public void prepareForDeferredProcessing() {
   }
 
diff --git a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
index d85dcda..58fa250 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/boolex/EventEvaluatorBase.java
@@ -22,7 +22,6 @@ abstract public class EventEvaluatorBase<E> extends ContextAwareBase implements
   boolean started;
 
   public String getName() {
-
     return name;
   }
 
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 4b99245..2b036b0 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
@@ -159,9 +159,9 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
         sendBuffer(eventObject);
       }
     } catch (EvaluationException ex) {
-      errorCount ++;
+      errorCount ++; 
       if (errorCount < CoreConstants.MAX_ERROR_COUNT) {
-        addError("SMTPAppender's EventEvaluator threw an Exception" + ex);
+        addError("SMTPAppender's EventEvaluator threw an Exception-", ex);
       }
     }
   }
@@ -425,7 +425,7 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
    */
   public String getCharsetEncoding() {
     return charsetEncoding;
-  }
+  } 
 
   /**
    * Set the character set encoding of the outgoing email messages. The default
diff --git a/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java b/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
index 80fe0c7..84e03af 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/util/FileUtil.java
@@ -13,28 +13,64 @@
  */
 package ch.qos.logback.core.util;
 
+import ch.qos.logback.core.spi.ContextAware;
+
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
 
 public class FileUtil {
 
 
-  public static boolean mustCreateParentDirectories(File file) {
+  static public boolean mustCreateParentDirectories(File file) {
     File parent = file.getParentFile();
-    if(parent != null && !parent.exists()) {
+    if (parent != null && !parent.exists()) {
       return true;
     } else {
       return false;
     }
   }
-  
-  public static boolean  createMissingParentDirectories(File file) {
+
+  static public boolean createMissingParentDirectories(File file) {
     File parent = file.getParentFile();
-    if(parent == null || parent.exists()) {
+    if (parent == null || parent.exists()) {
       throw new IllegalStateException(file + " should not have a null parent");
-    } 
-    if(parent.exists()) {
+    }
+    if (parent.exists()) {
       throw new IllegalStateException(file + " should not have existing parent directory");
-    } 
+    }
     return parent.mkdirs();
   }
+
+
+  static public String resourceAsString(ContextAware ca, ClassLoader classLoader, String resourceName) {
+    URL url = classLoader.getResource(resourceName);
+    if (url == null) {
+      ca.addError("Failed to find resource [" + resourceName + "]");
+      return null;
+    }
+
+    URLConnection urlConnection = null;
+    try {
+      urlConnection = url.openConnection();
+      urlConnection.setUseCaches(false);
+      InputStream is = urlConnection.getInputStream();
+      InputStreamReader isr = new InputStreamReader(is);
+      char[] buf = new char[128];
+      StringBuilder builder = new StringBuilder();
+      int count = -1;
+      while ((count = isr.read(buf, 0, buf.length)) != -1) {
+        builder.append(buf, 0, count);
+      }
+      isr.close();
+      is.close();
+      return builder.toString();
+    } catch (IOException e) {
+      ca.addError("Failled to open " + resourceName, e);
+    }
+    return null;
+  }
 }
diff --git a/logback-site/src/site/pages/manual/filters.html b/logback-site/src/site/pages/manual/filters.html
index d3b4b75..43d5e82 100644
--- a/logback-site/src/site/pages/manual/filters.html
+++ b/logback-site/src/site/pages/manual/filters.html
@@ -234,8 +234,8 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 &lt;/configuration></pre>
 
 
-    <h3><a name="evalutatorFilter"
-    href="#evalutatorFilter">EvaluatorFilter</a></h3>
+    <h2><a name="evalutatorFilter"
+    href="#evalutatorFilter">EvaluatorFilter</a></h2>
 
     <p><a
     href="../xref/ch/qos/logback/core/filter/EvaluatorFilter.html"><code>EvaluatorFilter</code></a>
@@ -250,18 +250,119 @@ public class SampleFilter extends Filter&gt;ILoggingEvent> {
 
     <p>The <code>EventEvaluator</code> is an abstract class and you
     can implement your own event evaluation logic by sub-classing
-    <code>EventEvaluator</code>. However, logback-classic also ships
-    with a concrete evaluator implementation called <a
+    <code>EventEvaluator</code>. 
+    </p>
+    
+
+    <!-- ======================== GEventEvaluator ========================= -->
+
+    <h3><a name="GEventEvaluator"
+    href="#GEventEvaluator">GEventEvaluator</a></h3>
+    
+    <p><a
+    href="../xref/ch/qos/logback/classic/boolex/GEventEvaluator.html">GEventEvaluator</a>
+    is a concrete <a
+    href="../xref/ch/qos/logback/core/boolex/EventEvaluator.html"><code>EventEvaluator</code></a>
+    implementation taking artibtrary Groovy language boolean
+    expressions as the evaluation criteria. It admits an arbitrary
+    boolean expression written in Groovy. We refer such groovy
+    language boolean expressions as "groovy evaulation
+    expressions". Groovy evaluation expressions enable hereto
+    unprecedented flexibility in event
+    filtering. <code>GEventEvaluator</code> requires the Groovy
+    runtime. Please see the <a
+    href="../setup.html#gEventEvaluator">corresponding section</a> of
+    the setup document.
+    </p>
+
+    <p>Evaluation expressions are compiled on-the-fly during the
+    interpretation of the configuration file. As a user, you do not
+    need to worry about the actual plumbing. However, it is your
+    reponsibility to ensure that the groovy-language expression is
+    valid.
+    </p>
+
+    <p>The evaluation expression acts on the current logging event,
+    logback automatically inserts the current logging event of type <a
+    href="../apidocs/ch/qos/logback/classic/spi/ILoggingEvent.html">ILoggingEvent.</a>
+    as a variable called 'event' and its shorthand 'e'. The variables
+    TRACE, DEBUG, INFO, WARN and ERROR are also exported into the
+    scope of the expression. Thus, "event.level == DEBUG" is a valid
+    groovy expression which will return <code>true</code> only if the
+    current logging event's level is equal to DEBUG.
+    </p>
+
+    <p>Here is a more complete example.</p>
+
+<pre class="prettyprint source">&lt;configuration>
+
+  &lt;appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <b>&lt;filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
+      &lt;evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> 
+        &lt;expression>
+           e.level>=WARN
+             &amp;amp;&amp;amp;  &lt;!-- Stands for &amp;&amp; in XML -->
+           !(e.mdc?.get("req.userAgent") ~= /Googlebot|msnbot|Yahoo/ )
+        &lt;/expression>
+      &lt;/evaluator>
+      &lt;OnMismatch>DENY&lt;/OnMismatch>
+      &lt;OnMatch>NEUTRAL&lt;/OnMatch>
+    &lt;/filter></b>
+    &lt;encoder>
+      &lt;pattern>
+        %-4relative [%thread] %-5level %logger - %msg%n
+      &lt;/pattern>
+    &lt;/encoder>
+  &lt;/appender>
+
+  &lt;root level="DEBUG">
+    &lt;appender-ref ref="STDOUT" />
+  &lt;/root>
+&lt;/configuration></pre>
+
+
+    <p>The above filter will let events of level WARN and higher go
+    through onto the console unless the error is generated by Web
+    crawlers associated with Google, MSN or Yahoo. It does so by
+    checking whether the MDC associated with the event contains a
+    value for "req.userAgent" matching the
+    <code>/Googlebot|msnbot|Yahoo/</code> regular expression. Note
+    that since the mdc map can be null, we are also using Groovy's <a
+    href="http://groovy.codehaus.org/Null+Object+Pattern">safe
+    derefencing opeator</a>, that is the .? operator. The equivalent
+    logic would have be much longer to express in Java.
+    </p>
+    
+    <p>If you are wondering how the identifier for the user agent was
+    inserted into the MDC under the 'req.userAgent' key, it behooves
+    us to mention that logback ships with a servlet filter named <a
+    href="mdc.html#mis"><code>MDCInsertingServletFilter</code></a>
+    designed for this purpose. It will be described in a later
+    chapter.
+    </p>
+
+    <!-- ==================== JaninoEventEvaluator ======================== -->
+    
+    <h3><a name="JaninoEventEvaluator"
+    href="#JaninoEventEvaluator">JaninoEventEvaluator</a></h3>
+    
+
+    <p>Logback-classic ships with another concrete
+    <code>EventEvaluator</code> implementation called <a
     href="../xref/ch/qos/logback/classic/boolex/JaninoEventEvaluator.html">JaninoEventEvaluator</a>
-    which takes artibtrary java language boolean expressions as the
+    which taking artibtrary java language boolean expressions as the
     evaluation criteria. We refer to such java language boolean
     expressions as "<em>evaulation expressions</em>". Evaluation
-    expressions enable hereto unprecedented flexibility in event
-    filtering. <code>JaninoEventEvaluator</code> requires the <a
+    expressions enable great flexibility in event
+    filtering.<code>JaninoEventEvaluator</code> requires the <a
     href="http://docs.codehaus.org/display/JANINO/Home">Janino
     library</a>. Please see the <a
     href="../setup.html#janino">corresponding section</a> of the setup
-    document.
+    document.  Compared to <code>JaninoEventEvaluator</code>,
+    <code>GEventEvaluator</code>, by virtue of the Groovy language, is
+    significantly more convenient to use, but
+    <code>JaninoEventEvaluator</code> will usually run (much) faster
+    for equivalent expressions.
     </p>
 
     <p>Evaluation expressions are compiled on-the-fly during the
@@ -555,6 +656,10 @@ java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfigura
     <p>In case you need to define additional matchers, you can do so by
     adding further <code>&lt;matcher></code> elements.</p>
 
+
+
+
+
     <!-- ================================================================ -->
     <!-- ===================== TURBO FILTER ============================= -->
     <!-- ================================================================ -->
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index 70d1eed..398366a 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -38,6 +38,11 @@
     by Ellen Strnod.
     </p>
 
+    <p>Added <a
+    href="manual/filters.html#GEventEvaluator">GEventEvaluator</a>
+    which processes boolean expression written in the Groovy language.
+    </p>
+
 
     <hr width="80%" align="center" />
 
diff --git a/logback-site/src/site/pages/setup.html b/logback-site/src/site/pages/setup.html
index 1b408c7..2922563 100644
--- a/logback-site/src/site/pages/setup.html
+++ b/logback-site/src/site/pages/setup.html
@@ -82,6 +82,16 @@
    JavaMail</a>, you need to place <em>mail.jar</em> on your class
    path.</p>
    
+
+   <h3><a name="gEventEvaluator"
+   href="#gEventEvaluator"><code>GEventEvaluator</code> requires the
+   Groovy runtime</a></h3>
+   
+   <p><code>GEventEvaluator</code> depends on the Groovy runtime. It
+   was tested with Groovy version 1.7.2.
+   </p>
+   
+
    <h3><a name="janino" href="#janino">Evaluators and more
    specifically <code>JaninoEvantEvaluator</code> require
    Janino</a></h3>
diff --git a/pom.xml b/pom.xml
index eb436ae..88076fc 100755
--- a/pom.xml
+++ b/pom.xml
@@ -43,7 +43,7 @@
   <properties>
     <!-- slf4j.version property is used below, in
          logback-classic/pom.xml and in setClasspath.cmd -->
-    <slf4j.version>1.6.0-RC0</slf4j.version>
+    <slf4j.version>1.6.0-alpha2</slf4j.version>
     <consolePlugin.version>1.1.0</consolePlugin.version>  
   </properties>
   
@@ -85,6 +85,11 @@
         <version>2.5.10</version>
       </dependency>
       <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-all</artifactId>
+        <version>1.7.2</version>
+      </dependency>
+      <dependency>
         <groupId>javax.mail</groupId>
         <artifactId>mail</artifactId>
         <version>1.4</version>

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

Summary of changes:
 logback-classic/pom.xml                            |   42 +++++-
 .../classic/boolex/EvaluatorTemplate.groovy        |   40 ++++++
 .../logback/classic/boolex/GEventEvaluator.java    |   86 ++++++++++++
 .../IEvaluator.java}                               |   17 ++-
 .../ch/qos/logback/classic/spi/ILoggingEvent.java  |    7 +
 .../ch/qos/logback/classic/spi/LoggingEvent.java   |    4 +
 .../ch/qos/logback/classic/spi/LoggingEventVO.java |    5 +-
 .../java/org/slf4j/impl/StaticLoggerBinder.java    |    2 +-
 .../classic/boolex/GEventEvaluatorTest.java        |  147 ++++++++++++++++++++
 .../qos/logback/classic/spi/PubLoggingEventVO.java |    4 +
 .../logback/core/boolex/EventEvaluatorBase.java    |    1 -
 .../ch/qos/logback/core/net/SMTPAppenderBase.java  |    6 +-
 .../java/ch/qos/logback/core/util/FileUtil.java    |   52 ++++++-
 logback-site/src/site/pages/manual/filters.html    |  121 +++++++++++++++-
 logback-site/src/site/pages/news.html              |    5 +
 logback-site/src/site/pages/setup.html             |   10 ++
 pom.xml                                            |    7 +-
 17 files changed, 521 insertions(+), 35 deletions(-)
 create mode 100644 logback-classic/src/main/groovy/ch/qos/logback/classic/boolex/EvaluatorTemplate.groovy
 create mode 100644 logback-classic/src/main/java/ch/qos/logback/classic/boolex/GEventEvaluator.java
 copy logback-classic/src/main/java/ch/qos/logback/classic/{pattern/LoggerConverter.java => boolex/IEvaluator.java} (62%)
 create mode 100644 logback-classic/src/test/java/ch/qos/logback/classic/boolex/GEventEvaluatorTest.java


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


More information about the logback-dev mailing list