You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2023/06/05 20:04:39 UTC
[logging-log4j2] 01/01: Set the default `minLevel` and `maxLevel` of `LevelRangeFilter` to `OFF` and `ALL`, respectively
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch LevelRangeFilter-defaults
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 0a097b4ffb2234d16dddec3a59ca90f3238b476a
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Mon Jun 5 22:04:23 2023 +0200
Set the default `minLevel` and `maxLevel` of `LevelRangeFilter` to `OFF` and `ALL`, respectively
---
.../log4j/core/filter/LevelRangeFilterTest.java | 84 +++++++++++++++-------
.../log4j/core/filter/LevelRangeFilter.java | 73 ++++++++++++-------
.../1503_change_defaults_for_LevelRangeFilter.xml | 25 +++++++
src/site/xdoc/manual/filters.xml | 54 ++++++++++++++
4 files changed, 186 insertions(+), 50 deletions(-)
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/LevelRangeFilterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/LevelRangeFilterTest.java
index 622503147f..7eab683c69 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/LevelRangeFilterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/LevelRangeFilterTest.java
@@ -17,41 +17,77 @@
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.Filter.Result;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.SimpleMessage;
+import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.apache.logging.log4j.core.filter.LevelRangeFilter.createFilter;
+import static org.assertj.core.api.Assertions.assertThat;
-public class LevelRangeFilterTest {
+class LevelRangeFilterTest {
@Test
- public void testLevels() {
- final LevelRangeFilter filter = LevelRangeFilter.createFilter(Level.ERROR, Level.INFO, null, null);
- filter.start();
- assertTrue(filter.isStarted());
- assertSame(Filter.Result.DENY, filter.filter(null, Level.DEBUG, null, (Object) null, (Throwable) null));
- assertSame(Filter.Result.NEUTRAL, filter.filter(null, Level.ERROR, null, (Object) null, (Throwable) null));
- LogEvent event = Log4jLogEvent.newBuilder() //
- .setLevel(Level.DEBUG) //
- .setMessage(new SimpleMessage("Test")) //
- .build();
- assertSame(Filter.Result.DENY, filter.filter(event));
- event = Log4jLogEvent.newBuilder() //
- .setLevel(Level.ERROR) //
- .setMessage(new SimpleMessage("Test")) //
- .build();
- assertSame(Filter.Result.NEUTRAL, filter.filter(event));
+ void verify_constants() {
+ assertThat(LevelRangeFilter.DEFAULT_MIN_LEVEL).isEqualTo(Level.OFF);
+ assertThat(LevelRangeFilter.DEFAULT_MAX_LEVEL).isEqualTo(Level.ALL);
+ assertThat(LevelRangeFilter.DEFAULT_ON_MATCH).isEqualTo(Result.NEUTRAL);
+ assertThat(LevelRangeFilter.DEFAULT_ON_MISMATCH).isEqualTo(Result.DENY);
+ }
+
+ @Test
+ void verify_defaults() {
+ final LevelRangeFilter filter = createFilter(null, null, null, null);
+ assertThat(filter.getMinLevel()).isEqualTo(Level.OFF);
+ assertThat(filter.getMaxLevel()).isEqualTo(Level.ALL);
+ assertThat(filter.getOnMatch()).isEqualTo(Result.NEUTRAL);
+ assertThat(filter.getOnMismatch()).isEqualTo(Result.DENY);
+ }
+
+ @ParameterizedTest
+ @MethodSource("org.apache.logging.log4j.Level#values")
+ void default_should_match_all_levels(final Level level) {
+ final LevelRangeFilter filter = createFilter(null, null, null, null);
+ assertThat(filter.filter(createEvent(level))).isEqualTo(LevelRangeFilter.DEFAULT_ON_MATCH);
}
@Test
- public void testMinimumOnlyLevel() {
- final LevelRangeFilter filter = LevelRangeFilter.createFilter(Level.ERROR, null, null, null);
- filter.start();
- assertTrue(filter.isStarted());
- assertSame(Filter.Result.NEUTRAL, filter.filter(null, Level.ERROR, null, (Object) null, (Throwable) null));
+ void overriding_defaults_should_be_effective() {
+
+ // Choose a configuration
+ final Level minLevel = Level.ERROR;
+ final Level maxLevel = Level.WARN;
+ final Result onMatch = Result.ACCEPT;
+ final Result onMismatch = Result.NEUTRAL;
+
+ // Verify we deviate from the defaults
+ assertThat(minLevel).isNotEqualTo(LevelRangeFilter.DEFAULT_MIN_LEVEL);
+ assertThat(maxLevel).isNotEqualTo(LevelRangeFilter.DEFAULT_MAX_LEVEL);
+ assertThat(onMatch).isNotEqualTo(LevelRangeFilter.DEFAULT_ON_MATCH);
+ assertThat(onMismatch).isNotEqualTo(LevelRangeFilter.DEFAULT_ON_MISMATCH);
+
+ // Verify the filtering
+ final LevelRangeFilter filter = createFilter(minLevel, maxLevel, onMatch, onMismatch);
+ final SoftAssertions assertions = new SoftAssertions();
+ for (final Level level : Level.values()) {
+ final Result expectedResult = level.isInRange(minLevel, maxLevel) ? onMatch : onMismatch;
+ assertions.assertThat(filter.filter(createEvent(level))).isEqualTo(expectedResult);
+ }
+ assertions.assertAll();
+
+ }
+
+ private static LogEvent createEvent(final Level level) {
+ final SimpleMessage message = new SimpleMessage("test message at level " + level);
+ return Log4jLogEvent
+ .newBuilder()
+ .setLevel(level)
+ .setMessage(message)
+ .build();
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/LevelRangeFilter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/LevelRangeFilter.java
index 3f5194ce87..6207717ee0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/LevelRangeFilter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/LevelRangeFilter.java
@@ -29,13 +29,12 @@ import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.util.PerformanceSensitive;
/**
- * This filter returns the {@code onMatch} result if the level in the {@code LogEvent} is in the range of the configured
- * min and max levels, otherwise it returns {@code onMismatch} value . For example, if the filter is configured with
- * {@link Level#ERROR} and {@link Level#INFO} and the LogEvent contains {@link Level#WARN} then the onMatch value will
- * be returned since {@link Level#WARN WARN} events are in between {@link Level#ERROR ERROR} and {@link Level#INFO
- * INFO}.
+ * This filter returns the {@link #onMatch} result if the level of the {@link LogEvent} is in the range of the configured {@link #minLevel} and {@link #maxLevel} values, otherwise it returns the {@link #onMismatch} result.
+ * The default values for {@link #minLevel} and {@link #maxLevel} are set to {@link Level#OFF} and {@link Level#ALL}, respectively.
+ * The default values for {@link #onMatch} and {@link #onMismatch} are set to {@link Result#NEUTRAL} and {@link Result#DENY}, respectively.
* <p>
- * The default Levels are both {@link Level#ERROR ERROR}.
+ * The levels get compared by their associated integral values; {@link Level#OFF} has an integral value of 0, {@link Level#FATAL} 100, {@link Level#ERROR} 200, and so on.
+ * For example, if the filter is configured with {@link #maxLevel} set to {@link Level#INFO}, the filter will return {@link #onMismatch} result for {@link LogEvent}s of level with higher integral values; {@link Level#DEBUG}, {@link Level#TRACE}, etc.
* </p>
*/
@Plugin(name = "LevelRangeFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
@@ -43,33 +42,49 @@ import org.apache.logging.log4j.util.PerformanceSensitive;
public final class LevelRangeFilter extends AbstractFilter {
/**
- * Creates a ThresholdFilter.
+ * The default minimum level threshold.
+ */
+ public static final Level DEFAULT_MIN_LEVEL = Level.OFF;
+
+ /**
+ * THe default maximum level threshold.
+ */
+ public static final Level DEFAULT_MAX_LEVEL = Level.ALL;
+
+ /**
+ * The default result on a match.
+ */
+ public static final Result DEFAULT_ON_MATCH = Result.NEUTRAL;
+
+ /**
+ * The default result on a mismatch.
+ */
+ public static final Result DEFAULT_ON_MISMATCH = Result.DENY;
+
+ /**
+ * Creates an instance with the provided properties.
*
- * @param minLevel
- * The minimum log Level.
- * @param maxLevel
- * The maximum log Level.
- * @param match
- * The action to take on a match.
- * @param mismatch
- * The action to take on a mismatch.
- * @return The created ThresholdFilter.
+ * @param minLevel the minimum level threshold
+ * @param maxLevel the maximum level threshold
+ * @param onMatch the result to return on a match
+ * @param onMismatch the result to return on a mismatch
+ * @return a new instance
*/
- // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
@PluginFactory
public static LevelRangeFilter createFilter(
// @formatter:off
@PluginAttribute("minLevel") final Level minLevel,
@PluginAttribute("maxLevel") final Level maxLevel,
- @PluginAttribute("onMatch") final Result match,
- @PluginAttribute("onMismatch") final Result mismatch) {
+ @PluginAttribute("onMatch") final Result onMatch,
+ @PluginAttribute("onMismatch") final Result onMismatch) {
// @formatter:on
- final Level actualMinLevel = minLevel == null ? Level.ERROR : minLevel;
- final Level actualMaxLevel = maxLevel == null ? Level.ERROR : maxLevel;
- final Result onMatch = match == null ? Result.NEUTRAL : match;
- final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
- return new LevelRangeFilter(actualMinLevel, actualMaxLevel, onMatch, onMismatch);
+ final Level effectiveMinLevel = minLevel == null ? DEFAULT_MIN_LEVEL : minLevel;
+ final Level effectiveMaxLevel = maxLevel == null ? DEFAULT_MAX_LEVEL : maxLevel;
+ final Result effectiveOnMatch = onMatch == null ? DEFAULT_ON_MATCH : onMatch;
+ final Result effectiveOnMismatch = onMismatch == null ? DEFAULT_ON_MISMATCH : onMismatch;
+ return new LevelRangeFilter(effectiveMinLevel, effectiveMaxLevel, effectiveOnMatch, effectiveOnMismatch);
}
+
private final Level maxLevel;
private final Level minLevel;
@@ -81,7 +96,7 @@ public final class LevelRangeFilter extends AbstractFilter {
}
private Result filter(final Level level) {
- return level.isInRange(this.minLevel, this.maxLevel) ? onMatch : onMismatch;
+ return level.isInRange(minLevel, maxLevel) ? onMatch : onMismatch;
}
@Override
@@ -176,17 +191,23 @@ public final class LevelRangeFilter extends AbstractFilter {
return filter(level);
}
+ /**
+ * @return the minimum level threshold
+ */
public Level getMinLevel() {
return minLevel;
}
+ /**
+ * @return the maximum level threshold
+ */
public Level getMaxLevel() {
return maxLevel;
}
@Override
public String toString() {
- return minLevel.toString();
+ return String.format("[%s,%s]", minLevel, maxLevel);
}
}
diff --git a/src/changelog/.2.x.x/1503_change_defaults_for_LevelRangeFilter.xml b/src/changelog/.2.x.x/1503_change_defaults_for_LevelRangeFilter.xml
new file mode 100644
index 0000000000..f08212ca6c
--- /dev/null
+++ b/src/changelog/.2.x.x/1503_change_defaults_for_LevelRangeFilter.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://logging.apache.org/log4j/changelog"
+ xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.1.xsd"
+ type="changed">
+ <issue id="1503" link="https://github.com/apache/logging-log4j2/pulls/1503"/>
+ <author id="vy"/>
+ <description format="asciidoc">Set the default `minLevel` and `maxLevel` of `LevelRangeFilter` to `OFF` and `ALL`, respectively</description>
+</entry>
diff --git a/src/site/xdoc/manual/filters.xml b/src/site/xdoc/manual/filters.xml
index c066e414c1..2947b993bc 100644
--- a/src/site/xdoc/manual/filters.xml
+++ b/src/site/xdoc/manual/filters.xml
@@ -235,6 +235,60 @@
</Loggers>
</Configuration>]]></pre>
</subsection>
+
+ <a name="LevelRangeFilter"/>
+ <subsection name="LevelRangeFilter">
+ <p>
+ <code>LevelRangeFilter</code> allows filtering against a level range, where levels get compared by their associated integral values; <code>OFF</code> has an integral value of 0, <code>FATAL</code> 100, <code>ERROR</code> 200, and so on.
+ </p>
+ <table>
+ <caption align="top">Map Filter Parameters</caption>
+ <tr>
+ <th>Parameter Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><code>minLevel</code></td>
+ <td><code>Level</code></td>
+ <td>the minimum level threshold (defaults to <code>OFF</code>, which has an integral value of 0)</td>
+ </tr>
+ <tr>
+ <td><code>maxLevel</code></td>
+ <td><code>Level</code></td>
+ <td>the maximum level threshold (defaults to <code>ALL</code>, which has an integral value of <code>Integer.MAX_VALUE</code>)</td>
+ </tr>
+ <tr>
+ <td><code>onMatch</code></td>
+ <td><code>Filter.Result</code></td>
+ <td>the result to return on a match, where allowed values are <code>ACCEPT</code>, <code>DENY</code> or <code>NEUTRAL</code> (default)</td>
+ </tr>
+ <tr>
+ <td><code>onMismatch</code></td>
+ <td><code>Filter.Result</code></td>
+ <td>the result to return on a mismatch, where allowed values are <code>ACCEPT</code>, <code>DENY</code> (default) or <code>NEUTRAL</code></td>
+ </tr>
+ </table>
+ <p>
+ In the following example configuration, a <code>LevelRangeFilter</code> is configured with <code>maxLevel</code> set to <code>INFO</code>.
+ The filter will return <code>onMismatch</code> result (i.e., <code>DENY</code>, the default) for log events of level with higher integral values than <code>INFO</code>; i.e., <code>DEBUG</code>, <code>TRACE</code>, etc.
+ </p>
+ <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN" name="MyApp">
+ <Appenders>
+ <Console name="STDOUT">
+ <LevelRangeFilter maxLevel="INFO"/>
+ <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Root level="ERROR">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>]]></pre>
+ </subsection>
+
<a name="MapFilter"/>
<subsection name="MapFilter">
<p>