You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2014/07/07 18:46:36 UTC

svn commit: r1608511 - in /logging/log4j/log4j2/trunk: log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java src/changes/changes.xml

Author: ggregory
Date: Mon Jul  7 16:46:35 2014
New Revision: 1608511

URL: http://svn.apache.org/r1608511
Log:
[LOG4J2-696] RegexFilter does not match multiline log messages.

Modified:
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java
    logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java
    logging/log4j/log4j2/trunk/src/changes/changes.xml

Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java?rev=1608511&r1=1608510&r2=1608511&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java Mon Jul  7 16:46:35 2014
@@ -16,6 +16,9 @@
  */
 package org.apache.logging.log4j.core.filter;
 
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Comparator;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -25,20 +28,21 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.message.Message;
 
 /**
  * This filter returns the onMatch result if the message matches the regular expression.
  *
- * The "useRawMsg" attribute can be used to indicate whether the regular expression should be
- * applied to the result of calling Message.getMessageFormat (true) or Message.getFormattedMessage()
- * (false). The default is false.
+ * The "useRawMsg" attribute can be used to indicate whether the regular expression should be applied to the result of
+ * calling Message.getMessageFormat (true) or Message.getFormattedMessage() (false). The default is false.
  *
  */
 @Plugin(name = "RegexFilter", category = "Core", elementType = "filter", printObject = true)
 public final class RegexFilter extends AbstractFilter {
 
+    private static final int DEFAULT_PATTERN_FLAGS = 0;
     private final Pattern pattern;
     private final boolean useRawMessage;
 
@@ -50,13 +54,13 @@ public final class RegexFilter extends A
 
     @Override
     public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
-                         final Object... params) {
+            final Object... params) {
         return filter(msg);
     }
 
     @Override
     public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
-                         final Throwable t) {
+            final Throwable t) {
         if (msg == null) {
             return onMismatch;
         }
@@ -65,7 +69,7 @@ public final class RegexFilter extends A
 
     @Override
     public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
-                         final Throwable t) {
+            final Throwable t) {
         if (msg == null) {
             return onMismatch;
         }
@@ -97,24 +101,64 @@ public final class RegexFilter extends A
 
     /**
      * Create a Filter that matches a regular expression.
-     * @param regex The regular expression to match.
-     * @param useRawMsg If true, the raw message will be used, otherwise the formatted message will be used.
-     * @param match The action to perform when a match occurs.
-     * @param mismatch The action to perform when a mismatch occurs.
+     * 
+     * @param regex
+     *        The regular expression to match.
+     * @param patternFlags
+     *        An array of Stirngs where each String is a {@link Pattern#compile(String, int)} compilation flag.
+     * @param useRawMsg
+     *        If true, the raw message will be used, otherwise the formatted message will be used.
+     * @param match
+     *        The action to perform when a match occurs.
+     * @param mismatch
+     *        The action to perform when a mismatch occurs.
      * @return The RegexFilter.
+     * @throws IllegalAccessException
+     * @throws IllegalArgumentException
      */
     @PluginFactory
     public static RegexFilter createFilter(
-            @PluginAttribute("regex") final Pattern regex,
+            //@formatter:off
+            @PluginAttribute("regex") final String regex,
+            @PluginElement("PatternFlags") final String[] patternFlags,
             @PluginAttribute("useRawMsg") final Boolean useRawMsg,
-            @PluginAttribute("onMatch") final Result match,
-            @PluginAttribute("onMismatch") final Result mismatch) {
-
+            @PluginAttribute("onMatch") final Result match, 
+            @PluginAttribute("onMismatch") final Result mismatch) 
+            //@formatter:on
+            throws IllegalArgumentException, IllegalAccessException {
         if (regex == null) {
             LOGGER.error("A regular expression must be provided for RegexFilter");
             return null;
         }
-        return new RegexFilter(useRawMsg, regex, match, mismatch);
+        return new RegexFilter(useRawMsg, Pattern.compile(regex, toPatternFlags(patternFlags)), match, mismatch);
     }
 
+    private static int toPatternFlags(final String[] patternFlags) throws IllegalArgumentException,
+            IllegalAccessException {
+        if (patternFlags == null || patternFlags.length == 0) {
+            return DEFAULT_PATTERN_FLAGS;
+        }
+        final Field[] fields = Pattern.class.getDeclaredFields();
+        final Comparator<Field> comparator = new Comparator<Field>() {
+
+            @Override
+            public int compare(final Field f1, final Field f2) {
+                return f1.getName().compareTo(f2.getName());
+            }
+        };
+        Arrays.sort(fields, comparator);
+        final String[] fieldNames = new String[fields.length];
+        for (int i = 0; i < fields.length; i++) {
+            fieldNames[i] = fields[i].getName();
+        }
+        int flags = DEFAULT_PATTERN_FLAGS;
+        for (final String test : patternFlags) {
+            final int index = Arrays.binarySearch(fieldNames, test);
+            if (index >= 0) {
+                final Field field = fields[index];
+                flags |= field.getInt(Pattern.class);
+            }
+        }
+        return flags;
+    }
 }

Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java?rev=1608511&r1=1608510&r2=1608511&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/RegexFilterTest.java Mon Jul  7 16:46:35 2014
@@ -16,12 +16,16 @@
  */
 package org.apache.logging.log4j.core.filter;
 
