Add some new filters and make the debug messages for configuration more concise
git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers@1029218 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/log4j2-api/src/main/java/org/apache/logging/log4j/Level.java b/log4j2-api/src/main/java/org/apache/logging/log4j/Level.java
index d987aa8..da075dc 100644
--- a/log4j2-api/src/main/java/org/apache/logging/log4j/Level.java
+++ b/log4j2-api/src/main/java/org/apache/logging/log4j/Level.java
@@ -18,13 +18,14 @@
/**
* Levels used for identifying the severity of an event. Levels are organized from most specific to least:<br>
- * OFF<br>
+ * OFF<br> (most specific)
* FATAL<br>
* ERROR<br>
* WARN<br>
* INFO<br>
* DEBUG<br>
* TRACE<br>
+ * ALL<br> (least specific)
*
* Typically, configuring a level in a filter or on a logger will cause logging events of that level and those
* that are more specific to pass through the filter.
@@ -65,24 +66,24 @@
}
/**
- * @doubt I really dislike the "greaterOrEqual" and "lessOrEqual" methods. I can never remember whether
- * the test compares this level to the passed in level or the other way around. As it stands, this
- * method is not intuitive as the name is greaterOrEqual but the test it does is <=.
+ * Compares this level against the level passed as an argument and returns true if this
+ * level is the same or more specific.
*
- * Compares the specified Level against this one.
* @param level The level to check.
- * @return True if the passed Level is more general or the same as this Level.
+ * @return True if the passed Level is more specific or the same as this Level.
*/
- public boolean greaterOrEqual(Level level) {
+ public boolean isAtLeastAsSpecificAs(Level level) {
return (intLevel <= level.intLevel);
}
/**
- * Compares the specified Level against this one.
+ * Compares this level against the level passed as an argument and returns true if this
+ * level is the same or more specific.
+ *
* @param level The level to check.
- * @return True if the passed Level is more general or the same as this Level.
+ * @return True if the passed Level is more specific or the same as this Level.
*/
- public boolean greaterOrEqual(int level) {
+ public boolean isAtLeastAsSpecificAs(int level) {
return (intLevel <= level);
}
diff --git a/log4j2-api/src/main/java/org/apache/logging/log4j/Marker.java b/log4j2-api/src/main/java/org/apache/logging/log4j/Marker.java
index c2ddf02..66e8c0a 100644
--- a/log4j2-api/src/main/java/org/apache/logging/log4j/Marker.java
+++ b/log4j2-api/src/main/java/org/apache/logging/log4j/Marker.java
@@ -24,42 +24,80 @@
*/
public class Marker implements Serializable {
- private static ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<String, Marker>();
+ private static ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<String, Marker>();
- public static Marker getMarker(String name) {
- return markerMap.putIfAbsent(name, new Marker(name));
- }
-
- public static Marker getMarker(String name, String parent) {
- Marker parentMarker = markerMap.get(parent);
- if (parentMarker == null) {
- throw new IllegalArgumentException("Parent Marker " + parent + " has not been defined");
+ public static Marker getMarker(String name) {
+ markerMap.putIfAbsent(name, new Marker(name));
+ return markerMap.get(name);
}
- return getMarker(name, parentMarker);
- }
- public static Marker getMarker(String name, Marker parent) {
- return markerMap.putIfAbsent(name, new Marker(name, parent));
- }
+ public static Marker getMarker(String name, String parent) {
+ Marker parentMarker = markerMap.get(parent);
+ if (parentMarker == null) {
+ throw new IllegalArgumentException("Parent Marker " + parent + " has not been defined");
+ }
+ return getMarker(name, parentMarker);
+ }
- private String name;
- private Marker parent;
+ public static Marker getMarker(String name, Marker parent) {
+ markerMap.putIfAbsent(name, new Marker(name, parent));
+ return markerMap.get(name);
+ }
- private Marker(String name) {
- this.name = name;
- }
+ private String name;
+ private Marker parent;
- private Marker(String name, Marker parent) {
- this.name = name;
- this.parent = parent;
- }
+ private Marker(String name) {
+ this.name = name;
+ }
- public String getName() {
- return this.name;
- }
+ private Marker(String name, Marker parent) {
+ this.name = name;
+ this.parent = parent;
+ }
- public Marker getParent() {
- return this.parent;
- }
+ public String getName() {
+ return this.name;
+ }
+ public Marker getParent() {
+ return this.parent;
+ }
+
+ public boolean isInstanceOf(Marker m) {
+ if (m == null) {
+ throw new IllegalArgumentException("A marker parameter is required");
+ }
+ Marker test = this;
+ do {
+ if (test == m) {
+ return true;
+ }
+ test = test.getParent();
+ } while (test != null);
+ return false;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Marker marker = (Marker) o;
+
+ if (name != null ? !name.equals(marker.name) : marker.name != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return name != null ? name.hashCode() : 0;
+ }
}
diff --git a/log4j2-api/src/main/java/org/apache/logging/log4j/internal/StatusConsoleListener.java b/log4j2-api/src/main/java/org/apache/logging/log4j/internal/StatusConsoleListener.java
index e9398fc..c5072dc 100644
--- a/log4j2-api/src/main/java/org/apache/logging/log4j/internal/StatusConsoleListener.java
+++ b/log4j2-api/src/main/java/org/apache/logging/log4j/internal/StatusConsoleListener.java
@@ -45,7 +45,7 @@
}
public void log(StatusData data) {
- if (data.getLevel().greaterOrEqual(level) && !filtered(data)) {
+ if (data.getLevel().isAtLeastAsSpecificAs(level) && !filtered(data)) {
System.out.println(data.getFormattedStatus());
}
}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/Log4jLogEvent.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/Log4jLogEvent.java
index e43e3d2..342cf99 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/Log4jLogEvent.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/Log4jLogEvent.java
@@ -100,6 +100,10 @@
return throwable;
}
+ public Marker getMarker() {
+ return marker;
+ }
+
/**
* @doubt Allows direct access to the map passed into the constructor, would allow appender
* or layout to manipulate event as seen by other appenders.
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
index e6e4cc3..442e87d 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java
@@ -1,6 +1,7 @@
package org.apache.logging.log4j.core;
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.message.Message;
import java.util.Map;
@@ -37,6 +38,12 @@
Message getMessage();
/**
+ * Get the Marker associated with the event.
+ * @return Marker
+ */
+ Marker getMarker();
+
+ /**
* Get thread name.
* @return thread name, may be null.
* @doubt guess this could go into a thread context object too.
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java
index bc1bb1e..c09ab3d 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java
@@ -141,4 +141,8 @@
return started;
}
+ public String toString() {
+ return name;
+ }
+
}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index 4489cfc..db7768d 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -34,7 +34,7 @@
* and then call getBytes which may use a configured encoding or the system
* default. OTOH, a Writer cannot print byte streams.
*/
-@Plugin(name="Console",type="Core",elementType="appender")
+@Plugin(name="Console",type="Core",elementType="appender",printObject=true)
public class ConsoleAppender extends OutputStreamAppender {
public static final String LAYOUT = "layout";
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
index 96b49b5..c2d8daa 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
@@ -31,7 +31,7 @@
/**
*
*/
-@Plugin(name="File",type="Core",elementType="appender")
+@Plugin(name="File",type="Core",elementType="appender",printObject=true)
public class FileAppender extends OutputStreamAppender {
public static final String FILE_NAME = "fileName";
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
index c1416de..21e0e0a 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
@@ -32,7 +32,7 @@
* This appender is primarily used for testing. Use in a real environment is discouraged as the
* List could eventually grow to cause an OutOfMemoryError.
*/
- @Plugin(name="List",type="Core",elementType="appender")
+ @Plugin(name="List",type="Core",elementType="appender",printObject=true)
public class ListAppender extends AppenderBase {
private List<LogEvent> events = new ArrayList<LogEvent>();
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
index dbdeabd..977e0fe 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/BaseConfiguration.java
@@ -422,17 +422,22 @@
}
parms[index] = array;
} else {
- Class parmClass = parmClasses[index];
+ Class parmClass = parmClasses[index];
+ boolean present = false;
for (Node child : children) {
- sb.append(child.toString());
PluginType childType = child.getType();
if (elem.value().equals(childType.getElementName()) ||
parmClass.isAssignableFrom(childType.getPluginClass())) {
+ sb.append(child.toString());
+ present = true;
used.add(child);
parms[index] = child.getObject();
break;
}
}
+ if (!present) {
+ sb.append("null");
+ }
}
}
}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
index dc73f91..32ee25a 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/LoggerConfig.java
@@ -46,7 +46,7 @@
/**
*
*/
-@Plugin(name="logger",type="Core")
+@Plugin(name="logger",type="Core", printObject=true)
public class LoggerConfig extends Filterable implements LogEventFactory {
private List<String> appenderRefs = new ArrayList<String>();
@@ -175,6 +175,10 @@
return new Log4jLogEvent(loggerName, marker, fqcn, level, data, t);
}
+ public String toString() {
+ return name == null || name.length() == 0 ? "root" : name;
+ }
+
@PluginFactory
public static LoggerConfig createLogger(@PluginAttr("additivity") String additivity,
@PluginAttr("level") String loggerLevel,
@@ -194,7 +198,7 @@
return new LoggerConfig(name, appenderRefs, filters, level, additive);
}
- @Plugin(name = "root", type = "Core")
+ @Plugin(name = "root", type = "Core", printObject=true)
public static class RootLogger extends LoggerConfig {
@PluginFactory
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java
new file mode 100644
index 0000000..e7e7ea0
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+@Plugin(name="StructuredData", type="Core", elementType="filter")
+public class DynamicThresholdFilter extends FilterBase {
+ private Map<String, Level> levelMap = new HashMap<String, Level>();
+ private Level defaultThreshold = Level.ERROR;
+ private String key;
+
+ private DynamicThresholdFilter(String key, Map<String, Level> pairs, Level defaultLevel,
+ Result onMatch, Result onMismatch) {
+ super(onMatch, onMismatch);
+ if (key == null) {
+ throw new NullPointerException("key cannot be null");
+ }
+ this.key = key;
+ this.levelMap = pairs;
+ this.defaultThreshold = defaultLevel;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
+ return filter(level);
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
+ return filter(level);
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+ return filter(level);
+ }
+
+ @Override
+ public Result filter(LogEvent event) {
+ return filter(event.getLevel());
+ }
+
+ private Result filter(Level level) {
+ Object value = ThreadContext.get(key);
+ if (value != null) {
+ Level ctxLevel = levelMap.get(value);
+ if (ctxLevel == null) {
+ ctxLevel = defaultThreshold;
+ }
+ return level.isAtLeastAsSpecificAs(ctxLevel) ? onMatch : onMismatch;
+ }
+ return Result.NEUTRAL;
+
+ }
+
+ @PluginFactory
+ public static DynamicThresholdFilter createFilter(@PluginAttr("key") String key,
+ @PluginAttr("pairs") ValueLevelPair[] pairs,
+ @PluginAttr("defaultThreshold") String level,
+ @PluginAttr("onmatch") String match,
+ @PluginAttr("onmismatch") String mismatch) {
+ Result onMatch = match == null ? null : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+ Map<String, Level> map = new HashMap<String, Level>();
+ for (ValueLevelPair pair : pairs) {
+ map.put(pair.getKey(), pair.getLevel());
+ }
+ Level l = Level.toLevel(level, Level.ERROR);
+ return new DynamicThresholdFilter(key, map, l, onMatch, onMismatch);
+ }
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/FilterBase.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/FilterBase.java
index ed93863..c439fcb 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/FilterBase.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/FilterBase.java
@@ -40,7 +40,7 @@
protected final Result onMismatch;
- protected static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger();
+ protected static final org.apache.logging.log4j.Logger logger = StatusLogger.getLogger();
protected static final String ON_MATCH = "onmatch";
protected static final String ON_MISMATCH = "onmismatch";
@@ -50,8 +50,8 @@
}
protected FilterBase(Result onMatch, Result onMismatch) {
- this.onMatch = onMatch == null ? Result.ACCEPT : onMatch;
- this.onMismatch = onMismatch == null ? Result.NEUTRAL : onMismatch;
+ this.onMatch = onMatch == null ? Result.NEUTRAL : onMatch;
+ this.onMismatch = onMismatch == null ? Result.DENY : onMismatch;
}
public void start() {
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java
index 00652f0..a434293 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java
@@ -36,12 +36,7 @@
private final List<Filter> filters;
private final boolean hasFilters;
- public Filters(Filter[] filters) {
- this.filters = filters == null || filters.length == 0 ? new ArrayList<Filter>() : Arrays.asList(filters);
- hasFilters = filters != null && filters.length > 0;
- }
-
- private Filters(List<Filter> filters) {
+ public Filters(List<Filter> filters) {
if (filters == null) {
this.filters = new ArrayList<Filter>();
this.hasFilters = false;
@@ -97,7 +92,8 @@
@PluginFactory
public static Filters createFilters(@PluginElement("filters") Filter[] filters) {
- return new Filters(filters);
+ List<Filter> f = filters == null || filters.length == 0 ? new ArrayList<Filter>() : Arrays.asList(filters);
+ return new Filters(f);
}
}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/KeyValuePair.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/KeyValuePair.java
new file mode 100644
index 0000000..31b420f
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/KeyValuePair.java
@@ -0,0 +1,56 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+/**
+ *
+ */
+@Plugin(name="KeyValuePair", type="Core", printObject=true)
+public class KeyValuePair {
+
+ private final String key;
+ private final String value;
+
+ public KeyValuePair(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ @PluginFactory
+ public static KeyValuePair createPair(@PluginAttr("key") String key,
+ @PluginAttr("value") String value) {
+
+ return new KeyValuePair(key, value);
+ }
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java
deleted file mode 100644
index 59e30a7..0000000
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MDCFilter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.logging.log4j.core.filter;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttr;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.message.Message;
-
-/**
- *
- */
-@Plugin(name="MDC", type="Core", elementType="filter")
-public class MDCFilter extends FilterBase {
- private final String key;
- private final String value;
-
- private static final String KEY = "key";
- private static final String VALUE = "value";
-
- public MDCFilter(String key, String value, Result onMatch, Result onMismatch) {
- super(onMatch, onMismatch);
- if (key == null) {
- throw new NullPointerException("key cannot be null");
- }
- if (value == null) {
- throw new NullPointerException("value cannot be null");
- }
- this.key = key;
- this.value = value;
- }
-
- public String getKey() {
- return this.key;
- }
-
- public String getValue() {
- return this.value;
- }
- public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
- return filter(ThreadContext.get(key));
- }
-
- public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
- return filter(ThreadContext.get(key));
- }
-
- public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
- return filter(ThreadContext.get(key));
- }
-
- @Override
- public Result filter(LogEvent event) {
- return filter(event.getContextMap().get(key));
- }
-
- private Result filter(Object val) {
- return this.value.equals(val) ? onMatch : onMismatch;
- }
-
- @PluginFactory
- public static MDCFilter createFilter(@PluginAttr("key") String key,
- @PluginAttr("value") String value,
- @PluginAttr("onmatch") String match,
- @PluginAttr("onmismatch") String mismatch) {
- Result onMatch = match == null ? null : Result.valueOf(match);
- Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
- return new MDCFilter(key, value, onMatch, onMismatch);
- }
-}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java
new file mode 100644
index 0000000..023c79b
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/MarkerFilter.java
@@ -0,0 +1,82 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+
+/**
+ * This filter returns the onMatch result if the marker in the LogEvent is the same as or has the
+ * configured marker as a parent.
+ *
+ */
+@Plugin(name="Marker", type="Core", elementType="filter")
+public class MarkerFilter extends FilterBase {
+
+ private static final String LEVEL = "level";
+
+ private final Marker marker;
+
+ private MarkerFilter(Marker marker, Result onMatch, Result onMismatch) {
+ super(onMatch, onMismatch);
+ this.marker = marker;
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
+ return filter(marker);
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
+ return filter(marker);
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+ return filter(marker);
+ }
+
+ @Override
+ public Result filter(LogEvent event) {
+ return filter(event.getMarker());
+ }
+
+ private Result filter(Marker marker) {
+ return marker != null && marker.isInstanceOf(this.marker) ? onMatch : onMismatch;
+ }
+
+ @PluginFactory
+ public static MarkerFilter createFilter(@PluginAttr("marker") String marker,
+ @PluginAttr("onMatch") String match,
+ @PluginAttr("onMismatch") String mismatch) {
+
+ if (marker == null) {
+ logger.error("A marker must be provided for MarkerFilter");
+ return null;
+ }
+ Marker m = Marker.getMarker(marker);
+ Result onMatch = match == null ? null : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+
+ return new MarkerFilter(m, onMatch, onMismatch);
+ }
+
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java
new file mode 100644
index 0000000..dc7c76d
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java
@@ -0,0 +1,96 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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.
+ *
+ */
+@Plugin(name="Regex", type="Core", elementType="filter")
+public class RegexFilter extends FilterBase {
+
+ private final Pattern pattern;
+ private final boolean useRawMessage;
+
+ private RegexFilter(boolean raw, Pattern pattern, Result onMatch, Result onMismatch) {
+ super(onMatch, onMismatch);
+ this.pattern = pattern;
+ this.useRawMessage = raw;
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
+ return filter(msg);
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
+ return filter(msg.toString());
+ }
+
+ public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+ String text = useRawMessage ? msg.getMessageFormat() : msg.getFormattedMessage();
+ return filter(text);
+ }
+
+ @Override
+ public Result filter(LogEvent event) {
+ String text = useRawMessage ? event.getMessage().getMessageFormat() : event.getMessage().getFormattedMessage();
+ return filter(text);
+ }
+
+ private Result filter(String msg) {
+ if (msg == null) {
+ return onMismatch;
+ }
+ Matcher m = pattern.matcher(msg);
+ return m.matches() ? onMatch : onMismatch;
+ }
+
+ @PluginFactory
+ public static RegexFilter createFilter(@PluginAttr("regex") String regex,
+ @PluginAttr("useRawMsg") String useRawMsg,
+ @PluginAttr("onMatch") String match,
+ @PluginAttr("onMismatch") String mismatch) {
+
+ if (regex == null) {
+ logger.error("A regular expression must be provided for RegexFilter");
+ return null;
+ }
+ boolean raw = useRawMsg == null ? false : Boolean.parseBoolean(useRawMsg);
+ Pattern pattern = Pattern.compile(regex);
+ Result onMatch = match == null ? null : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+
+ return new RegexFilter(raw, pattern, onMatch, onMismatch);
+ }
+
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java
new file mode 100644
index 0000000..fe187fb
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/StructuredDataFilter.java
@@ -0,0 +1,120 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+@Plugin(name="StructuredData", type="Core", elementType="filter")
+public class StructuredDataFilter extends FilterBase {
+ private final Map<String, Object> map;
+
+ private final boolean isAnd;
+
+ private StructuredDataFilter(Map<String, Object> map, boolean oper, Result onMatch, Result onMismatch) {
+ super(onMatch, onMismatch);
+ if (map == null) {
+ throw new NullPointerException("key cannot be null");
+ }
+ this.isAnd = oper;
+ this.map = map;
+ }
+
+ @Override
+ public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+ if (msg instanceof StructuredDataMessage) {
+ return filter((StructuredDataMessage)msg);
+ }
+ return Result.NEUTRAL;
+ }
+
+ @Override
+ public Result filter(LogEvent event) {
+ Message msg = event.getMessage();
+ if (msg instanceof StructuredDataMessage) {
+ return filter((StructuredDataMessage) msg);
+ }
+ return Result.NEUTRAL;
+ }
+
+ private Result filter(StructuredDataMessage msg) {
+ boolean match = false;
+ for (String key : map.keySet()) {
+ if (key.equalsIgnoreCase("id")) {
+ match = map.get(key).equals(msg.getId().toString());
+ } else if (key.equalsIgnoreCase("id.name")) {
+ match = map.get(key).equals(msg.getId().getName());
+ } else if (key.equalsIgnoreCase("type")) {
+ match = map.get(key).equals(msg.getType());
+ } else if (key.equalsIgnoreCase("message")) {
+ match = map.get(key).equals(msg.getFormattedMessage().toString());
+ } else {
+ String data = msg.getData().get(key).toString();
+ match = map.get(key).equals(data);
+ }
+ if ((!isAnd && match) || (isAnd && !match)) {
+ break;
+ }
+ }
+ return match ? onMatch : onMismatch;
+ }
+
+ @PluginFactory
+ public static StructuredDataFilter createFilter(@PluginAttr("pairs") KeyValuePair[] pairs,
+ @PluginAttr("operator") String oper,
+ @PluginAttr("onmatch") String match,
+ @PluginAttr("onmismatch") String mismatch) {
+ if (pairs == null || pairs.length == 0) {
+ logger.error("keys and values must be specified for the ThreadContextMapFilter");
+ }
+ Map<String, Object> map = new HashMap<String, Object>();
+ for (KeyValuePair pair : pairs) {
+ String key = pair.getKey();
+ if (key == null) {
+ logger.error("A null key is not valid in StructuredDataFilter");
+ continue;
+ }
+ String value = pair.getValue();
+ if (value == null) {
+ logger.error("A null value for key " + key + " is not allowed in StructuredDataFilter");
+ continue;
+ }
+ map.put(pair.getKey(), pair.getValue());
+ }
+ if (map.size() == 0) {
+ logger.error("StructuredDataFilter is not configured with any valid key value pairs");
+ return null;
+ }
+ boolean isAnd = oper == null || !oper.equalsIgnoreCase("or");
+ Result onMatch = match == null ? null : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+ return new StructuredDataFilter(map, isAnd, onMatch, onMismatch);
+ }
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
new file mode 100644
index 0000000..c7ab503
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilter.java
@@ -0,0 +1,119 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+@Plugin(name="ThreadContextMap", type="Core", elementType="filter")
+public class ThreadContextMapFilter extends FilterBase {
+ private final Map<String, Object> map;
+
+ private final boolean isAnd;
+
+ public ThreadContextMapFilter(Map<String, Object> pairs, boolean oper, Result onMatch, Result onMismatch) {
+ super(onMatch, onMismatch);
+ this.map = pairs;
+ this.isAnd = oper;
+ }
+
+ @Override
+ public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
+ return filter();
+ }
+
+ @Override
+ public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
+ return filter();
+ }
+
+ @Override
+ public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
+ return filter();
+ }
+
+ private Result filter() {
+ boolean match = false;
+ for (String key : map.keySet()) {
+ match = map.get(key).equals(ThreadContext.get(key));
+ if ((!isAnd && match) || (isAnd && !match)) {
+ break;
+ }
+ }
+ return match ? onMatch : onMismatch;
+ }
+
+ @Override
+ public Result filter(LogEvent event) {
+ Map<String, Object> ctx = event.getContextMap();
+ boolean match = false;
+ for (String key : map.keySet()) {
+ match = map.get(key).equals(ctx.get(key));
+ if ((!isAnd && match) || (isAnd && !match)) {
+ break;
+ }
+ }
+ return match ? onMatch : onMismatch;
+ }
+
+ @PluginFactory
+ public static ThreadContextMapFilter createFilter(@PluginElement("pairs") KeyValuePair[] pairs,
+ @PluginAttr("operator") String oper,
+ @PluginAttr("onmatch") String match,
+ @PluginAttr("onmismatch") String mismatch) {
+ if (pairs == null || pairs.length == 0) {
+ logger.error("key and value pairs must be specified for the ThreadContextMapFilter");
+ return null;
+ }
+ Map<String, Object> map = new HashMap<String, Object>();
+ for (KeyValuePair pair : pairs) {
+ String key = pair.getKey();
+ if (key == null) {
+ logger.error("A null key is not valid in ThreadContextMapFilter");
+ continue;
+ }
+ String value = pair.getValue();
+ if (value == null) {
+ logger.error("A null value for key " + key + " is not allowed in ThreadContextMapFilter");
+ continue;
+ }
+ map.put(pair.getKey(), pair.getValue());
+ }
+ if (map.size() == 0) {
+ logger.error("ThreadContextMapFilter is not configured with any valid key value pairs");
+ return null;
+ }
+ boolean isAnd = oper == null || !oper.equalsIgnoreCase("or");
+ Result onMatch = match == null ? null : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+ return new ThreadContextMapFilter(map, isAnd, onMatch, onMismatch);
+ }
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java
index 54f9766..835e8aa 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ThresholdFilter.java
@@ -40,7 +40,7 @@
private final Level level;
- public ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
+ private ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
super(onMatch, onMismatch);
this.level = level;
}
@@ -63,7 +63,7 @@
}
private Result filter(Level level) {
- return this.level.greaterOrEqual(level) ? onMatch : onMismatch;
+ return level.isAtLeastAsSpecificAs(this.level) ? onMatch : onMismatch;
}
@PluginFactory
@@ -71,8 +71,8 @@
@PluginAttr("onMatch") String match,
@PluginAttr("onMismatch") String mismatch) {
Level level = loggerLevel == null ? Level.ERROR : Level.toLevel(loggerLevel.toUpperCase());
- Result onMatch = match == null ? null : Result.valueOf(match);
- Result onMismatch = mismatch == null ? null : Result.valueOf(mismatch);
+ Result onMatch = match == null ? Result.NEUTRAL : Result.valueOf(match);
+ Result onMismatch = mismatch == null ? Result.DENY : Result.valueOf(mismatch);
return new ThresholdFilter(level, onMatch, onMismatch);
}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ValueLevelPair.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ValueLevelPair.java
new file mode 100644
index 0000000..4c9fc89
--- /dev/null
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/ValueLevelPair.java
@@ -0,0 +1,53 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+/**
+ *
+ */
+@Plugin(name="ValueLevelPair", type="Core")
+public class ValueLevelPair {
+
+ private String key;
+ private Level level;
+
+ public ValueLevelPair(String key, Level level) {
+ this.key = key;
+ this.level = level;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ @PluginFactory
+ public static ValueLevelPair createPair(@PluginAttr("key") String key,
+ @PluginAttr("threshold") String value) {
+
+ Level level = Level.toLevel(value);
+ return new ValueLevelPair(key, level);
+ }
+}
diff --git a/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java b/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
index 0adc984..372b580 100644
--- a/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
+++ b/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
@@ -386,7 +386,7 @@
* Philip E. Margolis' highly recommended book "C -- a Software
* Engineering Approach", ISBN 0-387-97389-3.
*/
-@Plugin(name="PatternLayout",type="Core",elementType="layout")
+@Plugin(name="PatternLayout",type="Core",elementType="layout",printObject=true)
public class PatternLayout extends LayoutBase {
/**
* Default pattern string for log output. Currently set to the
@@ -492,6 +492,10 @@
return new PatternParser(KEY);
}
+ public String toString() {
+ return "PatternLayout(" + conversionPattern + ")";
+ }
+
@PluginFactory
public static PatternLayout createLayout(@PluginAttr("pattern") String pattern,
@PluginAttr("charset") String charset) {
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/config/XMLConfigurationTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/config/XMLConfigurationTest.java
index 09a9257..530063f 100644
--- a/log4j2-core/src/test/java/org/apache/logging/log4j/core/config/XMLConfigurationTest.java
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/config/XMLConfigurationTest.java
@@ -22,15 +22,13 @@
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.filter.MDCFilter;
-import org.apache.logging.log4j.internal.StatusData;
+import org.apache.logging.log4j.core.filter.ThreadContextMapFilter;
import org.apache.logging.log4j.internal.StatusLogger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertTrue;
@@ -77,7 +75,7 @@
assertTrue("number of filters - " + filterCount, filterCount == 1);
Iterator<Filter> iter = l.getFilters();
Filter filter = iter.next();
- assertTrue(filter instanceof MDCFilter);
+ assertTrue(filter instanceof ThreadContextMapFilter);
Map<String, Appender> appenders = l.getAppenders();
assertNotNull(appenders);
assertTrue("number of appenders = " + appenders.size(), appenders.size() == 1);
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java
new file mode 100644
index 0000000..22db330
--- /dev/null
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Log4jLogEvent;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class DynamicThresholdFilterTest {
+
+ @Test
+ public void testFilter() {
+ ThreadContext.put("userid", "testuser");
+ ThreadContext.put("organization", "apache");
+ ValueLevelPair[] pairs = new ValueLevelPair[] { new ValueLevelPair("testuser", Level.DEBUG),
+ new ValueLevelPair("JohnDoe", Level.WARN)};
+ DynamicThresholdFilter filter = DynamicThresholdFilter.createFilter("userid", pairs, "ERROR", null, null);
+ filter.start();
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ assertTrue(filter.filter(null, Level.ERROR, null, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ ThreadContext.clear();
+ ThreadContext.put("userid", "JohnDoe");
+ ThreadContext.put("organization", "apache");
+ LogEvent event = new Log4jLogEvent(null, null, null, Level.DEBUG, new SimpleMessage("Test"), null);
+ assertTrue(filter.filter(event) == Filter.Result.DENY);
+ event = new Log4jLogEvent(null, null, null, Level.ERROR, new SimpleMessage("Test"), null);
+ assertTrue(filter.filter(event) == Filter.Result.NEUTRAL);
+ ThreadContext.clear();
+ }
+}
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/MarkerFilterTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/MarkerFilterTest.java
new file mode 100644
index 0000000..153eb53
--- /dev/null
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/MarkerFilterTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Log4jLogEvent;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class MarkerFilterTest {
+
+ @Test
+ public void testMarkers() {
+ Marker parent = Marker.getMarker("Parent");
+ Marker child = Marker.getMarker("Child", parent);
+ Marker grandChild = Marker.getMarker("GrandChild", child);
+ Marker sibling = Marker.getMarker("Sibling", parent);
+ Marker stranger = Marker.getMarker("Stranger");
+ MarkerFilter filter = MarkerFilter.createFilter("Parent", null, null);
+ filter.start();
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, null, stranger, null, (Throwable)null) == Filter.Result.DENY);
+ assertTrue(filter.filter(null, null, child, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ LogEvent event = new Log4jLogEvent(null, grandChild, null, Level.DEBUG, new SimpleMessage("Test"), null);
+ filter = MarkerFilter.createFilter("Child", null, null);
+ assertTrue(filter.filter(event) == Filter.Result.NEUTRAL);
+ event = new Log4jLogEvent(null, sibling, null, Level.DEBUG, new SimpleMessage("Test"), null);
+ assertTrue(filter.filter(event) == Filter.Result.DENY);
+ }
+}
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java
new file mode 100644
index 0000000..365222d
--- /dev/null
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class StructuredDataFilterTest {
+
+
+ @Test
+ public void testFilter() {
+ KeyValuePair[] pairs = new KeyValuePair[] { new KeyValuePair("id.name", "AccountTransfer"),
+ new KeyValuePair("ToAccount", "123456")};
+ StructuredDataFilter filter = StructuredDataFilter.createFilter(pairs, "and", null, null);
+ filter.start();
+ StructuredDataMessage msg = new StructuredDataMessage("AccountTransfer@18060", "Transfer Successful", "Audit");
+ msg.put("ToAccount", "123456");
+ msg.put("FromAccount", "211000");
+ msg.put("Amount", "1000.00");
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, Level.DEBUG, null, msg, (Throwable)null) == Filter.Result.NEUTRAL);
+ msg.put("ToAccount", "111111");
+ assertTrue(filter.filter(null, Level.ERROR, null, msg, (Throwable)null) == Filter.Result.DENY);
+ filter = StructuredDataFilter.createFilter(pairs, "or", null, null);
+ filter.start();
+ msg = new StructuredDataMessage("AccountTransfer@18060", "Transfer Successful", "Audit");
+ msg.put("ToAccount", "123456");
+ msg.put("FromAccount", "211000");
+ msg.put("Amount", "1000.00");
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, Level.DEBUG, null, msg, (Throwable)null) == Filter.Result.NEUTRAL);
+ msg.put("ToAccount", "111111");
+ assertTrue(filter.filter(null, Level.ERROR, null, msg, (Throwable)null) == Filter.Result.NEUTRAL);
+ }
+}
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilterTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilterTest.java
new file mode 100644
index 0000000..5031629
--- /dev/null
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThreadContextMapFilterTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.Filter;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ *
+ */
+public class ThreadContextMapFilterTest {
+
+ @Test
+ public void testFilter() {
+ ThreadContext.put("userid", "testuser");
+ ThreadContext.put("organization", "Apache");
+ KeyValuePair[] pairs = new KeyValuePair[] { new KeyValuePair("userid", "JohnDoe"),
+ new KeyValuePair("organization", "Apache")};
+ ThreadContextMapFilter filter = ThreadContextMapFilter.createFilter(pairs, "and", null, null);
+ filter.start();
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ ThreadContext.remove("userid");
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ ThreadContext.put("userid", "JohnDoe");
+ assertTrue(filter.filter(null, Level.ERROR, null, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ ThreadContext.put("organization", "ASF");
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ ThreadContext.clear();
+ filter = ThreadContextMapFilter.createFilter(pairs, "or", null, null);
+ filter.start();
+ assertTrue(filter.isStarted());
+ ThreadContext.put("userid", "testuser");
+ ThreadContext.put("organization", "Apache");
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ ThreadContext.put("organization", "ASF");
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ ThreadContext.remove("organization");
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ ThreadContext.clear();
+ }
+}
diff --git a/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThresholdFilterTest.java b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThresholdFilterTest.java
new file mode 100644
index 0000000..5192acb
--- /dev/null
+++ b/log4j2-core/src/test/java/org/apache/logging/log4j/core/filter/ThresholdFilterTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.logging.log4j.core.filter;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Log4jLogEvent;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+/**
+ *
+ */
+public class ThresholdFilterTest {
+
+ @Test
+ public void testThresholds() {
+ ThresholdFilter filter = ThresholdFilter.createFilter("ERROR", null, null);
+ filter.start();
+ assertTrue(filter.isStarted());
+ assertTrue(filter.filter(null, Level.DEBUG, null, null, (Throwable)null) == Filter.Result.DENY);
+ assertTrue(filter.filter(null, Level.ERROR, null, null, (Throwable)null) == Filter.Result.NEUTRAL);
+ LogEvent event = new Log4jLogEvent(null, null, null, Level.DEBUG, new SimpleMessage("Test"), null);
+ assertTrue(filter.filter(event) == Filter.Result.DENY);
+ event = new Log4jLogEvent(null, null, null, Level.ERROR, new SimpleMessage("Test"), null);
+ assertTrue(filter.filter(event) == Filter.Result.NEUTRAL);
+ }
+}
diff --git a/log4j2-core/src/test/resources/log4j-test1.xml b/log4j2-core/src/test/resources/log4j-test1.xml
index fd41b7f..9f03d6c 100644
--- a/log4j2-core/src/test/resources/log4j-test1.xml
+++ b/log4j2-core/src/test/resources/log4j-test1.xml
@@ -9,9 +9,7 @@
<appenders>
<Console name="STDOUT">
- <PatternLayout>
- <pattern>%m%n</pattern>
- </PatternLayout>
+ <PatternLayout pattern="%m%n"/>
</Console>
<File name="File" fileName="${filename}">
<PatternLayout>
@@ -28,7 +26,9 @@
<loggers>
<logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<filters>
- <MDC key="test" value="123"/>
+ <ThreadContextMap>
+ <KeyValuePair key="test" value="123"/>
+ </ThreadContextMap>
</filters>
<appender-ref ref="STDOUT"/>
</logger>>