ref) {
final String value = getValueAttribute(element);
if (value == null) {
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
index 4f04d23f33e..86b63b17b4d 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/BuilderManager.java
@@ -31,11 +31,13 @@
import org.apache.log4j.builders.filter.FilterBuilder;
import org.apache.log4j.builders.layout.LayoutBuilder;
import org.apache.log4j.builders.rewrite.RewritePolicyBuilder;
+import org.apache.log4j.builders.rolling.TriggeringPolicyBuilder;
import org.apache.log4j.config.PropertiesConfiguration;
import org.apache.log4j.rewrite.RewritePolicy;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.xml.XmlConfiguration;
import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.plugins.Inject;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory;
@@ -67,7 +69,7 @@ public class BuilderManager {
*/
@Inject
public BuilderManager(
- final ConfigurableInstanceFactory instanceFactory, @Namespace(NAMESPACE) PluginNamespace plugins) {
+ final ConfigurableInstanceFactory instanceFactory, @Namespace(NAMESPACE) final PluginNamespace plugins) {
this.instanceFactory = instanceFactory;
this.plugins = plugins;
}
@@ -124,7 +126,7 @@ public , T> T parse(
final String prefix,
final Properties props,
final PropertiesConfiguration config,
- T invalidValue) {
+ final T invalidValue) {
final P parser = createBuilder(getPlugin(className), prefix, props);
if (parser != null) {
final T value = parser.parse(config);
@@ -174,4 +176,12 @@ public RewritePolicy parseRewritePolicy(
b -> b.parse(rewriteElement, config),
INVALID_REWRITE_POLICY);
}
+
+ public TriggeringPolicy parseTriggeringPolicy(
+ final String className, final Element policyElement, final XmlConfiguration config) {
+ return newInstance(
+ this.getPlugin(className),
+ b -> b.parse(policyElement, config),
+ (TriggeringPolicy) null);
+ }
}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/EnhancedRollingFileAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/EnhancedRollingFileAppenderBuilder.java
new file mode 100644
index 00000000000..2c97bf170af
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/EnhancedRollingFileAppenderBuilder.java
@@ -0,0 +1,295 @@
+/*
+ * 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.log4j.builders.appender;
+
+import static org.apache.log4j.builders.BuilderManager.NAMESPACE;
+import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
+import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.log4j.Appender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.bridge.AppenderWrapper;
+import org.apache.log4j.bridge.LayoutAdapter;
+import org.apache.log4j.builders.AbstractBuilder;
+import org.apache.log4j.config.PropertiesConfiguration;
+import org.apache.log4j.spi.Filter;
+import org.apache.log4j.xml.XmlConfiguration;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.appender.RollingFileAppender;
+import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.w3c.dom.Element;
+
+/**
+ * Build a File Appender
+ */
+@Plugin("org.apache.log4j.rolling.RollingFileAppender")
+@Namespace(NAMESPACE)
+public class EnhancedRollingFileAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
+
+ private static final String TIME_BASED_ROLLING_POLICY = "org.apache.log4j.rolling.TimeBasedRollingPolicy";
+ private static final String FIXED_WINDOW_ROLLING_POLICY = "org.apache.log4j.rolling.FixedWindowRollingPolicy";
+ private static final Logger LOGGER = StatusLogger.getLogger();
+ private static final String TRIGGERING_TAG = "triggeringPolicy";
+ private static final String ROLLING_TAG = "rollingPolicy";
+ private static final int DEFAULT_MIN_INDEX = 1;
+ private static final int DEFAULT_MAX_INDEX = 7;
+ private static final String ACTIVE_FILE_PARAM = "ActiveFileName";
+ private static final String FILE_PATTERN_PARAM = "FileNamePattern";
+ private static final String MIN_INDEX_PARAM = "MinIndex";
+ private static final String MAX_INDEX_PARAM = "MaxIndex";
+
+ public EnhancedRollingFileAppenderBuilder() {}
+
+ public EnhancedRollingFileAppenderBuilder(final String prefix, final Properties properties) {
+ super(prefix, properties);
+ }
+
+ private void parseRollingPolicy(
+ final Element element,
+ final XmlConfiguration configuration,
+ final AtomicReference rollingPolicyClassName,
+ final AtomicReference activeFileName,
+ final AtomicReference fileNamePattern,
+ final AtomicInteger minIndex,
+ final AtomicInteger maxIndex) {
+ rollingPolicyClassName.set(configuration.subst(element.getAttribute("class"), getProperties()));
+ forEachElement(element.getChildNodes(), currentElement -> {
+ switch (currentElement.getTagName()) {
+ case PARAM_TAG:
+ switch (getNameAttributeKey(currentElement)) {
+ case ACTIVE_FILE_PARAM:
+ set(ACTIVE_FILE_PARAM, currentElement, activeFileName);
+ break;
+ case FILE_PATTERN_PARAM:
+ set(FILE_PATTERN_PARAM, currentElement, fileNamePattern);
+ break;
+ case MIN_INDEX_PARAM:
+ set(MIN_INDEX_PARAM, currentElement, minIndex);
+ break;
+ case MAX_INDEX_PARAM:
+ set(MAX_INDEX_PARAM, currentElement, maxIndex);
+ }
+ }
+ });
+ }
+
+ @Override
+ public Appender parseAppender(final Element element, final XmlConfiguration configuration) {
+ // FileAppender
+ final String name = getNameAttribute(element);
+ final AtomicReference layout = new AtomicReference<>();
+ final AtomicReference filter = new AtomicReference<>();
+ final AtomicReference fileName = new AtomicReference<>();
+ final AtomicReference level = new AtomicReference<>();
+ final AtomicBoolean immediateFlush = new AtomicBoolean(true);
+ final AtomicBoolean append = new AtomicBoolean(true);
+ final AtomicBoolean bufferedIo = new AtomicBoolean();
+ final AtomicInteger bufferSize = new AtomicInteger(8192);
+ // specific to RollingFileAppender
+ final AtomicReference rollingPolicyClassName = new AtomicReference<>();
+ final AtomicReference activeFileName = new AtomicReference<>();
+ final AtomicReference fileNamePattern = new AtomicReference<>();
+ final AtomicInteger minIndex = new AtomicInteger(DEFAULT_MIN_INDEX);
+ final AtomicInteger maxIndex = new AtomicInteger(DEFAULT_MAX_INDEX);
+ final AtomicReference triggeringPolicy = new AtomicReference<>();
+ forEachElement(element.getChildNodes(), currentElement -> {
+ switch (currentElement.getTagName()) {
+ case ROLLING_TAG:
+ parseRollingPolicy(
+ currentElement,
+ configuration,
+ rollingPolicyClassName,
+ activeFileName,
+ fileNamePattern,
+ minIndex,
+ maxIndex);
+ break;
+ case TRIGGERING_TAG:
+ triggeringPolicy.set(configuration.parseTriggeringPolicy(currentElement));
+ break;
+ case LAYOUT_TAG:
+ layout.set(configuration.parseLayout(currentElement));
+ break;
+ case FILTER_TAG:
+ configuration.addFilter(filter, currentElement);
+ break;
+ case PARAM_TAG:
+ switch (getNameAttributeKey(currentElement)) {
+ case FILE_PARAM:
+ set(FILE_PARAM, currentElement, fileName);
+ break;
+ case APPEND_PARAM:
+ set(APPEND_PARAM, currentElement, append);
+ break;
+ case BUFFERED_IO_PARAM:
+ set(BUFFERED_IO_PARAM, currentElement, bufferedIo);
+ break;
+ case BUFFER_SIZE_PARAM:
+ set(BUFFER_SIZE_PARAM, currentElement, bufferSize);
+ break;
+ case THRESHOLD_PARAM:
+ set(THRESHOLD_PARAM, currentElement, level);
+ break;
+ case IMMEDIATE_FLUSH_PARAM:
+ set(IMMEDIATE_FLUSH_PARAM, currentElement, immediateFlush);
+ break;
+ }
+ break;
+ }
+ });
+ return createAppender(
+ name,
+ layout.get(),
+ filter.get(),
+ fileName.get(),
+ level.get(),
+ immediateFlush.get(),
+ append.get(),
+ bufferedIo.get(),
+ bufferSize.get(),
+ rollingPolicyClassName.get(),
+ activeFileName.get(),
+ fileNamePattern.get(),
+ minIndex.get(),
+ maxIndex.get(),
+ triggeringPolicy.get(),
+ configuration);
+ }
+
+ @Override
+ public Appender parseAppender(
+ final String name,
+ final String appenderPrefix,
+ final String layoutPrefix,
+ final String filterPrefix,
+ final Properties props,
+ final PropertiesConfiguration configuration) {
+ final Layout layout = configuration.parseLayout(layoutPrefix, name, props);
+ final Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
+ final String level = getProperty(THRESHOLD_PARAM);
+ final String fileName = getProperty(FILE_PARAM);
+ final boolean append = getBooleanProperty(APPEND_PARAM, true);
+ final boolean immediateFlush = getBooleanProperty(IMMEDIATE_FLUSH_PARAM, true);
+ final boolean bufferedIo = getBooleanProperty(BUFFERED_IO_PARAM, false);
+ final int bufferSize = Integer.parseInt(getProperty(BUFFER_SIZE_PARAM, "8192"));
+ final String rollingPolicyClassName = getProperty(ROLLING_TAG);
+ final int minIndex = getIntegerProperty(ROLLING_TAG + "." + MIN_INDEX_PARAM, DEFAULT_MIN_INDEX);
+ final int maxIndex = getIntegerProperty(ROLLING_TAG + "." + MAX_INDEX_PARAM, DEFAULT_MAX_INDEX);
+ final String activeFileName = getProperty(ROLLING_TAG + "." + ACTIVE_FILE_PARAM);
+ final String fileNamePattern = getProperty(ROLLING_TAG + "." + FILE_PATTERN_PARAM);
+ final TriggeringPolicy triggeringPolicy =
+ configuration.parseTriggeringPolicy(props, appenderPrefix + "." + TRIGGERING_TAG);
+ return createAppender(
+ name,
+ layout,
+ filter,
+ fileName,
+ level,
+ immediateFlush,
+ append,
+ bufferedIo,
+ bufferSize,
+ rollingPolicyClassName,
+ activeFileName,
+ fileNamePattern,
+ minIndex,
+ maxIndex,
+ triggeringPolicy,
+ configuration);
+ }
+
+ private Appender createAppender(
+ final String name,
+ final Layout layout,
+ final Filter filter,
+ final String fileName,
+ final String level,
+ final boolean immediateFlush,
+ final boolean append,
+ final boolean bufferedIo,
+ final int bufferSize,
+ final String rollingPolicyClassName,
+ final String activeFileName,
+ final String fileNamePattern,
+ final int minIndex,
+ final int maxIndex,
+ final TriggeringPolicy triggeringPolicy,
+ final Configuration configuration) {
+ final org.apache.logging.log4j.core.Layout fileLayout = LayoutAdapter.adapt(layout);
+ final boolean actualImmediateFlush = bufferedIo ? false : immediateFlush;
+ final org.apache.logging.log4j.core.Filter fileFilter = buildFilters(level, filter);
+ if (rollingPolicyClassName == null) {
+ LOGGER.error("Unable to create RollingFileAppender, no rolling policy provided.");
+ return null;
+ }
+ final String actualFileName = activeFileName != null ? activeFileName : fileName;
+ if (actualFileName == null) {
+ LOGGER.error("Unable to create RollingFileAppender, no file name provided.");
+ return null;
+ }
+ if (fileNamePattern == null) {
+ LOGGER.error("Unable to create RollingFileAppender, no file name pattern provided.");
+ return null;
+ }
+ final DefaultRolloverStrategy.Builder rolloverStrategyBuilder = DefaultRolloverStrategy.newBuilder();
+ switch (rollingPolicyClassName) {
+ case FIXED_WINDOW_ROLLING_POLICY:
+ rolloverStrategyBuilder.setMin(Integer.toString(minIndex)).setMax(Integer.toString(maxIndex));
+ break;
+ case TIME_BASED_ROLLING_POLICY:
+ break;
+ default:
+ LOGGER.warn("Unsupported rolling policy: {}", rollingPolicyClassName);
+ }
+ final TriggeringPolicy actualTriggeringPolicy;
+ if (triggeringPolicy != null) {
+ actualTriggeringPolicy = triggeringPolicy;
+ } else if (rollingPolicyClassName.equals(TIME_BASED_ROLLING_POLICY)) {
+ actualTriggeringPolicy = TimeBasedTriggeringPolicy.newBuilder().build();
+ } else {
+ LOGGER.error("Unable to create RollingFileAppender, no triggering policy provided.");
+ return null;
+ }
+ return AppenderWrapper.adapt(RollingFileAppender.newBuilder()
+ .setAppend(append)
+ .setBufferedIo(bufferedIo)
+ .setBufferSize(bufferedIo ? bufferSize : 0)
+ .setConfiguration(configuration)
+ .setFileName(actualFileName)
+ .setFilePattern(fileNamePattern)
+ .setFilter(fileFilter)
+ .setImmediateFlush(actualImmediateFlush)
+ .setLayout(fileLayout)
+ .setName(name)
+ .setPolicy(actualTriggeringPolicy)
+ .setStrategy(rolloverStrategyBuilder.build())
+ .build());
+ }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
index 770cd991b36..897d7d598f4 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
@@ -42,8 +42,6 @@
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
-import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
-import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.time.Clock;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
@@ -193,10 +191,6 @@ private Appender createAppender(
return null;
}
final String filePattern = fileName + ".%i";
- final TriggeringPolicy timePolicy = TimeBasedTriggeringPolicy.newBuilder()
- .setClock(clock)
- .setModulate(true)
- .build();
final SizeBasedTriggeringPolicy sizePolicy = SizeBasedTriggeringPolicy.createPolicy(maxSize);
final CompositeTriggeringPolicy policy = CompositeTriggeringPolicy.createPolicy(sizePolicy);
final RolloverStrategy strategy = DefaultRolloverStrategy.newBuilder()
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
index 3d5ef21c3ae..781665ab1bb 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
@@ -66,7 +66,7 @@ public Filter parse(final Element filterElement, final XmlConfiguration config)
levelMax.set(getValueAttribute(currentElement));
break;
case LEVEL_MIN:
- levelMax.set(getValueAttribute(currentElement));
+ levelMin.set(getValueAttribute(currentElement));
break;
case ACCEPT_ON_MATCH:
acceptOnMatch.set(getBooleanValueAttribute(currentElement));
@@ -86,21 +86,23 @@ public Filter parse(final PropertiesConfiguration config) {
}
private Filter createFilter(final String levelMax, final String levelMin, final boolean acceptOnMatch) {
- Level max = Level.FATAL;
- Level min = Level.TRACE;
+ Level max = Level.OFF;
+ Level min = Level.ALL;
if (levelMax != null) {
- max = OptionConverter.toLevel(levelMax, org.apache.log4j.Level.FATAL)
- .getVersion2Level();
+ max = OptionConverter.toLevel(levelMax, org.apache.log4j.Level.OFF).getVersion2Level();
}
if (levelMin != null) {
- min = OptionConverter.toLevel(levelMin, org.apache.log4j.Level.DEBUG)
- .getVersion2Level();
+ min = OptionConverter.toLevel(levelMin, org.apache.log4j.Level.ALL).getVersion2Level();
}
final org.apache.logging.log4j.core.Filter.Result onMatch = acceptOnMatch
? org.apache.logging.log4j.core.Filter.Result.ACCEPT
: org.apache.logging.log4j.core.Filter.Result.NEUTRAL;
+ // XXX: LOG4J2-2315
+ // log4j1 order: ALL < TRACE < DEBUG < ... < FATAL < OFF
+ // log4j2 order: ALL > TRACE > DEBUG > ... > FATAL > OFF
+ // So we create as LevelRangeFilter.createFilter(minLevel=max, maxLevel=min, ...)
return FilterWrapper.adapt(
- LevelRangeFilter.createFilter(min, max, onMatch, org.apache.logging.log4j.core.Filter.Result.DENY));
+ LevelRangeFilter.createFilter(max, min, onMatch, org.apache.logging.log4j.core.Filter.Result.DENY));
}
}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/XmlLayoutBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/XmlLayoutBuilder.java
index 541e0ce03f1..37b8da819bb 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/XmlLayoutBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/XmlLayoutBuilder.java
@@ -28,7 +28,7 @@
import org.apache.log4j.config.PropertiesConfiguration;
import org.apache.log4j.layout.Log4j1XmlLayout;
import org.apache.log4j.xml.XmlConfiguration;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
import org.w3c.dom.Element;
@@ -60,17 +60,17 @@ public Layout parse(final Element layoutElement, final XmlConfiguration config)
locationInfo.set(getBooleanValueAttribute(currentElement));
}
});
- return createLayout(properties.get(), locationInfo.get());
+ return createLayout(config, properties.get(), locationInfo.get());
}
@Override
public Layout parse(final PropertiesConfiguration config) {
final boolean properties = getBooleanProperty(PROPERTIES);
final boolean locationInfo = getBooleanProperty(LOCATION_INFO);
- return createLayout(properties, locationInfo);
+ return createLayout(config, properties, locationInfo);
}
- private Layout createLayout(final boolean properties, final boolean locationInfo) {
- return LayoutWrapper.adapt(Log4j1XmlLayout.createLayout(new DefaultConfiguration(), locationInfo, properties));
+ private Layout createLayout(final Configuration config, final boolean properties, final boolean locationInfo) {
+ return LayoutWrapper.adapt(Log4j1XmlLayout.createLayout(config, locationInfo, properties));
}
}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/CompositeTriggeringPolicyBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/CompositeTriggeringPolicyBuilder.java
new file mode 100644
index 00000000000..1eeab59d405
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/CompositeTriggeringPolicyBuilder.java
@@ -0,0 +1,75 @@
+/*
+ * 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.log4j.builders.rolling;
+
+import static org.apache.log4j.builders.BuilderManager.NAMESPACE;
+import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import org.apache.log4j.builders.AbstractBuilder;
+import org.apache.log4j.config.PropertiesConfiguration;
+import org.apache.log4j.xml.XmlConfiguration;
+import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.w3c.dom.Element;
+
+@Plugin("org.apache.log4j.rolling.CompositeTriggeringPolicy")
+@Namespace(NAMESPACE)
+public class CompositeTriggeringPolicyBuilder extends AbstractBuilder
+ implements TriggeringPolicyBuilder {
+
+ private static final TriggeringPolicy[] EMPTY_TRIGGERING_POLICIES = new TriggeringPolicy[0];
+ private static final String POLICY_TAG = "triggeringPolicy";
+
+ public CompositeTriggeringPolicyBuilder() {
+ super();
+ }
+
+ public CompositeTriggeringPolicyBuilder(final String prefix, final Properties props) {
+ super(prefix, props);
+ }
+
+ @Override
+ public CompositeTriggeringPolicy parse(final Element element, final XmlConfiguration configuration) {
+ final List policies = new ArrayList<>();
+ forEachElement(element.getChildNodes(), currentElement -> {
+ switch (currentElement.getTagName()) {
+ case POLICY_TAG:
+ final TriggeringPolicy policy = configuration.parseTriggeringPolicy(currentElement);
+ if (policy != null) {
+ policies.add(policy);
+ }
+ break;
+ }
+ });
+ return createTriggeringPolicy(policies);
+ }
+
+ @Override
+ public CompositeTriggeringPolicy parse(final PropertiesConfiguration configuration) {
+ return createTriggeringPolicy(Collections.emptyList());
+ }
+
+ private CompositeTriggeringPolicy createTriggeringPolicy(final List policies) {
+ return CompositeTriggeringPolicy.createPolicy(policies.toArray(EMPTY_TRIGGERING_POLICIES));
+ }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/SizeBasedTriggeringPolicyBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/SizeBasedTriggeringPolicyBuilder.java
new file mode 100644
index 00000000000..fc531d5c9a5
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/SizeBasedTriggeringPolicyBuilder.java
@@ -0,0 +1,76 @@
+/*
+ * 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.log4j.builders.rolling;
+
+import static org.apache.log4j.builders.BuilderManager.NAMESPACE;
+import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
+
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.log4j.builders.AbstractBuilder;
+import org.apache.log4j.config.PropertiesConfiguration;
+import org.apache.log4j.xml.XmlConfiguration;
+import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.w3c.dom.Element;
+
+@Plugin("org.apache.log4j.rolling.SizeBasedTriggeringPolicy")
+@Namespace(NAMESPACE)
+public class SizeBasedTriggeringPolicyBuilder extends AbstractBuilder
+ implements TriggeringPolicyBuilder {
+
+ private static final String MAX_SIZE_PARAM = "MaxFileSize";
+ private static final long DEFAULT_MAX_SIZE = 10 * 1024 * 1024;
+
+ public SizeBasedTriggeringPolicyBuilder() {
+ super();
+ }
+
+ public SizeBasedTriggeringPolicyBuilder(final String prefix, final Properties props) {
+ super(prefix, props);
+ }
+
+ @Override
+ public SizeBasedTriggeringPolicy parse(final Element element, final XmlConfiguration configuration) {
+ final AtomicLong maxSize = new AtomicLong(DEFAULT_MAX_SIZE);
+ forEachElement(element.getChildNodes(), currentElement -> {
+ switch (currentElement.getTagName()) {
+ case PARAM_TAG:
+ switch (getNameAttributeKey(currentElement)) {
+ case MAX_SIZE_PARAM:
+ set(MAX_SIZE_PARAM, currentElement, maxSize);
+ break;
+ }
+ break;
+ }
+ });
+ return createTriggeringPolicy(maxSize.get());
+ }
+
+ @Override
+ public SizeBasedTriggeringPolicy parse(final PropertiesConfiguration configuration) {
+ final long maxSize = getLongProperty(MAX_SIZE_PARAM, DEFAULT_MAX_SIZE);
+ return createTriggeringPolicy(maxSize);
+ }
+
+ private SizeBasedTriggeringPolicy createTriggeringPolicy(final long maxSize) {
+ return SizeBasedTriggeringPolicy.createPolicy(Long.toString(maxSize));
+ }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TimeBasedRollingPolicyBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TimeBasedRollingPolicyBuilder.java
new file mode 100644
index 00000000000..c53e9ace482
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TimeBasedRollingPolicyBuilder.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.log4j.builders.rolling;
+
+import static org.apache.log4j.builders.BuilderManager.NAMESPACE;
+
+import java.util.Properties;
+import org.apache.log4j.builders.AbstractBuilder;
+import org.apache.log4j.config.PropertiesConfiguration;
+import org.apache.log4j.xml.XmlConfiguration;
+import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Plugin;
+import org.w3c.dom.Element;
+
+@Plugin("org.apache.log4j.rolling.TimeBasedRollingPolicy")
+@Namespace(NAMESPACE)
+public class TimeBasedRollingPolicyBuilder extends AbstractBuilder
+ implements TriggeringPolicyBuilder {
+
+ public TimeBasedRollingPolicyBuilder(final String prefix, final Properties props) {
+ super(prefix, props);
+ }
+
+ public TimeBasedRollingPolicyBuilder() {
+ super();
+ }
+
+ @Override
+ public TimeBasedTriggeringPolicy parse(final Element element, final XmlConfiguration configuration) {
+ return createTriggeringPolicy();
+ }
+
+ @Override
+ public TimeBasedTriggeringPolicy parse(final PropertiesConfiguration configuration) {
+ return createTriggeringPolicy();
+ }
+
+ private TimeBasedTriggeringPolicy createTriggeringPolicy() {
+ return TimeBasedTriggeringPolicy.newBuilder().build();
+ }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TriggeringPolicyBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TriggeringPolicyBuilder.java
new file mode 100644
index 00000000000..931ad08b405
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TriggeringPolicyBuilder.java
@@ -0,0 +1,24 @@
+/*
+ * 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.log4j.builders.rolling;
+
+import org.apache.log4j.builders.Parser;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
+
+public interface TriggeringPolicyBuilder extends Parser {
+ // NOP
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/config/PropertiesConfiguration.java b/log4j-1.2-api/src/main/java/org/apache/log4j/config/PropertiesConfiguration.java
index f3ed60377b3..5ee7bc06fa1 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/config/PropertiesConfiguration.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/config/PropertiesConfiguration.java
@@ -41,6 +41,7 @@
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Filter.Result;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.LoggerConfig;
@@ -612,6 +613,14 @@ private Filter buildFilter(final String className, final String appenderName, fi
return filter;
}
+ public TriggeringPolicy parseTriggeringPolicy(final Properties props, final String policyPrefix) {
+ final String policyClass = OptionConverter.findAndSubst(policyPrefix, props);
+ if (policyClass == null) {
+ return null;
+ }
+ return manager.parse(policyClass, policyPrefix, props, this, null);
+ }
+
private static T newInstanceOf(final String className, final String type) {
try {
return LoaderUtil.newInstanceOf(className);
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/helpers/OptionConverter.java b/log4j-1.2-api/src/main/java/org/apache/log4j/helpers/OptionConverter.java
index eea6bc673d7..b354d183058 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/helpers/OptionConverter.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/helpers/OptionConverter.java
@@ -41,7 +41,7 @@
/**
* A convenience class to convert property values to specific types.
*/
-public class OptionConverter {
+public final class OptionConverter {
private static class CharMap {
final char key;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1XmlLayout.java b/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1XmlLayout.java
index 0b2c45b9e11..ccb57282f81 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1XmlLayout.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/layout/Log4j1XmlLayout.java
@@ -55,7 +55,7 @@ public final class Log4j1XmlLayout extends AbstractStringLayout {
@PluginFactory
public static Log4j1XmlLayout createLayout(
// @formatter:off
- @PluginConfiguration Configuration configuration,
+ @PluginConfiguration final Configuration configuration,
@PluginAttribute(value = "locationInfo") final boolean locationInfo,
@PluginAttribute(value = "properties") final boolean properties
// @formatter:on
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/pattern/Log4j1LevelPatternConverter.java b/log4j-1.2-api/src/main/java/org/apache/log4j/pattern/Log4j1LevelPatternConverter.java
index ce38b4b0479..f93c9f8de2b 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/pattern/Log4j1LevelPatternConverter.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/pattern/Log4j1LevelPatternConverter.java
@@ -30,7 +30,7 @@
@Namespace(PatternConverter.CATEGORY)
@Plugin("Log4j1LevelPatternConverter")
@ConverterKeys({"v1Level"})
-public class Log4j1LevelPatternConverter extends LogEventPatternConverter {
+public final class Log4j1LevelPatternConverter extends LogEventPatternConverter {
private static final Log4j1LevelPatternConverter INSTANCE = new Log4j1LevelPatternConverter();
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
index 1519bf37e94..d705b856f55 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/spi/LocationInfo.java
@@ -18,6 +18,7 @@
import java.io.Serializable;
import java.util.Objects;
+import org.apache.logging.log4j.core.util.Integers;
/**
* The internal representation of caller location information.
@@ -101,35 +102,40 @@ public LocationInfo(final Throwable throwable, final String fqnOfCallingClass) {
prevClass = thisClass;
}
}
- this.stackTraceElement = new StackTraceElement(declaringClass, methodName, file, Integer.parseInt(line));
- this.fullInfo = stackTraceElement.toString();
+ if (declaringClass != null && methodName != null) {
+ this.stackTraceElement = new StackTraceElement(declaringClass, methodName, file, Integers.parseInt(line));
+ this.fullInfo = stackTraceElement.toString();
+ } else {
+ this.stackTraceElement = null;
+ this.fullInfo = null;
+ }
}
/**
* Gets the fully qualified class name of the caller making the logging request.
*/
public String getClassName() {
- return stackTraceElement.getClassName();
+ return stackTraceElement != null ? stackTraceElement.getClassName() : NA;
}
/**
* Gets the file name of the caller.
*/
public String getFileName() {
- return stackTraceElement.getFileName();
+ return stackTraceElement != null ? stackTraceElement.getFileName() : NA;
}
/**
* Gets the line number of the caller.
*/
public String getLineNumber() {
- return Integer.toString(stackTraceElement.getLineNumber());
+ return stackTraceElement != null ? Integer.toString(stackTraceElement.getLineNumber()) : NA;
}
/**
* Gets the method name of the caller.
*/
public String getMethodName() {
- return stackTraceElement.getMethodName();
+ return stackTraceElement != null ? stackTraceElement.getMethodName() : NA;
}
}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
index 25f81f01db1..daa0903ba03 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java
@@ -42,6 +42,7 @@
import org.apache.log4j.spi.Filter;
import org.apache.logging.log4j.core.Filter.Result;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.LoggerConfig;
@@ -663,6 +664,12 @@ private Layout buildLayout(final String className, final Element layout_element)
return null;
}
+ public TriggeringPolicy parseTriggeringPolicy(final Element policyElement) {
+ final String className = subst(policyElement.getAttribute(CLASS_ATTR));
+ LOGGER.debug("Parsing triggering policy of class: \"{}\"", className);
+ return manager.parseTriggeringPolicy(className, policyElement, this);
+ }
+
/**
* Used internally to parse a level element.
*/
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
index a1001d2aa5f..0dc789bcf5a 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
@@ -89,6 +89,7 @@ public void testExist() {
public void testForcedLog() {
final MockCategory category = new MockCategory("org.example.foo");
category.setAdditivity(false);
+ category.setHierarchy(LogManager.getHierarchy());
((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender);
// Logging a String
category.info("Hello, World");
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilderTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilderTest.java
new file mode 100644
index 00000000000..79a4354406b
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilderTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.log4j.builders.filter;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.StringReader;
+import java.util.Properties;
+import java.util.stream.Stream;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.log4j.bridge.FilterWrapper;
+import org.apache.log4j.spi.Filter;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Filter.Result;
+import org.apache.logging.log4j.core.filter.LevelRangeFilter;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+public class LevelRangeFilterBuilderTest {
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testAcceptOnMatchTrue(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(Level.INFO, Level.ERROR, true);
+
+ assertResult(Result.DENY, levelRangeFilter, Level.ALL);
+ assertResult(Result.DENY, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.INFO);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.WARN);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ERROR);
+ assertResult(Result.DENY, levelRangeFilter, Level.FATAL);
+ assertResult(Result.DENY, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testAcceptOnMatchFalse(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(Level.INFO, Level.ERROR, false);
+
+ assertResult(Result.DENY, levelRangeFilter, Level.ALL);
+ assertResult(Result.DENY, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.INFO);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.WARN);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.ERROR);
+ assertResult(Result.DENY, levelRangeFilter, Level.FATAL);
+ assertResult(Result.DENY, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testAcceptOnMatchNull(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(Level.INFO, Level.ERROR, null);
+
+ assertResult(Result.DENY, levelRangeFilter, Level.ALL);
+ assertResult(Result.DENY, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.INFO);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.WARN);
+ assertResult(Result.NEUTRAL, levelRangeFilter, Level.ERROR);
+ assertResult(Result.DENY, levelRangeFilter, Level.FATAL);
+ assertResult(Result.DENY, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testMinLevelNull(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(null, Level.ERROR, true);
+
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ALL);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.INFO);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.WARN);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ERROR);
+ assertResult(Result.DENY, levelRangeFilter, Level.FATAL);
+ assertResult(Result.DENY, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testMaxLevelNull(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(Level.INFO, null, true);
+
+ assertResult(Result.DENY, levelRangeFilter, Level.ALL);
+ assertResult(Result.DENY, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.INFO);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.WARN);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ERROR);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.FATAL);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testMinMaxLevelSame(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(Level.INFO, Level.INFO, true);
+
+ assertResult(Result.DENY, levelRangeFilter, Level.ALL);
+ assertResult(Result.DENY, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.INFO);
+ assertResult(Result.DENY, levelRangeFilter, Level.WARN);
+ assertResult(Result.DENY, levelRangeFilter, Level.ERROR);
+ assertResult(Result.DENY, levelRangeFilter, Level.FATAL);
+ assertResult(Result.DENY, levelRangeFilter, Level.OFF);
+ }
+
+ @ParameterizedTest
+ @ArgumentsSource(TestLevelRangeFilterBuilderProvider.class)
+ public void testMinMaxLevelNull(TestLevelRangeFilterBuilder builder) throws Exception {
+ LevelRangeFilter levelRangeFilter = builder.build(null, null, true);
+
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ALL);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.DEBUG);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.INFO);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.WARN);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.ERROR);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.FATAL);
+ assertResult(Result.ACCEPT, levelRangeFilter, Level.OFF);
+ }
+
+ private static void assertResult(Result expected, LevelRangeFilter filter, Level level) {
+ assertSame(expected, filter.filter(null, level, null, (Object) null, null));
+ }
+
+ private static class TestLevelRangeFilterBuilderProvider implements ArgumentsProvider {
+
+ @Override
+ public Stream extends Arguments> provideArguments(ExtensionContext extensionContext) {
+ return Stream.of(
+ Arguments.of(new TestLevelRangeFilterFromXmlBuilder()),
+ Arguments.of(new TestLevelRangeFilterFromPropertyBuilder()));
+ }
+ }
+
+ private interface TestLevelRangeFilterBuilder {
+
+ LevelRangeFilter build(Level levelMin, Level levelMax, Boolean acceptOnMatch) throws Exception;
+ }
+
+ private static class TestLevelRangeFilterFromXmlBuilder implements TestLevelRangeFilterBuilder {
+
+ @Override
+ public LevelRangeFilter build(Level levelMin, Level levelMax, Boolean acceptOnMatch) throws Exception {
+ LevelRangeFilterBuilder builder = new LevelRangeFilterBuilder();
+ Filter filter = builder.parse(generateTestXml(levelMin, levelMax, acceptOnMatch), null);
+ org.apache.logging.log4j.core.Filter wrappedFilter = ((FilterWrapper) filter).getFilter();
+ return (LevelRangeFilter) wrappedFilter;
+ }
+
+ private static Element generateTestXml(Level levelMin, Level levelMax, Boolean acceptOnMatch) throws Exception {
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n");
+ if (levelMin != null) {
+ sb.append(String.format("\n", levelMin));
+ }
+ if (levelMax != null) {
+ sb.append(String.format("\n", levelMax));
+ }
+ if (acceptOnMatch != null) {
+ sb.append(String.format("\n", acceptOnMatch));
+ }
+ sb.append("");
+
+ return DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder()
+ .parse(new InputSource(new StringReader(sb.toString())))
+ .getDocumentElement();
+ }
+ }
+
+ private static class TestLevelRangeFilterFromPropertyBuilder implements TestLevelRangeFilterBuilder {
+
+ @Override
+ public LevelRangeFilter build(Level levelMin, Level levelMax, Boolean acceptOnMatch) {
+ Properties properties = new Properties();
+ if (levelMin != null) {
+ properties.setProperty("foobar.levelMin", levelMin.name());
+ }
+ if (levelMax != null) {
+ properties.setProperty("foobar.levelMax", levelMax.name());
+ }
+ if (acceptOnMatch != null) {
+ properties.setProperty("foobar.acceptOnMatch", acceptOnMatch.toString());
+ }
+ LevelRangeFilterBuilder builder = new LevelRangeFilterBuilder("foobar", properties);
+ Filter filter = builder.parse(null);
+ org.apache.logging.log4j.core.Filter wrappedFilter = ((FilterWrapper) filter).getFilter();
+ return (LevelRangeFilter) wrappedFilter;
+ }
+ }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
index 48996f99bef..946bd7b042a 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
@@ -26,6 +26,7 @@
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -71,6 +72,12 @@ public abstract class AbstractLog4j1ConfigurationTest {
abstract Configuration getConfiguration(String configResourcePrefix) throws URISyntaxException, IOException;
+ protected InputStream getResourceAsStream(final String configResource) throws IOException {
+ final InputStream is = getClass().getClassLoader().getResourceAsStream(configResource);
+ assertNotNull(is);
+ return is;
+ }
+
protected LoggerContext configure(final String configResourcePrefix) throws URISyntaxException, IOException {
Configurator.reconfigure(getConfiguration(configResourcePrefix));
return (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false);
@@ -550,4 +557,101 @@ public void testGlobalThreshold() throws Exception {
assertEquals(1, legacyAppender.getEvents().size());
}
}
+
+ protected void testEnhancedRollingFileAppender(final Configuration configuration) {
+ Appender appender;
+ TriggeringPolicy policy;
+ RolloverStrategy strategy;
+ DefaultRolloverStrategy defaultRolloverStrategy;
+ // Time policy with default attributes
+ appender = configuration.getAppender("DEFAULT_TIME");
+ assertTrue("is RollingFileAppender", appender instanceof RollingFileAppender);
+ final RollingFileAppender defaultTime = (RollingFileAppender) appender;
+ assertEquals("append", true, defaultTime.getManager().isAppend());
+ assertEquals("bufferSize", 8192, defaultTime.getManager().getBufferSize());
+ assertEquals("immediateFlush", true, defaultTime.getImmediateFlush());
+ assertEquals("fileName", "target/EnhancedRollingFileAppender/defaultTime.log", defaultTime.getFileName());
+ assertEquals(
+ "filePattern",
+ "target/EnhancedRollingFileAppender/defaultTime.%d{yyyy-MM-dd}.log",
+ defaultTime.getFilePattern());
+ policy = defaultTime.getTriggeringPolicy();
+ assertTrue("is TimeBasedTriggeringPolicy", policy instanceof TimeBasedTriggeringPolicy);
+ // Size policy with default attributes
+ appender = configuration.getAppender("DEFAULT_SIZE");
+ assertTrue("is RollingFileAppender", appender instanceof RollingFileAppender);
+ final RollingFileAppender defaultSize = (RollingFileAppender) appender;
+ assertEquals("append", true, defaultSize.getManager().isAppend());
+ assertEquals("bufferSize", 8192, defaultSize.getManager().getBufferSize());
+ assertEquals("immediateFlush", true, defaultSize.getImmediateFlush());
+ assertEquals("fileName", "target/EnhancedRollingFileAppender/defaultSize.log", defaultSize.getFileName());
+ assertEquals(
+ "filePattern", "target/EnhancedRollingFileAppender/defaultSize.%i.log", defaultSize.getFilePattern());
+ policy = defaultSize.getTriggeringPolicy();
+ assertTrue("is SizeBasedTriggeringPolicy", policy instanceof SizeBasedTriggeringPolicy);
+ assertEquals(10 * 1024 * 1024L, ((SizeBasedTriggeringPolicy) policy).getMaxFileSize());
+ strategy = defaultSize.getManager().getRolloverStrategy();
+ assertTrue("is DefaultRolloverStrategy", strategy instanceof DefaultRolloverStrategy);
+ defaultRolloverStrategy = (DefaultRolloverStrategy) strategy;
+ assertEquals(1, defaultRolloverStrategy.getMinIndex());
+ assertEquals(7, defaultRolloverStrategy.getMaxIndex());
+ // Time policy with custom attributes
+ appender = configuration.getAppender("TIME");
+ assertTrue("is RollingFileAppender", appender instanceof RollingFileAppender);
+ final RollingFileAppender time = (RollingFileAppender) appender;
+ assertEquals("append", false, time.getManager().isAppend());
+ assertEquals("bufferSize", 1000, time.getManager().getBufferSize());
+ assertEquals("immediateFlush", false, time.getImmediateFlush());
+ assertEquals("fileName", "target/EnhancedRollingFileAppender/time.log", time.getFileName());
+ assertEquals(
+ "filePattern", "target/EnhancedRollingFileAppender/time.%d{yyyy-MM-dd}.log", time.getFilePattern());
+ policy = time.getTriggeringPolicy();
+ assertTrue("is TimeBasedTriggeringPolicy", policy instanceof TimeBasedTriggeringPolicy);
+ // Size policy with custom attributes
+ appender = configuration.getAppender("SIZE");
+ assertTrue("is RollingFileAppender", appender instanceof RollingFileAppender);
+ final RollingFileAppender size = (RollingFileAppender) appender;
+ assertEquals("append", false, size.getManager().isAppend());
+ assertEquals("bufferSize", 1000, size.getManager().getBufferSize());
+ assertEquals("immediateFlush", false, size.getImmediateFlush());
+ assertEquals("fileName", "target/EnhancedRollingFileAppender/size.log", size.getFileName());
+ assertEquals("filePattern", "target/EnhancedRollingFileAppender/size.%i.log", size.getFilePattern());
+ policy = size.getTriggeringPolicy();
+ assertTrue("is SizeBasedTriggeringPolicy", policy instanceof SizeBasedTriggeringPolicy);
+ assertEquals(10_000_000L, ((SizeBasedTriggeringPolicy) policy).getMaxFileSize());
+ strategy = size.getManager().getRolloverStrategy();
+ assertTrue("is DefaultRolloverStrategy", strategy instanceof DefaultRolloverStrategy);
+ defaultRolloverStrategy = (DefaultRolloverStrategy) strategy;
+ assertEquals(11, defaultRolloverStrategy.getMinIndex());
+ assertEquals(20, defaultRolloverStrategy.getMaxIndex());
+ }
+
+ protected void testLevelRangeFilter() throws Exception {
+ try (final LoggerContext ctx = configure("config-1.2/log4j-LevelRangeFilter")) {
+ final Configuration config = ctx.getConfiguration();
+ final Logger logger = LogManager.getLogger(PropertiesConfigurationTest.class);
+ // List appender
+ final Appender appender = config.getAppender("LIST");
+ assertNotNull(appender);
+ final ListAppender legacyAppender = (ListAppender) ((Adapter) appender).getAppender();
+ // deny
+ logger.trace("TRACE");
+ assertEquals(0, legacyAppender.getEvents().size());
+ // deny
+ logger.debug("DEBUG");
+ assertEquals(0, legacyAppender.getEvents().size());
+ // accept
+ logger.info("INFO");
+ assertEquals(1, legacyAppender.getEvents().size());
+ // accept
+ logger.warn("WARN");
+ assertEquals(2, legacyAppender.getEvents().size());
+ // accept
+ logger.error("ERROR");
+ assertEquals(3, legacyAppender.getEvents().size());
+ // deny
+ logger.fatal("FATAL");
+ assertEquals(3, legacyAppender.getEvents().size());
+ }
+ }
}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
index fa982579160..4ba9c2c8ae0 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
@@ -63,7 +63,7 @@ public class PropertiesConfigurationTest extends AbstractLog4j1ConfigurationTest
@Override
Configuration getConfiguration(final String configResourcePrefix) throws URISyntaxException, IOException {
final String configResource = configResourcePrefix + SUFFIX;
- final InputStream inputStream = ClassLoader.getSystemResourceAsStream(configResource);
+ final InputStream inputStream = getResourceAsStream(configResource);
final ConfigurationSource source = new ConfigurationSource(inputStream);
final LoggerContext context = LoggerContext.getContext(false);
final Configuration configuration = new PropertiesConfigurationFactory().getConfiguration(context, source);
@@ -127,10 +127,38 @@ public void testConsoleAppenderLevelRangeFilter() throws Exception {
final Filterable filterable = (Filterable) appender;
final CompositeFilter filter = (CompositeFilter) filterable.getFilter();
final org.apache.logging.log4j.core.Filter[] filters = filter.getFiltersArray();
- final LevelRangeFilter customFilterReal = (LevelRangeFilter) filters[0];
- assertEquals(Level.ALL, customFilterReal.getMinLevel());
- final LevelRangeFilter defaultFilter = (LevelRangeFilter) filters[1];
- assertEquals(Level.TRACE, defaultFilter.getMinLevel());
+ final LevelRangeFilter filter1 = (LevelRangeFilter) filters[0];
+ // XXX: LOG4J2-2315
+ assertEquals(Level.OFF, filter1.getMinLevel());
+ assertEquals(Level.ALL, filter1.getMaxLevel());
+ final LevelRangeFilter filter2 = (LevelRangeFilter) filters[1];
+ assertEquals(Level.ERROR, filter2.getMinLevel());
+ assertEquals(Level.INFO, filter2.getMaxLevel());
+ final LevelRangeFilter filter3 = (LevelRangeFilter) filters[2];
+ assertEquals(Level.OFF, filter3.getMinLevel());
+ assertEquals(Level.ALL, filter3.getMaxLevel());
+
+ final ListAppender legacyAppender = (ListAppender) ((AppenderAdapter.Adapter) appender).getAppender();
+ final Logger logger = LogManager.getLogger(PropertiesConfigurationTest.class);
+
+ // deny
+ logger.trace("TRACE");
+ assertEquals(0, legacyAppender.getEvents().size());
+ // deny
+ logger.debug("DEBUG");
+ assertEquals(0, legacyAppender.getEvents().size());
+ // accept
+ logger.info("INFO");
+ assertEquals(1, legacyAppender.getEvents().size());
+ // accept
+ logger.warn("WARN");
+ assertEquals(2, legacyAppender.getEvents().size());
+ // accept
+ logger.error("ERROR");
+ assertEquals(3, legacyAppender.getEvents().size());
+ // deny
+ logger.fatal("FATAL");
+ assertEquals(3, legacyAppender.getEvents().size());
}
}
@@ -321,4 +349,19 @@ public void testUntrimmedValues() throws Exception {
public void testGlobalThreshold() throws Exception {
super.testGlobalThreshold();
}
+
+ @Test
+ public void testEnhancedRollingFileAppender() throws Exception {
+ try (final LoggerContext ctx = configure("config-1.2/log4j-EnhancedRollingFileAppender")) {
+ final Configuration configuration = ctx.getConfiguration();
+ assertNotNull(configuration);
+ testEnhancedRollingFileAppender(configuration);
+ }
+ }
+
+ @Override
+ @Test
+ public void testLevelRangeFilter() throws Exception {
+ super.testLevelRangeFilter();
+ }
}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
index 500d0caad5d..eb934c085e6 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.log4j.config;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -34,6 +35,11 @@
import org.apache.log4j.xml.XmlConfigurationFactory;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.RollingFileAppender;
+import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.test.junit.ConfigurationFactoryType;
@@ -51,8 +57,7 @@ public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest {
@Override
Configuration getConfiguration(final String configResourcePrefix) throws URISyntaxException, IOException {
final String configResource = configResourcePrefix + SUFFIX;
- final InputStream inputStream = ClassLoader.getSystemResourceAsStream(configResource);
- assertNotNull(inputStream);
+ final InputStream inputStream = getResourceAsStream(configResource);
final ConfigurationSource source = new ConfigurationSource(inputStream);
final LoggerContext context = LoggerContext.getContext(false);
final Configuration configuration = context.getConfiguration(source);
@@ -181,4 +186,28 @@ public void testMultipleFilters(final @TempDir Path tmpFolder) throws Exception
public void testGlobalThreshold() throws Exception {
super.testGlobalThreshold();
}
+
+ @Test
+ public void testEnhancedRollingFileAppender() throws Exception {
+ try (final LoggerContext ctx = configure("config-1.2/log4j-EnhancedRollingFileAppender")) {
+ final Configuration configuration = ctx.getConfiguration();
+ assertNotNull(configuration);
+ testEnhancedRollingFileAppender(configuration);
+ // Only supported through XML configuration
+ final Appender appender = configuration.getAppender("MIXED");
+ assertTrue(appender instanceof RollingFileAppender, "is RollingFileAppender");
+ final TriggeringPolicy policy = ((RollingFileAppender) appender).getTriggeringPolicy();
+ assertTrue(policy instanceof CompositeTriggeringPolicy, "is CompositeTriggeringPolicy");
+ final TriggeringPolicy[] policies = ((CompositeTriggeringPolicy) policy).getTriggeringPolicies();
+ assertEquals(2, policies.length);
+ assertTrue(policies[0] instanceof TimeBasedTriggeringPolicy, "is TimeBasedTriggeringPolicy");
+ assertTrue(policies[1] instanceof SizeBasedTriggeringPolicy, "is SizeBasedTriggeringPolicy");
+ }
+ }
+
+ @Override
+ @Test
+ public void testLevelRangeFilter() throws Exception {
+ super.testLevelRangeFilter();
+ }
}
diff --git a/log4j-1.2-api/src/test/resources/LOG4J2-3326.properties b/log4j-1.2-api/src/test/resources/LOG4J2-3326.properties
index d417fb85c71..9fc31300b5f 100644
--- a/log4j-1.2-api/src/test/resources/LOG4J2-3326.properties
+++ b/log4j-1.2-api/src/test/resources/LOG4J2-3326.properties
@@ -15,9 +15,12 @@
# limitations under the License.
#
-log4j.appender.CUSTOM=org.apache.log4j.CustomNoopAppender
+log4j.appender.CUSTOM=org.apache.log4j.ListAppender
log4j.appender.CUSTOM.filter.1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.CUSTOM.filter.1.levelMin=ALL
log4j.appender.CUSTOM.filter.2=org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.CUSTOM.filter.2.levelMin=INFO
+log4j.appender.CUSTOM.filter.2.levelMax=ERROR
+log4j.appender.CUSTOM.filter.3=org.apache.log4j.varia.LevelRangeFilter
log4j.rootLogger=trace, CUSTOM
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.properties
new file mode 100644
index 00000000000..a0ef860d21c
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.properties
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+###############################################################################
+#
+# Log4J 1.2 Configuration.
+#
+
+log4j.rootLogger=TRACE, DEFAULT_TIME, DEFAULT_SIZE, TIME, SIZE
+
+log4j.appender.DEFAULT_TIME = org.apache.log4j.rolling.RollingFileAppender
+log4j.appender.DEFAULT_TIME.layout = org.apache.log4j.SimpleLayout
+log4j.appender.DEFAULT_TIME.File = target/EnhancedRollingFileAppender/defaultTime.log
+log4j.appender.DEFAULT_TIME.rollingPolicy = org.apache.log4j.rolling.TimeBasedRollingPolicy
+log4j.appender.DEFAULT_TIME.rollingPolicy.FileNamePattern = target/EnhancedRollingFileAppender/defaultTime.%d{yyyy-MM-dd}.log
+
+log4j.appender.DEFAULT_SIZE = org.apache.log4j.rolling.RollingFileAppender
+log4j.appender.DEFAULT_SIZE.File = target/EnhancedRollingFileAppender/defaultSize.log
+log4j.appender.DEFAULT_SIZE.layout = org.apache.log4j.SimpleLayout
+log4j.appender.DEFAULT_SIZE.triggeringPolicy = org.apache.log4j.rolling.SizeBasedTriggeringPolicy
+log4j.appender.DEFAULT_SIZE.rollingPolicy = org.apache.log4j.rolling.FixedWindowRollingPolicy
+log4j.appender.DEFAULT_SIZE.rollingPolicy.FileNamePattern = target/EnhancedRollingFileAppender/defaultSize.%i.log
+
+log4j.appender.TIME = org.apache.log4j.rolling.RollingFileAppender
+log4j.appender.TIME.Append = false
+log4j.appender.TIME.BufferedIO = true
+log4j.appender.TIME.BufferSize = 1000
+log4j.appender.TIME.File = target/EnhancedRollingFileAppender/ignoredTime.log
+log4j.appender.TIME.ImmediateFlush = false
+log4j.appender.TIME.layout = org.apache.log4j.SimpleLayout
+log4j.appender.TIME.triggeringPolicy = org.apache.log4j.rolling.TimeBasedRollingPolicy
+# It is explicitly not a TimeBasedRolling
+log4j.appender.TIME.rollingPolicy = org.apache.log4j.rolling.FixedWindowRollingPolicy
+log4j.appender.TIME.rollingPolicy.ActiveFileName = target/EnhancedRollingFileAppender/time.log
+log4j.appender.TIME.rollingPolicy.FileNamePattern = target/EnhancedRollingFileAppender/time.%d{yyyy-MM-dd}.log
+
+log4j.appender.SIZE = org.apache.log4j.rolling.RollingFileAppender
+log4j.appender.SIZE.Append = false
+log4j.appender.SIZE.BufferedIO = true
+log4j.appender.SIZE.BufferSize = 1000
+log4j.appender.SIZE.File = target/EnhancedRollingFileAppender/ignoredSize.log
+log4j.appender.SIZE.ImmediateFlush = false
+log4j.appender.SIZE.layout = org.apache.log4j.SimpleLayout
+log4j.appender.SIZE.FileName = target/EnhancedRollingFileAppender/size.log
+log4j.appender.SIZE.triggeringPolicy = org.apache.log4j.rolling.SizeBasedTriggeringPolicy
+log4j.appender.SIZE.triggeringPolicy.MaxFileSize = 10000000
+log4j.appender.SIZE.rollingPolicy = org.apache.log4j.rolling.FixedWindowRollingPolicy
+log4j.appender.SIZE.rollingPolicy.ActiveFileName = target/EnhancedRollingFileAppender/size.log
+log4j.appender.SIZE.rollingPolicy.FileNamePattern = target/EnhancedRollingFileAppender/size.%i.log
+log4j.appender.SIZE.rollingPolicy.MinIndex = 11
+log4j.appender.SIZE.rollingPolicy.MaxIndex = 20
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.xml b/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.xml
new file mode 100644
index 00000000000..a568dc21ca2
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.properties
new file mode 100644
index 00000000000..b84788b417d
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.properties
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+log4j.appender.LIST = org.apache.log4j.ListAppender
+log4j.appender.LIST.filter.1 = org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.LIST.filter.1.LevelMin = INFO
+log4j.appender.LIST.filter.1.LevelMax = ERROR
+log4j.appender.LIST.filter.1.AcceptOnMatch = false
+log4j.rootLogger = debug, LIST
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.xml b/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.xml
new file mode 100644
index 00000000000..ab4cdd7e5a4
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 7d4adbc4f9e..e0402cd5688 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
@@ -265,16 +265,10 @@ public Result filter(
return filter(level);
}
- /**
- * @return the minimum level threshold
- */
public Level getMinLevel() {
return minLevel;
}
- /**
- * @return the maximum level threshold
- */
public Level getMaxLevel() {
return maxLevel;
}
diff --git a/pom.xml b/pom.xml
index 33111db267d..f1d578c2d3f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,7 +31,7 @@
org.apache.logging
logging-parent
- 10.5.0
+ 10.6.0
diff --git a/src/changelog/.3.x.x/update_org_apache_logging_logging_parent.xml b/src/changelog/.3.x.x/update_org_apache_logging_logging_parent.xml
index 4eaf7d0ed4b..cb1345c9140 100644
--- a/src/changelog/.3.x.x/update_org_apache_logging_logging_parent.xml
+++ b/src/changelog/.3.x.x/update_org_apache_logging_logging_parent.xml
@@ -3,6 +3,6 @@
xmlns="http://logging.apache.org/log4j/changelog"
xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.3.xsd"
type="updated">
-
- Update `org.apache.logging:logging-parent` to version `10.5.0`
+
+ Update `org.apache.logging:logging-parent` to version `10.6.0`
diff --git a/src/site/_release-notes/_3.x.x.adoc b/src/site/_release-notes/_3.x.x.adoc
index bc2b6fcdf19..0b495a76f1f 100644
--- a/src/site/_release-notes/_3.x.x.adoc
+++ b/src/site/_release-notes/_3.x.x.adoc
@@ -59,7 +59,7 @@ This release contains...
* Update `com.fasterxml.jackson:jackson-bom` to version `2.16.1` (https://github.com/apache/logging-log4j2/pull/2127[2127])
* Update `com.github.h-thurow:simple-jndi` to version `0.24.0` (https://github.com/apache/logging-log4j2/pull/2195[2195])
* Update `org.apache.groovy:groovy-bom` to version `4.0.17` (https://github.com/apache/logging-log4j2/pull/2124[2124])
-* Update `org.apache.logging:logging-parent` to version `10.5.0` (https://github.com/apache/logging-log4j2/pull/2118[2118])
+* Update `org.apache.logging:logging-parent` to version `10.6.0` (https://github.com/apache/logging-log4j2/pull/2193[2193])
* Update `org.apache.maven.surefire:surefire-junit47` to version `3.2.5` (https://github.com/apache/logging-log4j2/pull/2177[2177])
* Update `org.apache.tomcat:tomcat-juli` to version `10.1.18` (https://github.com/apache/logging-log4j2/pull/2176[2176])
* Update `org.assertj:assertj-core` to version `3.25.1` (https://github.com/apache/logging-log4j2/pull/2152[2152])