This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 34447910d9c773d06311243c0c5595e5f277fe18 Author: ppkarwasz <[email protected]> AuthorDate: Mon Feb 21 20:46:57 2022 +0100 Adds Log4j 1.x global threshold (#764) The `log4j.threshold` configuration key was not translated into its Log4j 2.x equivalent global filter. Conflicts: log4j-1.2-api/src/main/java/org/apache/log4j/xml/XmlConfiguration.java --- .../log4j/config/Log4j1ConfigurationParser.java | 11 +++++ .../log4j/config/PropertiesConfiguration.java | 10 +++++ .../org/apache/log4j/xml/XmlConfiguration.java | 10 +++++ .../config/AbstractLog4j1ConfigurationTest.java | 31 +++++++++++++- .../config/Log4j1ConfigurationFactoryTest.java | 16 ++++++++ .../log4j/config/PropertiesConfigurationTest.java | 6 +++ .../apache/log4j/config/XmlConfigurationTest.java | 47 +++++++++------------- .../config-1.2/log4j-global-threshold.properties | 20 +++++++++ .../config-1.2/log4j-global-threshold.xml | 26 ++++++++++++ 9 files changed, 148 insertions(+), 29 deletions(-) diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java index d345ba0..927c154 100644 --- a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java +++ b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java @@ -25,8 +25,10 @@ import java.util.Objects; import java.util.Properties; import java.util.TreeMap; +import org.apache.log4j.LogManager; import org.apache.log4j.helpers.OptionConverter; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Filter.Result; import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.appender.FileAppender; import org.apache.logging.log4j.core.appender.NullAppender; @@ -36,10 +38,12 @@ import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; +import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; +import org.apache.logging.log4j.core.filter.ThresholdFilter; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.Strings; @@ -103,6 +107,13 @@ public class Log4j1ConfigurationParser { if (Boolean.valueOf(debugValue)) { builder.setStatusLevel(Level.DEBUG); } + // global threshold + final String threshold = OptionConverter.findAndSubst(PropertiesConfiguration.THRESHOLD_KEY, properties); + if (threshold != null) { + final Level level = OptionConverter.convertLevel(threshold.trim(), Level.ALL); + builder.add(builder.newFilter("ThresholdFilter", Result.NEUTRAL, Result.DENY) + .addAttribute("level", level)); + } // Root buildRootLogger(getLog4jValue(ROOTCATEGORY)); buildRootLogger(getLog4jValue(ROOTLOGGER)); 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 12294fd..5eb9686 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 @@ -39,11 +39,14 @@ import org.apache.log4j.bridge.FilterAdapter; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.spi.ErrorHandler; 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.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.config.status.StatusConfiguration; +import org.apache.logging.log4j.core.filter.ThresholdFilter; import org.apache.logging.log4j.util.LoaderUtil; /** @@ -66,6 +69,7 @@ public class PropertiesConfiguration extends Log4j1Configuration { */ private static final String RESET_KEY = "log4j.reset"; + public static final String THRESHOLD_KEY = "log4j.threshold"; public static final String DEBUG_KEY = "log4j.debug"; private static final String INTERNAL_ROOT_NAME = "root"; @@ -313,6 +317,12 @@ public class PropertiesConfiguration extends Log4j1Configuration { LogManager.resetConfiguration(); } + final String threshold = OptionConverter.findAndSubst(THRESHOLD_KEY, properties); + if (threshold != null) { + final Level level = OptionConverter.convertLevel(threshold.trim(), Level.ALL); + addFilter(ThresholdFilter.createFilter(level, Result.NEUTRAL, Result.DENY)); + } + configureRoot(properties); parseLoggers(properties); 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 ca7941e..dc8e940 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 @@ -45,10 +45,12 @@ import org.apache.log4j.spi.AppenderAttachable; import org.apache.log4j.spi.ErrorHandler; import org.apache.log4j.spi.Filter; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.Filter.Result; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.config.status.StatusConfiguration; +import org.apache.logging.log4j.core.filter.ThresholdFilter; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.LoaderUtil; import org.w3c.dom.Document; @@ -89,6 +91,7 @@ public class XmlConfiguration extends Log4j1Configuration { private static final String ADDITIVITY_ATTR = "additivity"; private static final String CONFIG_DEBUG_ATTR = "configDebug"; private static final String INTERNAL_DEBUG_ATTR = "debug"; + private static final String THRESHOLD_ATTR = "threshold"; private static final String EMPTY_STR = ""; private static final Class[] ONE_STRING_PARAM = new Class[]{String.class}; private static final String dbfKey = "javax.xml.parsers.DocumentBuilderFactory"; @@ -755,6 +758,13 @@ public class XmlConfiguration extends Log4j1Configuration { final StatusConfiguration statusConfig = new StatusConfiguration().setStatus(status); statusConfig.initialize(); + final String threshold = subst(element.getAttribute(THRESHOLD_ATTR)); + if (threshold != null) { + final org.apache.logging.log4j.Level level = OptionConverter.convertLevel(threshold.trim(), + org.apache.logging.log4j.Level.ALL); + addFilter(ThresholdFilter.createFilter(level, Result.NEUTRAL, Result.DENY)); + } + forEachElement(element.getChildNodes(), (currentElement) -> { switch (currentElement.getTagName()) { case CATEGORY: case LOGGER_ELEMENT: 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 ce42bbd..6ba1373 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 @@ -43,6 +43,7 @@ import org.apache.log4j.bridge.FilterAdapter; import org.apache.log4j.bridge.FilterWrapper; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.ConsoleAppender; @@ -62,6 +63,7 @@ import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.filter.CompositeFilter; import org.apache.logging.log4j.core.filter.Filterable; +import org.apache.logging.log4j.core.filter.ThresholdFilter; import org.apache.logging.log4j.core.layout.HtmlLayout; import org.apache.logging.log4j.core.layout.PatternLayout; import org.apache.logging.log4j.core.util.CloseShieldOutputStream; @@ -70,7 +72,7 @@ public abstract class AbstractLog4j1ConfigurationTest { abstract Configuration getConfiguration(String configResourcePrefix) throws URISyntaxException, IOException; - private LoggerContext configure(String configResourcePrefix) throws URISyntaxException, IOException { + protected LoggerContext configure(String configResourcePrefix) throws URISyntaxException, IOException { Configurator.reconfigure(getConfiguration(configResourcePrefix)); return (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false); } @@ -494,4 +496,31 @@ public abstract class AbstractLog4j1ConfigurationTest { System.clearProperty("test.tmpDir"); } } + + public void testGlobalThreshold() throws Exception { + try (final LoggerContext ctx = configure("config-1.2/log4j-global-threshold")) { + final Configuration config = ctx.getConfiguration(); + final Filter filter = config.getFilter(); + assertTrue(filter instanceof ThresholdFilter); + ThresholdFilter thresholdFilter = (ThresholdFilter)filter; + assertEquals(Level.INFO, thresholdFilter.getLevel()); + assertEquals(Filter.Result.NEUTRAL, thresholdFilter.getOnMatch()); + assertEquals(Filter.Result.DENY, thresholdFilter.getOnMismatch()); + + final Logger logger = LogManager.getLogger(PropertiesConfigurationTest.class); + // List appender + final Appender appender = config.getAppender("LIST"); + assertNotNull(appender); + final ListAppender legacyAppender = (ListAppender) ((Adapter) appender).getAppender(); + // Stopped by root logger level + logger.trace("TRACE"); + assertEquals(0, legacyAppender.getEvents().size()); + // Stopped by global threshold + logger.debug("DEBUG"); + assertEquals(0, legacyAppender.getEvents().size()); + // Accepted + logger.info("INFO"); + assertEquals(1, legacyAppender.getEvents().size()); + } + } } diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java index 26c000a..5b591a6 100644 --- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java +++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java @@ -29,11 +29,14 @@ import java.net.URL; import org.apache.log4j.layout.Log4j1XmlLayout; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.appender.ConsoleAppender.Target; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.filter.ThresholdFilter; import org.apache.logging.log4j.core.layout.PatternLayout; import org.junit.Test; @@ -173,4 +176,17 @@ public class Log4j1ConfigurationFactoryTest extends AbstractLog4j1ConfigurationT fail(e.getMessage()); } } + + @Test + public void testGlobalThreshold() throws Exception { + try (final LoggerContext ctx = configure("config-1.2/log4j-global-threshold")) { + final Configuration config = ctx.getConfiguration(); + final Filter filter = config.getFilter(); + assertTrue(filter instanceof ThresholdFilter); + ThresholdFilter thresholdFilter = (ThresholdFilter)filter; + assertEquals(Level.INFO, thresholdFilter.getLevel()); + assertEquals(Filter.Result.NEUTRAL, thresholdFilter.getOnMatch()); + assertEquals(Filter.Result.DENY, thresholdFilter.getOnMismatch()); + } + } } 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 ab490f7..d87a31a 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 @@ -311,4 +311,10 @@ public class PropertiesConfigurationTest extends AbstractLog4j1ConfigurationTest } } + @Override + @Test + public void testGlobalThreshold() throws Exception { + super.testGlobalThreshold(); + } + } 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 1b9c0e9..f567d26 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,17 @@ */ package org.apache.log4j.config; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + import org.apache.log4j.ListAppender; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -27,24 +38,10 @@ import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.Configurator; -import org.apache.logging.log4j.spi.LoggerContextFactory; import org.apache.logging.log4j.util.LazyValue; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * Test configuration from XML. */ @@ -69,7 +66,7 @@ public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest { @Test public void testXML() throws Exception { - configure("target/test-classes/log4j1-file.xml"); + configure("log4j1-file"); Logger logger = LogManager.getLogger("test"); logger.debug("This is a test of the root logger"); File file = new File("target/temp.A1"); @@ -82,7 +79,7 @@ public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest { @Test public void testListAppender() throws Exception { - LoggerContext loggerContext = configure("target/test-classes/log4j1-list.xml"); + LoggerContext loggerContext = configure("log4j1-list"); Logger logger = LogManager.getLogger("test"); logger.debug("This is a test of the root logger"); Configuration configuration = loggerContext.getConfiguration(); @@ -104,18 +101,6 @@ public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest { assertTrue(messages != null && messages.size() > 0, "No messages"); } - private LoggerContext configure(String configLocation) throws Exception { - File file = new File(configLocation); - InputStream is = new FileInputStream(file); - ConfigurationSource source = new ConfigurationSource(is, file); - LoggerContextFactory factory = org.apache.logging.log4j.LogManager.getFactory(); - LoggerContext context = (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false); - Configuration configuration = new XmlConfigurationFactory().getConfiguration(context, source); - assertNotNull(configuration, "No configuration created"); - Configurator.reconfigure(configuration); - return context; - } - @Override @Test public void testConsoleEnhancedPatternLayout() throws Exception { @@ -194,4 +179,10 @@ public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest { super.testMultipleFilters(tmpFolder); } + @Override + @Test + public void testGlobalThreshold() throws Exception { + super.testGlobalThreshold(); + } + } diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.properties new file mode 100644 index 0000000..f76d396 --- /dev/null +++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.properties @@ -0,0 +1,20 @@ +# +# 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.threshold = info +log4j.appender.LIST = org.apache.log4j.ListAppender +log4j.rootLogger = debug, LIST diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.xml b/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.xml new file mode 100644 index 0000000..fb969ca --- /dev/null +++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-global-threshold.xml @@ -0,0 +1,26 @@ +<?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. +--> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" threshold="info"> + <appender name="LIST" class="org.apache.log4j.ListAppender" /> + + <root> + <priority value="debug" /> + <appender-ref ref="LIST" /> + </root> +</log4j:configuration>