-import java.util.regex.Pattern;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Filter.Result;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.config.plugins.util.TypeConverters;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
@@ -29,8 +33,6 @@ import org.apache.logging.log4j.status.S
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
-
 /**
  *
  */
@@ -41,29 +43,41 @@ public class RegexFilterTest {
     }
 
     @Test
-    public void testThresholds() {
-        RegexFilter filter = RegexFilter.createFilter(Pattern.compile(".* test .*"), false, null, null);
+    public void testThresholds() throws Exception {
+        RegexFilter filter = RegexFilter.createFilter(".* test .*", null, false, null, null);
         filter.start();
         assertTrue(filter.isStarted());
         assertSame(Filter.Result.NEUTRAL,
-            filter.filter(null, Level.DEBUG, null, "This is a test message", (Throwable) null));
+                filter.filter(null, Level.DEBUG, null, "This is a test message", (Throwable) null));
         assertSame(Filter.Result.DENY, filter.filter(null, Level.ERROR, null, "This is not a test", (Throwable) null));
-        LogEvent event = new Log4jLogEvent(null, null, null, Level.DEBUG, new SimpleMessage("Another test message"), null);
+        LogEvent event = new Log4jLogEvent(null, null, null, Level.DEBUG, new SimpleMessage("Another test message"),
+                null);
         assertSame(Filter.Result.NEUTRAL, filter.filter(event));
         event = new Log4jLogEvent(null, null, null, Level.ERROR, new SimpleMessage("test"), null);
         assertSame(Filter.Result.DENY, filter.filter(event));
-        filter = RegexFilter.createFilter((Pattern) TypeConverters.convert("* test *", Pattern.class, null), false, null, null);
+        filter = RegexFilter.createFilter(null, null, false, null, null);
         assertNull(filter);
     }
 
     @Test
-    public void testNoMsg() {
-        final RegexFilter filter = RegexFilter.createFilter(Pattern.compile(".* test .*"), false, null, null);
+    public void testDotAllPattern() throws Exception {
+        String singleLine = "test single line matches";
+        String multiLine = "test multi line matches\nsome more lines";
+        RegexFilter filter = RegexFilter.createFilter(".*line.*", new String[] { "DOTALL", "COMMENTS" }, false,
+                Filter.Result.DENY, Filter.Result.ACCEPT);
+        Result singleLineResult = filter.filter(null, null, null, singleLine, (Throwable) null);
+        Result multiLineResult = filter.filter(null, null, null, multiLine, (Throwable) null);
+        assertThat(singleLineResult, equalTo(Result.DENY));
+        assertThat(multiLineResult, equalTo(Result.DENY));
+    }
+
+    @Test
+    public void testNoMsg() throws Exception {
+        final RegexFilter filter = RegexFilter.createFilter(".* test .*", null, false, null, null);
         filter.start();
         assertTrue(filter.isStarted());
         assertSame(Filter.Result.DENY, filter.filter(null, Level.DEBUG, null, (String) null, (Throwable) null));
         assertSame(Filter.Result.DENY, filter.filter(null, Level.DEBUG, null, (Message) null, (Throwable) null));
         assertSame(Filter.Result.DENY, filter.filter(null, Level.DEBUG, null, null, (Object[]) null));
-
     }
 }

Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1608511&r1=1608510&r2=1608511&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Mon Jul  7 16:46:35 2014
@@ -22,6 +22,9 @@
   </properties>
   <body>
     <release version="2.0-???" date="2014-0M-DD" description="Bug fixes and enhancements">
+      <action issue="LOG4J2-696" dev="ggregory" type="add">
+        RegexFilter does not match multiline log messages.
+      </action>
       <action issue="LOG4J2-699" dev="rpopma" type="fix">
         PatternLayout manual page missing documentation on header/footer.
       </action>