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/13 18:51:19 UTC

[logging-log4j2] 01/02: LOG4J2-2908 - Move Spring Lookup and Spring properties to a new Spring Boot module

This is an automated email from the ASF dual-hosted git repository.

rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit bc3265e6bb3436b5cc136f2097d159ad84cab91e
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Wed Aug 12 11:19:34 2020 -0700

    LOG4J2-2908 - Move Spring Lookup and Spring properties to a new Spring Boot module
---
 log4j-bom/pom.xml                                  | 10 +++-
 .../logging/log4j/core/config/Configurator.java    | 22 ++++++++
 .../log4j/core/impl/Log4jContextFactory.java       | 21 ++++++++
 .../core/selector/ClassLoaderContextSelector.java  | 22 ++++++--
 .../log4j/core/selector/ContextSelector.java       | 38 ++++++++++++++
 log4j-distribution/pom.xml                         | 23 +++++++--
 .../pom.xml                                        | 40 +++++++++------
 .../boot}/Log4j2CloudConfigLoggingSystem.java      |  2 +-
 .../spring/boot}/SpringEnvironmentHolder.java      |  2 +-
 .../logging/log4j/spring/boot}/SpringLookup.java   |  2 +-
 .../log4j/spring/boot}/SpringPropertySource.java   |  2 +-
 .../org.apache.logging.log4j.util.PropertySource   |  3 +-
 .../src/main/resources/log4j2.system.properties    |  2 +-
 log4j-spring-boot/src/site/markdown/index.md       | 60 ++++++++++++++++++++++
 log4j-spring-boot/src/site/site.xml                | 52 +++++++++++++++++++
 .../log4j/spring/boot}/SpringLookupTest.java       |  2 +-
 .../log4j-spring-cloud-config-client/pom.xml       | 17 ++----
 .../org.apache.logging.log4j.util.PropertySource   | 15 ------
 log4j-spring-cloud-config/pom.xml                  |  8 +--
 .../logging/log4j/web/Log4jWebInitializerImpl.java |  9 ++--
 .../logging/log4j/web/WebLoggerContextUtils.java   | 21 +++++++-
 .../logging/log4j/web/ServletAppenderTest.java     |  2 +-
 .../apache/logging/log4j/web/WebLookupTest.java    |  4 +-
 pom.xml                                            |  9 +++-
 24 files changed, 317 insertions(+), 71 deletions(-)

diff --git a/log4j-bom/pom.xml b/log4j-bom/pom.xml
index e663207..547265d 100644
--- a/log4j-bom/pom.xml
+++ b/log4j-bom/pom.xml
@@ -108,10 +108,10 @@
         <artifactId>log4j-couchdb</artifactId>
         <version>${project.version}</version>
       </dependency>
-      <!-- MongoDB 2 Appender Plugin -->
+      <!-- MongoDB 4 Appender Plugin -->
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
-        <artifactId>log4j-mongodb2</artifactId>
+        <artifactId>log4j-mongodb4</artifactId>
         <version>${project.version}</version>
       </dependency>
       <!-- MongoDB 3 Appender Plugin -->
@@ -168,6 +168,12 @@
         <artifactId>log4j-kubernetes</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <!-- Spring Boot support  -->
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-spring-boot</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <!-- Spring Cloud Config Client -->
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
index 57e0da7..e5aea28 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
@@ -164,6 +164,28 @@ public final class Configurator {
         return null;
     }
 
