You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2020/08/01 19:31:56 UTC
[logging-log4j2] branch master updated: LOG4J2-2901 - Missing
configuration files should be ignored when creating a composite
configuration
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/master by this push:
new 5f67313 LOG4J2-2901 - Missing configuration files should be ignored when creating a composite configuration
5f67313 is described below
commit 5f67313e61599fd18452932068afd04e48fb866c
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sat Aug 1 12:31:46 2020 -0700
LOG4J2-2901 - Missing configuration files should be ignored when creating a composite configuration
---
.../log4j/core/config/ConfigurationFactory.java | 18 +++++--
.../log4j/core/config/ConfigurationSource.java | 56 +++++++++++++++-------
.../log4j/core/impl/Log4jContextFactory.java | 35 ++++++++++----
.../config/CompositeConfigurationMissingTest.java | 48 +++++++++++++++++++
.../core/config/CompositeConfigurationTest.java | 19 ++++++++
.../src/test/resources/log4j-comp-logger-root.xml | 4 +-
.../log4j/web/Log4jWebInitializerImplTest.java | 2 +-
.../src/test/resources/log4j2-combined.xml | 39 +++++----------
.../src/test/resources/log4j2-override.xml | 31 ++----------
src/changes/changes.xml | 3 ++
10 files changed, 169 insertions(+), 86 deletions(-)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
index 7112f56..f89d11f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
@@ -403,14 +403,22 @@ public abstract class ConfigurationFactory extends ConfigurationBuilderFactory {
final List<AbstractConfiguration> configs = new ArrayList<>();
for (final String sourceLocation : sources) {
final Configuration config = getConfiguration(loggerContext, sourceLocation.trim());
- if (config != null && config instanceof AbstractConfiguration) {
- configs.add((AbstractConfiguration) config);
+ if (config != null) {
+ if (config instanceof AbstractConfiguration) {
+ configs.add((AbstractConfiguration) config);
+ } else {
+ LOGGER.error("Failed to created configuration at {}", sourceLocation);
+ return null;
+ }
} else {
- LOGGER.error("Failed to created configuration at {}", sourceLocation);
- return null;
+ LOGGER.warn("Unable to create configuration for {}, ignoring", sourceLocation);
}
}
- return new CompositeConfiguration(configs);
+ if (configs.size() > 1) {
+ return new CompositeConfiguration(configs);
+ } else if (configs.size() == 1) {
+ return configs.get(0);
+ }
}
return getConfiguration(loggerContext, configLocationStr);
} else {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
index ad94891..4db5ce3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
@@ -31,12 +31,18 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.Objects;
-import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.net.UrlConnectionFactory;
+import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
+import org.apache.logging.log4j.core.util.AuthorizationProvider;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Source;
import org.apache.logging.log4j.util.LoaderUtil;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+import javax.net.ssl.HttpsURLConnection;
/**
* Represents the source for the logging configuration.
@@ -320,6 +326,7 @@ public class ConfigurationSource {
if (source != null) {
return source;
}
+ return null;
}
if (!configLocation.isAbsolute()) { // LOG4J2-704 avoid confusing error message thrown by uri.toURL()
ConfigurationFactory.LOGGER.error("File not found in file system or classpath: {}", configLocation.toString());
@@ -331,6 +338,8 @@ public class ConfigurationSource {
InputStream is = urlConnection.getInputStream();
long lastModified = urlConnection.getLastModified();
return new ConfigurationSource(is, configLocation.toURL(), lastModified);
+ } catch (final FileNotFoundException ex) {
+ ConfigurationFactory.LOGGER.warn("Could not locate file {}", configLocation.toString());
} catch (final MalformedURLException ex) {
ConfigurationFactory.LOGGER.error("Invalid URL {}", configLocation.toString(), ex);
} catch (final Exception ex) {
@@ -350,25 +359,38 @@ public class ConfigurationSource {
if (url == null) {
return null;
}
- InputStream is = null;
+ return getConfigurationSource(url);
+ }
+
+ private static ConfigurationSource getConfigurationSource(URL url) {
try {
- is = url.openStream();
- } catch (final IOException ioe) {
- ConfigurationFactory.LOGGER.catching(Level.DEBUG, ioe);
- return null;
- }
- if (is == null) {
- return null;
- }
-
- if (FileUtils.isFile(url)) {
+ URLConnection urlConnection = url.openConnection();
+ AuthorizationProvider provider = ConfigurationFactory.authorizationProvider(PropertiesUtil.getProperties());
+ provider.addAuthorization(urlConnection);
+ if (url.getProtocol().equals(HTTPS)) {
+ SslConfiguration sslConfiguration = SslConfigurationFactory.getSslConfiguration();
+ if (sslConfiguration != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ if (!sslConfiguration.isVerifyHostName()) {
+ ((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ }
+ }
+ }
+ File file = FileUtils.fileFromUri(url.toURI());
try {
- return new ConfigurationSource(is, FileUtils.fileFromUri(url.toURI()));
- } catch (final URISyntaxException ex) {
- // Just ignore the exception.
- ConfigurationFactory.LOGGER.catching(Level.DEBUG, ex);
+ if (file != null) {
+ return new ConfigurationSource(urlConnection.getInputStream(), FileUtils.fileFromUri(url.toURI()));
+ } else {
+ return new ConfigurationSource(urlConnection.getInputStream(), url, urlConnection.getLastModified());
+ }
+ } catch (FileNotFoundException ex) {
+ ConfigurationFactory.LOGGER.info("Unable to locate file {}, ignoring.", url.toString());
+ return null;
}
+ } catch (IOException | URISyntaxException ex) {
+ ConfigurationFactory.LOGGER.warn("Error accessing {} due to {}, ignoring.", url.toString(),
+ ex.getMessage());
+ return null;
}
- return new ConfigurationSource(is, url);
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
index 1ca8280..56d0e78 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
@@ -24,6 +24,7 @@ import java.util.Objects;
import org.apache.logging.log4j.core.LifeCycle;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
+import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
@@ -265,18 +266,34 @@ public class Log4jContextFactory implements LoggerContextFactory, ShutdownCallba
for (final URI configLocation : configLocations) {
final Configuration currentReadConfiguration = ConfigurationFactory.getInstance()
.getConfiguration(ctx, name, configLocation);
- if (currentReadConfiguration instanceof AbstractConfiguration) {
- configurations.add((AbstractConfiguration) currentReadConfiguration);
+ if (currentReadConfiguration != null) {
+ if (currentReadConfiguration instanceof DefaultConfiguration) {
+ LOGGER.warn("Unable to locate configuration {}, ignoring", configLocation.toString());
+ }
+ else if (currentReadConfiguration instanceof AbstractConfiguration) {
+ configurations.add((AbstractConfiguration) currentReadConfiguration);
+ } else {
+ LOGGER.error(
+ "Found configuration {}, which is not an AbstractConfiguration and can't be handled by CompositeConfiguration",
+ configLocation);
+ }
} else {
- LOGGER.error(
- "Found configuration {}, which is not an AbstractConfiguration and can't be handled by CompositeConfiguration",
- configLocation);
+ LOGGER.info("Unable to access configuration {}, ignoring", configLocation.toString());
}
}
- final CompositeConfiguration compositeConfiguration = new CompositeConfiguration(configurations);
- LOGGER.debug("Starting LoggerContext[name={}] from configurations at {}", ctx.getName(),
- configLocations);
- ctx.start(compositeConfiguration);
+ if (configurations.size() == 0) {
+ LOGGER.error("No configurations could be created for {}", configLocations.toString());
+ } else if (configurations.size() == 1) {
+ AbstractConfiguration config = configurations.get(0);
+ LOGGER.debug("Starting LoggerContext[name={}] from configuration at {}", ctx.getName(),
+ config.getConfigurationSource().getLocation());
+ ctx.start(config);
+ } else {
+ final CompositeConfiguration compositeConfiguration = new CompositeConfiguration(configurations);
+ LOGGER.debug("Starting LoggerContext[name={}] from configurations at {}", ctx.getName(),
+ configLocations);
+ ctx.start(compositeConfiguration);
+ }
ContextAnchor.THREAD_CONTEXT.remove();
} else {
ctx.start();
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationMissingTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationMissingTest.java
new file mode 100644
index 0000000..81693a4
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationMissingTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.config;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CompositeConfigurationMissingTest {
+
+ @BeforeClass
+ public static void beforeClass() {
+ System.setProperty("log4j2.configurationFile", "classpath:log4j-comp-logger-root.xml,log4j-does-not-exist.json");
+ }
+
+ @Test
+ public void testMissingConfig() {
+ LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+
+ final AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration();
+ assertNotNull("No configuration returned", config);
+ //Test for Root log level override
+ assertEquals("Expected Root logger log level to be ERROR", Level.ERROR, config.getRootLogger().getLevel());
+
+ //Test for no cat2 level override
+ final LoggerConfig cat2 = config.getLogger("cat2");
+ assertEquals("Expected cat2 log level to be INFO", Level.DEBUG, cat2.getLevel());
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
index 845573c..ae59552 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
@@ -168,6 +168,25 @@ public class CompositeConfigurationTest {
}
@Test
+ public void testMissingConfig() {
+ final LoggerContextRule lcr = new LoggerContextRule("classpath:log4j-comp-logger-root.xml,log4j-does-not-exist.json");
+ final Statement test = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ final AbstractConfiguration config = (AbstractConfiguration) lcr.getConfiguration();
+ assertNotNull("No configuration returned", config);
+ //Test for Root log level override
+ assertEquals("Expected Root logger log level to be ERROR", Level.ERROR, config.getRootLogger().getLevel());
+
+ //Test for no cat2 level override
+ final LoggerConfig cat2 = config.getLogger("cat2");
+ assertEquals("Expected cat2 log level to be INFO", Level.DEBUG, cat2.getLevel());
+ }
+ };
+ runTest(lcr, test);
+ }
+
+ @Test
public void testAppenderRefFilterMerge() {
final LoggerContextRule lcr = new LoggerContextRule(
"classpath:log4j-comp-logger-ref.xml,log4j-comp-logger-ref.json");
diff --git a/log4j-core/src/test/resources/log4j-comp-logger-root.xml b/log4j-core/src/test/resources/log4j-comp-logger-root.xml
index dcf2605..407b3c6 100644
--- a/log4j-core/src/test/resources/log4j-comp-logger-root.xml
+++ b/log4j-core/src/test/resources/log4j-comp-logger-root.xml
@@ -16,12 +16,12 @@
limitations under the License.
-->
-<Configuration status="ERROR" name="LoggerConfigTest">
+<Configuration status="INFO" name="LoggerConfigTest">
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n"/>
</Console>
- <File name="File" fileName="${filename}" bufferedIO="false">
+ <File name="File" fileName="target/test.log" bufferedIO="false">
<PatternLayout>
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</PatternLayout>
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
index 9da3ba1..71d0cf2 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
@@ -393,7 +393,7 @@ public class Log4jWebInitializerImplTest {
public void testCompositeLocationParameterSetsCompositeConfiguration() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn("mycontext");
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(
- "/a.txt,,/WEB-INF/log4j2-mycontext.xml");
+ "log4j2-combined.xml,log4j2-override.xml");
this.initializerImpl.start();
diff --git a/log4j-core/src/test/resources/log4j-comp-logger-root.xml b/log4j-web/src/test/resources/log4j2-combined.xml
similarity index 52%
copy from log4j-core/src/test/resources/log4j-comp-logger-root.xml
copy to log4j-web/src/test/resources/log4j2-combined.xml
index dcf2605..043d972 100644
--- a/log4j-core/src/test/resources/log4j-comp-logger-root.xml
+++ b/log4j-web/src/test/resources/log4j2-combined.xml
@@ -16,29 +16,16 @@
limitations under the License.
-->
-<Configuration status="ERROR" name="LoggerConfigTest">
- <Appenders>
- <Console name="STDOUT">
- <PatternLayout pattern="%m%n"/>
- </Console>
- <File name="File" fileName="${filename}" bufferedIO="false">
- <PatternLayout>
- <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
- </PatternLayout>
- </File>
- </Appenders>
-
- <Loggers>
- <Logger name="cat1" level="debug" additivity="false">
- <AppenderRef ref="File"/>
- </Logger>
-
- <Logger name="cat2" level="debug" additivity="false">
- <AppenderRef ref="File"/>
- </Logger>
- <Root>
- <AppenderRef ref="STDOUT" />
- </Root>
- </Loggers>
-
-</Configuration>
+<Configuration status="OFF">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="%d [%t] %-5level: %msg%n%throwable" />
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Logger name="org.foo" level="DEBUG" />
+ <Root level="TRACE">
+ <AppenderRef ref="Console" />
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/log4j-core/src/test/resources/log4j-comp-logger-root.xml b/log4j-web/src/test/resources/log4j2-override.xml
similarity index 52%
copy from log4j-core/src/test/resources/log4j-comp-logger-root.xml
copy to log4j-web/src/test/resources/log4j2-override.xml
index dcf2605..bba8f9d 100644
--- a/log4j-core/src/test/resources/log4j-comp-logger-root.xml
+++ b/log4j-web/src/test/resources/log4j2-override.xml
@@ -16,29 +16,8 @@
limitations under the License.
-->
-<Configuration status="ERROR" name="LoggerConfigTest">
- <Appenders>
- <Console name="STDOUT">
- <PatternLayout pattern="%m%n"/>
- </Console>
- <File name="File" fileName="${filename}" bufferedIO="false">
- <PatternLayout>
- <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
- </PatternLayout>
- </File>
- </Appenders>
-
- <Loggers>
- <Logger name="cat1" level="debug" additivity="false">
- <AppenderRef ref="File"/>
- </Logger>
-
- <Logger name="cat2" level="debug" additivity="false">
- <AppenderRef ref="File"/>
- </Logger>
- <Root>
- <AppenderRef ref="STDOUT" />
- </Root>
- </Loggers>
-
-</Configuration>
+<Configuration>
+ <Loggers>
+ <Logger name="org.foo" level="ERROR" />
+ </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ad89e8b..ead2719 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -181,6 +181,9 @@
</action>
</release>
<release version="2.14.0" date="2020-MM-DD" description="GA Release 2.14.0">
+ <action issue="LOG4J2-2901" dev="rgoers" type="fix">
+ Missing configuration files should be ignored when creating a composite configuration.
+ </action>
<action issue="LOG4J2-2883" dev="rgoers" type="fix">
When using DirectFileRolloverStrategy the file pattern was not being recalculated on
size based rollover after a time based rollover had occurred.