diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/MonitorUriTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/MonitorUriTest.java
new file mode 100644
index 00000000000..20c519afa55
--- /dev/null
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/MonitorUriTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+import static org.awaitility.Awaitility.waitAtMost;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.Configurator;
+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.properties.PropertiesConfiguration;
+import org.apache.logging.log4j.core.util.Source;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.CleanupMode;
+import org.junit.jupiter.api.io.TempDir;
+
+public class MonitorUriTest {
+
+    private static final int MONITOR_INTERVAL = 3;
+
+    @Test
+    void testReconfigureOnChangeInMonitorUri(@TempDir(cleanup = CleanupMode.ON_SUCCESS) final Path tempDir)
+            throws IOException {
+        ConfigurationBuilder<PropertiesConfiguration> configBuilder =
+                ConfigurationBuilderFactory.newConfigurationBuilder(PropertiesConfiguration.class);
+        Path config = tempDir.resolve("config.xml");
+        Path monitorUri = tempDir.resolve("monitorUri.xml");
+        ConfigurationSource configSource = new ConfigurationSource(new Source(config), new byte[] {}, 0);
+        Configuration configuration = configBuilder
+                .setConfigurationSource(configSource)
+                .setMonitorInterval(String.valueOf(MONITOR_INTERVAL))
+                .add(configBuilder.newMonitorUri(monitorUri.toUri().toString()))
+                .build();
+
+        try (LoggerContext loggerContext = Configurator.initialize(configuration)) {
+            Files.write(monitorUri, Collections.singletonList("a change"));
+            waitAtMost(MONITOR_INTERVAL + 2, TimeUnit.SECONDS)
+                    .until(() -> loggerContext.getConfiguration() != configuration);
+        }
+    }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 5b60a7727b3..ec7611b508b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -22,6 +22,7 @@
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -132,6 +133,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
     private ConcurrentMap<String, Appender> appenders = new ConcurrentHashMap<>();
     private ConcurrentMap<String, LoggerConfig> loggerConfigs = new ConcurrentHashMap<>();
     private List<CustomLevelConfig> customLevels = Collections.emptyList();
+    private List<URI> uris = Collections.emptyList();
     private final ConcurrentMap<String, String> propertyMap = new ConcurrentHashMap<>();
     private final Interpolator tempLookup = new Interpolator(propertyMap);
     private final StrSubstitutor runtimeStrSubstitutor = new RuntimeStrSubstitutor(tempLookup);
@@ -267,6 +269,7 @@ public void initialize() {
         setup();
         setupAdvertisement();
         doConfigure();
+        watchMonitorUris();
         setState(State.INITIALIZED);
         LOGGER.debug("Configuration {} initialized", this);
     }
@@ -325,7 +328,7 @@ public void start() {
         if (watchManager.getIntervalSeconds() >= 0) {
             LOGGER.info(
                     "Start watching for changes to {} every {} seconds",
-                    getConfigurationSource(),
+                    watchManager.getConfigurationWatchers().keySet(),
                     watchManager.getIntervalSeconds());
             watchManager.start();
         }
@@ -347,6 +350,17 @@ public void start() {
         LOGGER.info("Configuration {} started.", this);
     }
 
+    private void watchMonitorUris() {
+        if (this instanceof Reconfigurable && watchManager.getIntervalSeconds() >= 0) {
+            uris.stream().forEach(uri -> {
+                Source source = new Source(uri);
+                final ConfigurationFileWatcher watcher = new ConfigurationFileWatcher(
+                        this, (Reconfigurable) this, listeners, source.getFile().lastModified());
+                watchManager.watch(source, watcher);
+            });
+        }
+    }
+
     private boolean hasAsyncLoggers() {
         if (root instanceof AsyncLoggerConfig) {
             return true;
@@ -729,9 +743,16 @@ protected void doConfigure() {
             } else if (child.isInstanceOf(AsyncWaitStrategyFactoryConfig.class)) {
                 final AsyncWaitStrategyFactoryConfig awsfc = child.getObject(AsyncWaitStrategyFactoryConfig.class);
                 asyncWaitStrategyFactory = awsfc.createWaitStrategyFactory();
+            } else if (child.isInstanceOf(MonitorUris.class)) {
+                uris = convertToJavaNetUris(child.getObject(MonitorUris.class).getUris());
             } else {
                 final List<String> expected = Arrays.asList(
-                        "\"Appenders\"", "\"Loggers\"", "\"Properties\"", "\"Scripts\"", "\"CustomLevels\"");
+                        "\"Appenders\"",
+                        "\"Loggers\"",
+                        "\"Properties\"",
+                        "\"Scripts\"",
+                        "\"CustomLevels\"",
+                        "\"MonitorUris\"");
                 LOGGER.error(
                         "Unknown object \"{}\" of type {} is ignored: try nesting it inside one of: {}.",
                         child.getName(),
@@ -767,6 +788,18 @@ protected void doConfigure() {
         setParents();
     }
 
+    private List<URI> convertToJavaNetUris(final List<Uri> uris) {
+        final List<URI> javaNetUris = new ArrayList<>();
+        for (Uri uri : uris) {
+            try {
+                javaNetUris.add(new URI(uri.getUri()));
+            } catch (URISyntaxException e) {
+                throw new ConfigurationException("Invalid URI provided for MonitorUri " + uri);
+            }
+        }
+        return javaNetUris;
+    }
+
     public static Level getDefaultLevel() {
         final String levelName = PropertiesUtil.getProperties()
                 .getStringProperty(DefaultConfiguration.DEFAULT_LEVEL, Level.ERROR.name());
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/MonitorUris.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/MonitorUris.java
new file mode 100644
index 00000000000..d294e8fa083
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/MonitorUris.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+
+/**
+ * Container for MonitorUri objects.
+ */
+@Plugin(name = "MonitorUris", category = Core.CATEGORY_NAME, printObject = true)
+public final class MonitorUris {
+
+    private final List<Uri> uris;
+
+    private MonitorUris(final Uri[] uris) {
+        this.uris = new ArrayList<>(Arrays.asList(uris));
+    }
+
+    /**
+     * Create a MonitorUris object to contain all the URIs to be monitored.
+     *
+     * @param uris An array of URIs.
+     * @return A MonitorUris object.
+     */
+    @PluginFactory
+    public static MonitorUris createMonitorUris( //
+            @PluginElement("Uris") final Uri[] uris) {
+        return new MonitorUris(uris == null ? Uri.EMPTY_ARRAY : uris);
+    }
+
+    /**
+     * Returns a list of the {@code Uri} objects created during configuration.
+     * @return the URIs to be monitored
+     */
+    public List<Uri> getUris() {
+        return uris;
+    }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Uri.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Uri.java
new file mode 100644
index 00000000000..a07dc3e2a03
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Uri.java
@@ -0,0 +1,88 @@
+/*
+ * 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 java.util.Objects;
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.PluginValue;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Descriptor of a URI object that is created via configuration.
+ */
+@Plugin(name = "Uri", category = Core.CATEGORY_NAME, printObject = true)
+public final class Uri {
+
+    /**
+     * The empty array.
+     */
+    static final Uri[] EMPTY_ARRAY = {};
+
+    private final String uri;
+
+    private Uri(final String uri) {
+        this.uri = Objects.requireNonNull(uri, "uri is null");
+    }
+
+    /**
+     * Creates a Uri object.
+     *
+     * @param uri the URI.
+     * @return A Uri object.
+     */
+    @PluginFactory
+    public static Uri createUri( // @formatter:off
+            @PluginValue("uri") final String uri) {
+        // @formatter:on
+
+        StatusLogger.getLogger().debug("Creating Uri('{}')", uri);
+        return new Uri(uri);
+    }
+
+    /**
+     * Returns the URI.
+     *
+     * @return the URI
+     */
+    public String getUri() {
+        return uri;
+    }
+
+    @Override
+    public int hashCode() {
+        return uri.hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (!(object instanceof Uri)) {
+            return false;
+        }
+        final Uri other = (Uri) object;
+        return this.uri == other.uri;
+    }
+
+    @Override
+    public String toString() {
+        return "Uri[" + uri + "]";
+    }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
index 3b9fc489614..badbd346cda 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ConfigurationBuilder.java
@@ -61,6 +61,15 @@ public interface ConfigurationBuilder<T extends Configuration> extends Builder<T
      */
     ConfigurationBuilder<T> add(CustomLevelComponentBuilder builder);
 
+    /**
+     * Adds a MonitorUri component.
+     * @param builder The MonitorUriComponentBuilder with all of its attributes set.
+     * @return this builder instance.
+     */
+    default ConfigurationBuilder<T> add(MonitorUriComponentBuilder builder) {
+        return this;
+    }
+
     /**
      * Adds a Filter component.
      * @param builder the FilterComponentBuilder with all of its attributes and sub components set.
@@ -272,6 +281,15 @@ public interface ConfigurationBuilder<T extends Configuration> extends Builder<T
      */
     CustomLevelComponentBuilder newCustomLevel(String name, int level);
 
+    /**
+     * Returns a builder for creating MonitorUris
+     * @param uri The URI.
+     * @return A new MonitorUriComponentBuilder.
+     */
+    default MonitorUriComponentBuilder newMonitorUri(String uri) {
+        return null;
+    }
+
     /**
      * Returns a builder for creating Filters.
      * @param pluginName The Plugin type of the Filter.
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/MonitorUriComponentBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/MonitorUriComponentBuilder.java
new file mode 100644
index 00000000000..4942dc02c37
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/MonitorUriComponentBuilder.java
@@ -0,0 +1,22 @@
+/*
+ * 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.builder.api;
+
+/**
+ * Assembler for constructing MonitorUri Components.
+ */
+public interface MonitorUriComponentBuilder extends ComponentBuilder<MonitorUriComponentBuilder> {}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/package-info.java
index 273906a5d48..6d91c2d89d8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/package-info.java
@@ -20,7 +20,7 @@
  * @since 2.4
  */
 @Export
-@Version("2.20.1")
+@Version("2.25.0")
 package org.apache.logging.log4j.core.config.builder.api;
 
 import org.osgi.annotation.bundle.Export;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
index f1ec35e06a0..8cf02dde440 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
@@ -46,6 +46,7 @@ public class BuiltConfiguration extends AbstractConfiguration {
     private Component propertiesComponent;
     private Component customLevelsComponent;
     private Component scriptsComponent;
+    private Component monitorUriComponent;
     private String contentType = "text";
 
     public BuiltConfiguration(
@@ -78,6 +79,10 @@ public BuiltConfiguration(
                     customLevelsComponent = component;
                     break;
                 }
+                case "MonitorUris": {
+                    monitorUriComponent = component;
+                    break;
+                }
             }
         }
         this.rootComponent = rootComponent;
@@ -95,6 +100,9 @@ public void setup() {
         if (customLevelsComponent.getComponents().size() > 0) {
             children.add(convertToNode(rootNode, customLevelsComponent));
         }
+        if (monitorUriComponent.getComponents().size() > 0) {
+            children.add(convertToNode(rootNode, monitorUriComponent));
+        }
         children.add(convertToNode(rootNode, loggersComponent));
         children.add(convertToNode(rootNode, appendersComponent));
         if (filtersComponent.getComponents().size() > 0) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
index 633e619b281..1dc4a66ac1e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
@@ -55,6 +55,7 @@
 import org.apache.logging.log4j.core.config.builder.api.KeyValuePairComponentBuilder;
 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.MonitorUriComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.PropertyComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.ScriptComponentBuilder;
@@ -77,6 +78,7 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
     private Component properties;
     private Component customLevels;
     private Component scripts;
+    private Component monitorUris;
     private final Class<T> clazz;
     private ConfigurationSource source;
     private int monitorInterval;
@@ -124,6 +126,8 @@ public DefaultConfigurationBuilder(final Class<T> clazz) {
         components.add(appenders);
         loggers = new Component("Loggers");
         components.add(loggers);
+        monitorUris = new Component("MonitorUris");
+        components.add(monitorUris);
     }
 
     protected ConfigurationBuilder<T> add(final Component parent, final ComponentBuilder<?> builder) {
@@ -136,6 +140,11 @@ public ConfigurationBuilder<T> add(final AppenderComponentBuilder builder) {
         return add(appenders, builder);
     }
 
+    @Override
+    public ConfigurationBuilder<T> add(final MonitorUriComponentBuilder builder) {
+        return add(monitorUris, builder);
+    }
+
     @Override
     public ConfigurationBuilder<T> add(final CustomLevelComponentBuilder builder) {
         return add(customLevels, builder);
@@ -291,6 +300,7 @@ private void writeXmlConfiguration(final XMLStreamWriter xmlWriter) throws XMLSt
         writeXmlSection(xmlWriter, properties);
         writeXmlSection(xmlWriter, scripts);
         writeXmlSection(xmlWriter, customLevels);
+        writeXmlSection(xmlWriter, monitorUris);
         if (filters.getComponents().size() == 1) {
             writeXmlComponent(xmlWriter, filters.getComponents().get(0));
         } else if (filters.getComponents().size() > 1) {
@@ -337,7 +347,6 @@ private void writeXmlAttributes(final XMLStreamWriter xmlWriter, final Component
         }
     }
 
-    @Override
     public ScriptComponentBuilder newScript(final String name, final String language, final String text) {
         return new DefaultScriptComponentBuilder(this, name, language, text);
     }
@@ -453,6 +462,11 @@ public CustomLevelComponentBuilder newCustomLevel(final String name, final int l
         return new DefaultCustomLevelComponentBuilder(this, name, level);
     }
 
+    @Override
+    public MonitorUriComponentBuilder newMonitorUri(final String uri) {
+        return new DefaultMonitorUriComponentBuilder(this, uri);
+    }
+
     @Override
     public FilterComponentBuilder newFilter(
             final String type, final Filter.Result onMatch, final Filter.Result onMismatch) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultMonitorUriComponentBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultMonitorUriComponentBuilder.java
new file mode 100644
index 00000000000..21299003cf8
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultMonitorUriComponentBuilder.java
@@ -0,0 +1,33 @@
+/*
+ * 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.builder.impl;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.builder.api.MonitorUriComponentBuilder;
+
+/**
+ *
+ */
+class DefaultMonitorUriComponentBuilder extends DefaultComponentAndConfigurationBuilder<MonitorUriComponentBuilder>
+        implements MonitorUriComponentBuilder {
+
+    public DefaultMonitorUriComponentBuilder(
+            final DefaultConfigurationBuilder<? extends Configuration> builder, final String uri) {
+        super(builder, "Uri");
+        addAttribute("uri", uri);
+    }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/package-info.java
index c56f92230f3..32a69487d75 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/package-info.java
@@ -20,7 +20,7 @@
  * @since 2.4
  */
 @Export
-@Version("2.20.2")
+@Version("2.25.0")
 package org.apache.logging.log4j.core.config.builder.impl;
 
 import org.osgi.annotation.bundle.Export;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/package-info.java
index 111d1644f68..3db1c7abd6b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/package-info.java
@@ -18,7 +18,7 @@
  * Configuration of Log4j 2.
  */
 @Export
-@Version("2.24.1")
+@Version("2.25.0")
 package org.apache.logging.log4j.core.config;
 
 import org.osgi.annotation.bundle.Export;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
index 6dc9fd6957a..8f7cb3e5b1b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationBuilder.java
@@ -35,6 +35,7 @@
 import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.LoggableComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
+import org.apache.logging.log4j.core.config.builder.api.MonitorUriComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.ScriptComponentBuilder;
 import org.apache.logging.log4j.core.config.builder.api.ScriptFileComponentBuilder;
@@ -124,6 +125,12 @@ public PropertiesConfiguration build() {
             }
         }
 
+        final Map<String, Properties> monitorUris =
+                PropertiesUtil.partitionOnCommonPrefixes(PropertiesUtil.extractSubset(rootProperties, "monitorUri"));
+        for (final Map.Entry<String, Properties> entry : monitorUris.entrySet()) {
+            builder.add(createMonitorUri(entry.getKey().trim(), entry.getValue()));
+        }
+
         final String filterProp = rootProperties.getProperty("filters");
         if (filterProp != null) {
             final String[] filterNames = filterProp.split(",");
@@ -250,6 +257,14 @@ private AppenderRefComponentBuilder createAppenderRef(final String key, final Pr
         return addFiltersToComponent(appenderRefBuilder, properties);
     }
 
+    private MonitorUriComponentBuilder createMonitorUri(final String key, final Properties properties) {
+        final String uri = (String) properties.remove("uri");
+        if (Strings.isEmpty(uri)) {
+            throw new ConfigurationException("No uri attribute provided for MonitorUri " + key);
+        }
+        return builder.newMonitorUri(uri);
+    }
+
     private LoggerComponentBuilder createLogger(final String key, final Properties properties) {
         final String levelAndRefs = properties.getProperty("");
         final String name = (String) properties.remove(CONFIG_NAME);
diff --git a/src/changelog/.2.x.x/3074_monitor_additional_files.xml b/src/changelog/.2.x.x/3074_monitor_additional_files.xml
new file mode 100644
index 00000000000..dcc2d028def
--- /dev/null
+++ b/src/changelog/.2.x.x/3074_monitor_additional_files.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="https://logging.apache.org/xml/ns"
+       xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+       type="fixed">
+  <issue id="3074" link="https://github.com/apache/logging-log4j2/issues/3074"/>
+  <description format="asciidoc">Support configuration option to provide URIs to monitor in addition to the config file.</description>
+</entry>
diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.json b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.json
new file mode 100644
index 00000000000..e8022cc4836
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.json
@@ -0,0 +1,15 @@
+{
+  "Configuration": {
+    "monitorInterval": "30",
+    "MonitorUris": {
+      "Uri": [
+        {
+          "uri": "to-be-monitored-1.file"
+        },
+        {
+          "uri": "to-be-monitored-2.file"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.properties b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.properties
new file mode 100644
index 00000000000..1c7010a326c
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.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.
+#
+##
+monitorInterval = 30
+monitorUri.0.uri = to-be-monitored-1.file
+monitorUri.1.uri = to-be-monitored-2.file
diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.xml b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.xml
new file mode 100644
index 00000000000..be987894adc
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+               xsi:schemaLocation="
+                   https://logging.apache.org/xml/ns
+                   https://logging.apache.org/xml/ns/log4j-config-2.xsd"
+               monitorInterval="30">
+  <MonitorUris>
+    <Uri uri="to-be-monitored-1.file"/>
+    <Uri uri="to-be-monitored-2.file"/>
+  </MonitorUris>
+</Configuration>
diff --git a/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.yaml b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.yaml
new file mode 100644
index 00000000000..a7ee9d371ec
--- /dev/null
+++ b/src/site/antora/modules/ROOT/examples/manual/configuration/monitoruris.yaml
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+Configuration:
+  monitorInterval: '30'
+  MonitorUris:
+    Uri:
+    - uri: to-be-monitored-1.file
+    - uri: to-be-monitored-2.file
diff --git a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc
index 7a0e738e41c..da37190a1c5 100644
--- a/src/site/antora/modules/ROOT/pages/manual/configuration.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/configuration.adoc
@@ -988,6 +988,69 @@ include::example$manual/configuration/routing.properties[tag=appender]
 Therefore, the dollar `$` sign needs to be escaped.
 <2> All the attributes of children of the `Route` element have a **deferred** evaluation. Therefore, they need only one `$` sign.
 
+[#monitorUris]
+== Monitor URIs
+
+Log4j can be configured to poll for changes to resources (in addition to the configuration file) using the `MonitorUris` element of the configuration. If a change is detected in any of the specifed resources, Log4j automatically reconfigures the logger context.
+
+The polling interval is determined by the value of the <<configuration-attribute-monitorInterval>> attribute. If set to 0, polling is disabled. See <<configuration-attribute-monitorInterval>> for further details. 
+
+This may be useful where the configuration is dependent on a resource that is external to the configuration file. 
+
+The MonitorUris component supports the following nested element: 
+
+[#MonitorUris-elements]
+[cols="1m,1,4"]
+|===
+| Type | Multiplicity | Description
+
+| `Uri`
+| one or more
+| Specifies the URI of a resouce to be polled for changes.
+|===
+
+The Uri component supports the following attribute:
+[#uri-attributes-name]
+=== `uri`
+
+[cols="1h,5"]
+|===
+| Type          | `String`
+|===
+
+See example below:
+
+[tabs]
+====
+XML::
++
+[source,xml]
+----
+include::example$manual/configuration/monitoruris.xml[lines=18..]
+----
+
+JSON::
++
+[source,json]
+----
+include::example$manual/configuration/monitoruris.json[]
+----
+
+YAML::
++
+[source,yaml]
+----
+include::example$manual/configuration/monitoruris.yaml[lines=17..]
+----
+
+Properties::
++
+[source,properties]
+----
+include::example$manual/configuration/monitoruris.properties[lines=18..]
+----
+====
+
 [id=arbiters]
 == [[Arbiters]] Arbiters