+    /**
+     * Initializes the Logging Context.
+     * @param name The Context name.
+     * @param loader The ClassLoader for the Context (or null).
+     * @param configLocation The configuration for the logging context (or null).
+     * @param entry The external context entry to be attached to the LoggerContext
+     * @return The LoggerContext.
+     */
+    public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation,
+            final Map.Entry<String, Object> entry) {
+
+        try {
+            final Log4jContextFactory factory = getFactory();
+            return factory == null ? null :
+                    factory.getContext(FQCN, loader, entry, false, configLocation, name);
+        } catch (final Exception ex) {
+            LOGGER.error("There was a problem initializing the LoggerContext [{}] using configuration at [{}].",
+                    name, configLocation, ex);
+        }
+        return null;
+    }
+
     public static LoggerContext initialize(final String name, final ClassLoader loader, final List<URI> configLocations,
             final Object externalContext) {
         try {
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 c29b668..b221d72 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
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.impl;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import org.apache.logging.log4j.core.LifeCycle;
@@ -247,6 +248,26 @@ public class Log4jContextFactory implements LoggerContextFactory, ShutdownCallba
         return ctx;
     }
 
+    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Map.Entry<String, Object> entry,
+            final boolean currentContext, final URI configLocation, final String name) {
+        final LoggerContext ctx = selector.getContext(fqcn, loader, entry, currentContext, configLocation);
+        if (name != null) {
+            ctx.setName(name);
+        }
+        if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+            if (configLocation != null || name != null) {
+                ContextAnchor.THREAD_CONTEXT.set(ctx);
+                final Configuration config = ConfigurationFactory.getInstance().getConfiguration(ctx, name, configLocation);
+                LOGGER.debug("Starting LoggerContext[name={}] from configuration at {}", ctx.getName(), configLocation);
+                ctx.start(config);
+                ContextAnchor.THREAD_CONTEXT.remove();
+            } else {
+                ctx.start();
+            }
+        }
+        return ctx;
+    }
+
     public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Object externalContext,
             final boolean currentContext, final List<URI> configLocations, final String name) {
         final LoggerContext ctx = selector
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
index f8a5e9d..2177e08 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
@@ -121,6 +121,12 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
     @Override
     public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext,
             final URI configLocation) {
+        return getContext(fqcn, loader, null, currentContext, configLocation);
+    }
+
+    @Override
+    public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Map.Entry<String, Object> entry,
+            final boolean currentContext, final URI configLocation) {
         if (currentContext) {
             final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
             if (ctx != null) {
@@ -128,11 +134,11 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
             }
             return getDefault();
         } else if (loader != null) {
-            return locateContext(loader, configLocation);
+            return locateContext(loader, entry, configLocation);
         } else {
             final Class<?> clazz = StackLocatorUtil.getCallerClass(fqcn);
             if (clazz != null) {
-                return locateContext(clazz.getClassLoader(), configLocation);
+                return locateContext(clazz.getClassLoader(), entry, configLocation);
             }
             final LoggerContext lc = ContextAnchor.THREAD_CONTEXT.get();
             if (lc != null) {
@@ -165,7 +171,8 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
         return Collections.unmodifiableList(list);
     }
 
-    private LoggerContext locateContext(final ClassLoader loaderOrNull, final URI configLocation) {
+    private LoggerContext locateContext(final ClassLoader loaderOrNull, final Map.Entry<String, Object> entry,
+            final URI configLocation) {
         // LOG4J2-477: class loader may be null
         final ClassLoader loader = loaderOrNull != null ? loaderOrNull : ClassLoader.getSystemClassLoader();
         final String name = toContextMapKey(loader);
@@ -204,6 +211,9 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
                 }
             }
             LoggerContext ctx = createContext(name, configLocation);
+            if (entry != null) {
+                ctx.putObject(entry.getKey(), entry.getValue());
+            }
             LoggerContext newContext = CONTEXT_MAP.computeIfAbsent(name,
                     k -> new AtomicReference<>(new WeakReference<>(ctx))).get().get();
             if (newContext == ctx) {
@@ -214,6 +224,9 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
         final WeakReference<LoggerContext> weakRef = ref.get();
         LoggerContext ctx = weakRef.get();
         if (ctx != null) {
+            if (entry != null && ctx.getObject(entry.getKey()) == null) {
+                ctx.putObject(entry.getKey(), entry.getValue());
+            }
             if (ctx.getConfigLocation() == null && configLocation != null) {
                 LOGGER.debug("Setting configuration to {}", configLocation);
                 ctx.setConfigLocation(configLocation);
@@ -225,6 +238,9 @@ public class ClassLoaderContextSelector implements ContextSelector, LoggerContex
             return ctx;
         }
         ctx = createContext(name, configLocation);
+        if (entry != null) {
+            ctx.putObject(entry.getKey(), entry.getValue());
+        }
         ref.compareAndSet(weakRef, new WeakReference<>(ctx));
         return ctx;
     }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
index a1a892c..727ea3e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.selector;
 
 import java.net.URI;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.core.LoggerContext;
@@ -71,6 +72,23 @@ public interface ContextSelector {
      * Returns the LoggerContext.
      * @param fqcn The fully qualified class name of the caller.
      * @param loader ClassLoader to use or null.
+     * @param entry An entry for the external Context map.
+     * @param currentContext If true returns the current Context, if false returns the Context appropriate
+     * for the caller if a more appropriate Context can be determined.
+     * @return The LoggerContext.
+     */
+    default LoggerContext getContext(String fqcn, ClassLoader loader, Map.Entry<String, Object> entry, boolean currentContext) {
+        LoggerContext lc = getContext(fqcn, loader, currentContext);
+        if (lc != null) {
+            lc.putObject(entry.getKey(), entry.getValue());
+        }
+        return lc;
+    }
+
+    /**
+     * Returns the LoggerContext.
+     * @param fqcn The fully qualified class name of the caller.
+     * @param loader ClassLoader to use or null.
      * @param currentContext If true returns the current Context, if false returns the Context appropriate
      * for the caller if a more appropriate Context can be determined.
      * @param configLocation The location of the configuration for the LoggerContext.
@@ -79,6 +97,24 @@ public interface ContextSelector {
     LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation);
 
     /**
+     * Returns the LoggerContext.
+     * @param fqcn The fully qualified class name of the caller.
+     * @param loader ClassLoader to use or null.
+     * @param currentContext If true returns the current Context, if false returns the Context appropriate
+     * for the caller if a more appropriate Context can be determined.
+     * @param configLocation The location of the configuration for the LoggerContext.
+     * @return The LoggerContext.
+     */
+    default LoggerContext getContext(String fqcn, ClassLoader loader, Map.Entry<String, Object> entry,
+            boolean currentContext, URI configLocation) {
+        LoggerContext lc = getContext(fqcn, loader, currentContext, configLocation);
+        if (lc != null) {
+            lc.putObject(entry.getKey(), entry.getValue());
+        }
+        return lc;
+    }
+
+    /**
      * Returns a List of all the available LoggerContexts.
      * @return The List of LoggerContexts.
      */
@@ -89,4 +125,6 @@ public interface ContextSelector {
      * @param context The context to remove.
      */
     void removeContext(LoggerContext context);
+
+
 }
diff --git a/log4j-distribution/pom.xml b/log4j-distribution/pom.xml
index be997a5..6293d0e 100644
--- a/log4j-distribution/pom.xml
+++ b/log4j-distribution/pom.xml
@@ -274,18 +274,18 @@
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-mongodb2</artifactId>
+      <artifactId>log4j-mongodb4</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-mongodb2</artifactId>
+      <artifactId>log4j-mongodb4</artifactId>
       <version>${project.version}</version>
       <classifier>sources</classifier>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-mongodb2</artifactId>
+      <artifactId>log4j-mongodb4</artifactId>
       <version>${project.version}</version>
       <classifier>javadoc</classifier>
     </dependency>
@@ -410,6 +410,23 @@
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-spring-boot</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-spring-boot</artifactId>
+      <version>${project.version}</version>
+      <classifier>sources</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-spring-boot</artifactId>
+      <version>${project.version}</version>
+      <classifier>javadoc</classifier>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-spring-cloud-config-client</artifactId>
       <version>${project.version}</version>
     </dependency>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml b/log4j-spring-boot/pom.xml
similarity index 90%
copy from log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
copy to log4j-spring-boot/pom.xml
index dcc20ca..cfeae61 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
+++ b/log4j-spring-boot/pom.xml
@@ -19,20 +19,38 @@
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j-spring-cloud-config</artifactId>
+    <artifactId>log4j</artifactId>
     <version>2.14.0-SNAPSHOT</version>
     <relativePath>../</relativePath>
   </parent>
-  <artifactId>log4j-spring-cloud-config-client</artifactId>
+  <artifactId>log4j-spring-boot</artifactId>
   <packaging>jar</packaging>
-  <name>Apache Log4j Spring Cloud Config Client Support</name>
-  <description>Apache Log4j Spring Cloud Config Client Support</description>
+  <name>Apache Log4j Spring Boot Support</name>
+  <description>Apache Log4j Spring iBoot Support</description>
   <properties>
     <log4jParentDir>${basedir}/../..</log4jParentDir>
-    <docLabel>Log4j Spring Cloud Config Client Documentation</docLabel>
-    <projectDir>/log4j-spring-cloud-config-client</projectDir>
-    <module.name>org.apache.logging.log4j.spring.cloud.config.client</module.name>
+    <docLabel>Log4j Spring Boot Documentation</docLabel>
+    <projectDir>/log4j-spring-boot</projectDir>
+    <module.name>org.apache.logging.log4j.spring.boot</module.name>
   </properties>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-framework-bom</artifactId>
+        <version>${springVersion}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot</artifactId>
+        <version>${spring-boot.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -40,14 +58,6 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.springframework.cloud</groupId>
-      <artifactId>spring-cloud-config-client</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.cloud</groupId>
-      <artifactId>spring-cloud-bus</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot</artifactId>
     </dependency>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/Log4j2CloudConfigLoggingSystem.java
similarity index 99%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java
rename to log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/Log4j2CloudConfigLoggingSystem.java
index c41c0a8..35b6565 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java
+++ b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/Log4j2CloudConfigLoggingSystem.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.spring.cloud.config.client;
+package org.apache.logging.log4j.spring.boot;
 
 import java.io.File;
 import java.io.FileNotFoundException;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringEnvironmentHolder.java b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringEnvironmentHolder.java
similarity index 96%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringEnvironmentHolder.java
rename to log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringEnvironmentHolder.java
index 60fa511..e7fe436 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringEnvironmentHolder.java
+++ b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringEnvironmentHolder.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.spring.cloud.config.client;
+package org.apache.logging.log4j.spring.boot;
 
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookup.java b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringLookup.java
similarity index 98%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookup.java
rename to log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringLookup.java
index 7da12ea..513aaaf 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookup.java
+++ b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringLookup.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.spring.cloud.config.client;
+package org.apache.logging.log4j.spring.boot;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringPropertySource.java b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringPropertySource.java
similarity index 96%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringPropertySource.java
rename to log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringPropertySource.java
index 8ffed65..5a2b231 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/SpringPropertySource.java
+++ b/log4j-spring-boot/src/main/java/org/apache/logging/log4j/spring/boot/SpringPropertySource.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.spring.cloud.config.client;
+package org.apache.logging.log4j.spring.boot;
 
 import org.apache.logging.log4j.util.PropertySource;
 import org.springframework.core.env.Environment;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.component.properties b/log4j-spring-boot/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
similarity index 93%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.component.properties
rename to log4j-spring-boot/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
index a57801c..8903871 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.component.properties
+++ b/log4j-spring-boot/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
@@ -1,4 +1,3 @@
-#
 # 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.
@@ -13,4 +12,4 @@
 # 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.
-#
\ No newline at end of file
+org.apache.logging.log4j.spring.boot.SpringPropertySource
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties b/log4j-spring-boot/src/main/resources/log4j2.system.properties
similarity index 92%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties
rename to log4j-spring-boot/src/main/resources/log4j2.system.properties
index d2e6ae1..cc729f8 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties
+++ b/log4j-spring-boot/src/main/resources/log4j2.system.properties
@@ -14,4 +14,4 @@
 # See the license for the specific language governing permissions and
 # limitations under the license.
 #
-org.springframework.boot.logging.LoggingSystem=org.apache.logging.log4j.spring.cloud.config.client.Log4j2CloudConfigLoggingSystem
\ No newline at end of file
+org.springframework.boot.logging.LoggingSystem=org.apache.logging.log4j.spring.boot.Log4j2CloudConfigLoggingSystem
\ No newline at end of file
diff --git a/log4j-spring-boot/src/site/markdown/index.md b/log4j-spring-boot/src/site/markdown/index.md
new file mode 100644
index 0000000..325455c
--- /dev/null
+++ b/log4j-spring-boot/src/site/markdown/index.md
@@ -0,0 +1,60 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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 Spring Boot Support
+
+This module provides enhanced support for Spring Boot beyond what Spring Boot itself provides. 
+
+## Overview
+
+The components in this module require a Spring Environment to have been created. Spring Boot 
+applications initialize logging multiple times. The first initialization occurs before
+any initialization work is performed by Spring, thus no Environment will have been created
+and the components implemented in this module will not produce the desired results. Subsequent
+initializations of logging will have a Spring Environment. 
+
+
+## Usage
+
+### Spring Lookup
+
+The Spring Lookup allows configuration files to reference properties defined in Spring
+configuration files from a Log4j configuration file. For example:
+
+    <property name="applicationName">${spring:spring.application.name}</property>
+    
+would set the Log4j applicationName property to the value of spring.application.name set in the 
+Spring configuration.     
+
+### Spring Property Source
+
+Log4j uses property sources when resolving properties it uses internally. This support allows
+most of Log4j's [System Properties](http://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties)
+to be specified in the Spring Configuration. However, some properties that are only referenced
+during the first Log4j initialization, such as the property Log4j uses to allow the default 
+Log4j implementation to be chosen, would not be available.
+
+## Requirements
+
+The Log4j 2 Spring Cloud Configuration integration has a dependency on Log4j 2 API, Log4j 2 Core, and 
+Spring Boot versions 2.0.3.RELEASE or 2.1.1.RELEASE or later versions it either release series.
+For more information, see [Runtime Dependencies](../../runtime-dependencies.html).
+
+
+
+
diff --git a/log4j-spring-boot/src/site/site.xml b/log4j-spring-boot/src/site/site.xml
new file mode 100644
index 0000000..5abfffd
--- /dev/null
+++ b/log4j-spring-boot/src/site/site.xml
@@ -0,0 +1,52 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project name="Log4j Spring Cloud Config Integration"
+         xmlns="http://maven.apache.org/DECORATION/1.4.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/" />
+      <item name="Logging Services" href="http://logging.apache.org/"/>
+      <item name="Log4j" href="../index.html"/>
+    </links>
+
+    <!-- Component-specific reports -->
+    <menu ref="reports"/>
+
+	<!-- Overall Project Info -->
+    <menu name="Log4j Project Information" img="icon-info-sign">
+      <item name="Dependencies" href="../dependencies.html" />
+      <item name="Dependency Convergence" href="../dependency-convergence.html" />
+      <item name="Dependency Management" href="../dependency-management.html" />
+      <item name="Project Team" href="../team-list.html" />
+      <item name="Mailing Lists" href="../mail-lists.html" />
+      <item name="Issue Tracking" href="../issue-tracking.html" />
+      <item name="Project License" href="../license.html" />
+      <item name="Source Repository" href="../source-repository.html" />
+      <item name="Project Summary" href="../project-summary.html" />
+    </menu>
+
+    <menu name="Log4j Project Reports" img="icon-cog">
+      <item name="Changes Report" href="../changes-report.html" />
+      <item name="JIRA Report" href="../jira-report.html" />
+      <item name="Surefire Report" href="../surefire-report.html" />
+      <item name="RAT Report" href="../rat-report.html" />
+    </menu>
+  </body>
+</project>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookupTest.java b/log4j-spring-boot/src/test/java/org/apache/logging/log4j/spring/boot/SpringLookupTest.java
similarity index 97%
rename from log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookupTest.java
rename to log4j-spring-boot/src/test/java/org/apache/logging/log4j/spring/boot/SpringLookupTest.java
index 9fa8a21..f934943 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/SpringLookupTest.java
+++ b/log4j-spring-boot/src/test/java/org/apache/logging/log4j/spring/boot/SpringLookupTest.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.spring.cloud.config.client;
+package org.apache.logging.log4j.spring.boot;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.LoggerContext;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
index dcc20ca..ae200dd 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
@@ -40,6 +40,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-spring-boot</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-config-client</artifactId>
     </dependency>
@@ -48,18 +53,6 @@
       <artifactId>spring-cloud-bus</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.springframework.boot</groupId>
-      <artifactId>spring-boot</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-context-support</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest-all</artifactId>
       <scope>test</scope>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
deleted file mode 100644
index 01b50a9..0000000
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/META-INF/services/org.apache.logging.log4j.util.PropertySource
+++ /dev/null
@@ -1,15 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache license, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the license for the specific language governing permissions and
-# limitations under the license.
-org.apache.logging.log4j.spring.cloud.config.client.SpringPropertySource
diff --git a/log4j-spring-cloud-config/pom.xml b/log4j-spring-cloud-config/pom.xml
index c37f1d2..a4ed781 100644
--- a/log4j-spring-cloud-config/pom.xml
+++ b/log4j-spring-cloud-config/pom.xml
@@ -31,9 +31,9 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <revapi.skip>true</revapi.skip>
-    <spring-cloud-version>Greenwich.SR1</spring-cloud-version>
-    <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
-    <springVersion>5.1.8.RELEASE</springVersion>
+    <spring-cloud-version>Hoxton.SR7</spring-cloud-version>
+    <spring-boot.version>2.3.2.RELEASE</spring-boot.version>
+    <springVersion>5.2.8.RELEASE</springVersion>
     <log4jParentDir>${basedir}/..</log4jParentDir>
   </properties>
   <dependencyManagement>
@@ -47,7 +47,7 @@
       </dependency>
       <dependency>
         <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot</artifactId>
+        <artifactId>spring-boot-starter-parent</artifactId>
         <version>${spring-boot.version}</version>
         <type>pom</type>
         <scope>import</scope>
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
index ce36076..ba53d4f 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
@@ -133,7 +133,8 @@ final class Log4jWebInitializerImpl extends AbstractLifeCycle implements Log4jWe
             final ContextSelector selector = ((Log4jContextFactory) factory).getSelector();
             if (selector instanceof NamedContextSelector) {
                 this.namedContextSelector = (NamedContextSelector) selector;
-                context = this.namedContextSelector.locateContext(this.name, this.servletContext, configLocation);
+                context = this.namedContextSelector.locateContext(this.name,
+                        WebLoggerContextUtils.createExternalEntry(this.servletContext), configLocation);
                 ContextAnchor.THREAD_CONTEXT.set(context);
                 if (context.isInitialized()) {
                     context.start();
@@ -166,12 +167,14 @@ final class Log4jWebInitializerImpl extends AbstractLifeCycle implements Log4jWe
         }
         if (location != null && location.contains(",")) {
             final List<URI> uris = getConfigURIs(location);
-            this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uris, this.servletContext);
+            this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uris,
+                    WebLoggerContextUtils.createExternalEntry(this.servletContext));
             return;
         }
 
         final URI uri = getConfigURI(location);
-        this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uri, this.servletContext);
+        this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uri,
+                WebLoggerContextUtils.createExternalEntry(this.servletContext));
     }
 
     private List<URI> getConfigURIs(final String location) {
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/WebLoggerContextUtils.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/WebLoggerContextUtils.java
index c12e19b..a142bcc 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/WebLoggerContextUtils.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/WebLoggerContextUtils.java
@@ -16,6 +16,8 @@
  */
 package org.apache.logging.log4j.web;
 
+import java.util.AbstractMap;
+import java.util.Map;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import javax.servlet.ServletContext;
@@ -37,6 +39,7 @@ public final class WebLoggerContextUtils {
     }
 
     private static final Lock WEB_SUPPORT_LOOKUP = new ReentrantLock();
+    private static final String SERVLET_CONTEXT = "__SERVLET_CONTEXT__";
 
     /**
      * Finds the main {@link org.apache.logging.log4j.core.LoggerContext} configured for the given ServletContext.
@@ -112,6 +115,16 @@ public final class WebLoggerContextUtils {
         };
     }
 
+    public static Map.Entry<String, Object> createExternalEntry(ServletContext servletContext) {
+        return new AbstractMap.SimpleEntry<>(SERVLET_CONTEXT, servletContext);
+    }
+
+    public static void setServletContext(LoggerContext lc, ServletContext servletContext) {
+        if (lc != null) {
+            lc.putObject(SERVLET_CONTEXT, servletContext);
+        }
+    }
+
     /**
      * Gets the current {@link ServletContext} if it has already been assigned to a LoggerContext's external context.
      *
@@ -123,7 +136,11 @@ public final class WebLoggerContextUtils {
         if (lc == null) {
             lc = LogManager.getContext(false);
         }
-        return lc == null ? null :
-            lc.getExternalContext() instanceof ServletContext ? (ServletContext) lc.getExternalContext() : null;
+
+        Object obj = lc != null ? lc.getObject(SERVLET_CONTEXT) : null;
+        if (obj instanceof ServletContext) {
+            return (ServletContext) obj;
+        }
+        return null;
     }
 }
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
index 7621370..bb7147c 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
@@ -51,7 +51,7 @@ public class ServletAppenderTest {
             initializer.setLoggerContext();
             final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
             assertNotNull("No LoggerContext", ctx);
-            assertNotNull("No ServletContext", ctx.getExternalContext());
+            assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
             final Configuration configuration = ctx.getConfiguration();
             assertNotNull("No configuration", configuration);
             final Appender appender = configuration.getAppender("Servlet");
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
index a44202a..0a257ff 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
@@ -48,7 +48,7 @@ public class WebLookupTest {
             initializer.setLoggerContext();
             final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
             assertNotNull("No LoggerContext", ctx);
-            assertNotNull("No ServletContext", ctx.getExternalContext());
+            assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
             final Configuration config = ctx.getConfiguration();
             assertNotNull("No Configuration", config);
             final StrSubstitutor substitutor = config.getStrSubstitutor();
@@ -90,7 +90,7 @@ public class WebLookupTest {
         initializer.setLoggerContext();
         final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
         assertNotNull("No LoggerContext", ctx);
-        assertNotNull("No ServletContext", ctx.getExternalContext());
+        assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
         final Configuration config = ctx.getConfiguration();
         assertNotNull("No Configuration", config);
         final Map<String, Appender> appenders = config.getAppenders();
diff --git a/pom.xml b/pom.xml
index f28931a..54d6a2b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -191,7 +191,8 @@
     <logbackVersion>1.2.3</logbackVersion>
     <jackson1Version>1.9.13</jackson1Version>
     <jackson2Version>2.11.2</jackson2Version>
-    <springVersion>3.2.18.RELEASE</springVersion>
+    <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
+    <springVersion>5.1.8.RELEASE</springVersion>
     <kubernetes-client.version>4.6.1</kubernetes-client.version>
     <flumeVersion>1.9.0</flumeVersion>
     <disruptorVersion>3.4.2</disruptorVersion>
@@ -730,6 +731,11 @@
         <version>${springVersion}</version>
       </dependency>
       <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context-support</artifactId>
+        <version>${springVersion}</version>
+      </dependency>
+      <dependency>
         <groupId>io.fabric8</groupId>
         <artifactId>kubernetes-client</artifactId>
         <version>${kubernetes-client.version}</version>
@@ -1395,6 +1401,7 @@
     <module>log4j-osgi</module>
     <module>log4j-docker</module>
     <module>log4j-kubernetes</module>
+    <module>log4j-spring-boot</module>
     <module>log4j-spring-cloud-config</module>
   </modules>
   <profiles>