You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2018/11/16 22:43:24 UTC

[geode] 08/11: GEODE-2644: Make LogWriterAppender optional and support log4j2.xml

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

klund pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git

commit 4be9e7aa4cd90ca5ac4410d04aadfc3a4efcbba0
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Fri Nov 2 17:03:24 2018 -0700

    GEODE-2644: Make LogWriterAppender optional and support log4j2.xml
    
    LogWriterAppender is now configured in log4j2.xml and it supports
    sessions that correspond with Cache lifecycle. This allows Geode to
    pause and resume LogWriterAppender and GeodeConsoleAppender without
    resorting to dynamically adding and removing appenders.
    
    When the Cache exists, log events stop going to the Console and instead
    go to the Geode log file. Whenever the Cache does not exist, log events
    go only to the Console.
    
    These changes remove as much of the Log4j2 Core manipulation as
    possible.
    
    Also fixed:
    * GEODE-5789: Geode now updates log level of all Geode loggers.
    
    List of changes:
    * Change LogWriterAppender to be pausable and session-oriented
    * Add GeodeConsoleAppender which is pausable
    * Log4j2 Core dependency is now optional
    * Internal Logging interfaces allow Logging service to be pluggable
    * Log4j2 xml integration testing now uses JUnit Rule from Log4j2
    * Reduce coupling between Logging and the rest of Geode
    * Greatly increase test coverage for Logging
---
 .../GfshStartLocatorLogAcceptanceTest.java         |   36 +-
 .../LoggingWithReconnectDistributedTest.java       |  210 +++
 .../LocatorLauncherIntegrationTestCase.java        |    2 +-
 .../internal/InternalLocatorIntegrationTest.java   |   76 -
 .../logging/BannerLoggingIntegrationTest.java      |  129 ++
 .../logging/ConfigurationInfoIntegrationTest.java} |   24 +-
 .../logging/ConfigurationIntegrationTest.java      |  133 ++
 .../DistributedSystemLogFileIntegrationTest.java   | 1152 --------------
 .../logging/LocatorLogFileIntegrationTest.java     |  123 --
 .../LogLevelChangesWithCacheIntegrationTest.java   |  150 ++
 ...hangesWithDistributedSystemIntegrationTest.java |  167 ++
 .../logging/LogServiceIntegrationTest.java         |  236 ---
 ...oggingWithDistributedSystemIntegrationTest.java | 1597 ++++++++++++++++++++
 .../logging/LoggingWithLocatorIntegrationTest.java |  207 +++
 .../LoggingWithLocatorLauncherIntegrationTest.java |   65 +
 .../LoggingWithServerLauncherIntegrationTest.java  |   65 +
 .../ManagerLogWriterFactoryIntegrationTest.java    |  152 ++
 .../geode/internal/logging/NonBlankStrings.java}   |   23 +-
 ...StartupConfigurationLoggingIntegrationTest.java |  159 ++
 ...stemOutRuleAndSystemErrRuleIntegrationTest.java |   98 ++
 .../BothLogWriterAppendersIntegrationTest.java     |  180 +++
 ...> CacheWithCustomLogConfigIntegrationTest.java} |  100 +-
 .../CacheWithDefaultAppendersIntegrationTest.java  |   96 ++
 ...gurationWithLogLevelChangesIntegrationTest.java |  226 +++
 ...penderWithLoggerContextRuleIntegrationTest.java |   70 +-
 ...leAppenderWithSystemOutRuleIntegrationTest.java |  182 ---
 ...mWithBothLogWriterAppendersIntegrationTest.java |  203 +++
 ...edSystemWithLogLevelChangesIntegrationTest.java |  207 +++
 .../logging/log4j/FastLoggerIntegrationTest.java   |  411 ++---
 ...FastLoggerWithDefaultConfigIntegrationTest.java |   53 +-
 ...reVerboseMarkerFilterAcceptIntegrationTest.java |   26 +-
 ...fireVerboseMarkerFilterDenyIntegrationTest.java |   26 +-
 .../log4j/GeodeConsoleAppenderIntegrationTest.java |  210 +++
 ...odeConsoleAppenderWithCacheIntegrationTest.java |  168 ++
 ...leAppenderWithSystemOutRuleIntegrationTest.java |   98 ++
 ...deVerboseMarkerFilterAcceptIntegrationTest.java |   26 +-
 ...eodeVerboseMarkerFilterDenyIntegrationTest.java |   26 +-
 ...ServiceWithCustomLogConfigIntegrationTest.java} |   32 +-
 .../log4j/LogWriterAppenderIntegrationTest.java    |  341 ++---
 ...LogWriterAppenderWithLimitsIntegrationTest.java |  147 ++
 ...AppenderWithMemberNameInXmlIntegrationTest.java |  148 ++
 .../SecurityLogWriterAppenderIntegrationTest.java  |  136 ++
 .../MemberMXBeanShowLogIntegrationTest.java        |  186 +++
 .../ChangeLogLevelFunctionIntegrationTest.java     |  164 ++
 .../apache/geode/codeAnalysis/excludedClasses.txt  |    9 +-
 ...thLogWriterAppendersIntegrationTest_log4j2.xml} |   19 +-
 ...eWithCustomLogConfigIntegrationTest_log4j2.xml} |   10 +-
 ...nWithLogLevelChangesIntegrationTest_log4j2.xml} |   13 +-
 ...WithLoggerContextRuleIntegrationTest_log4j2.xml |   26 +-
 ...thLogWriterAppendersIntegrationTest_log4j2.xml} |   19 +-
 ...mWithLogLevelChangesIntegrationTest_log4j2.xml} |   13 +-
 ...oseMarkerFilterAcceptIntegrationTest_log4j2.xml |    2 +-
 ...rboseMarkerFilterDenyIntegrationTest_log4j2.xml |    2 +-
 ...GeodeConsoleAppenderIntegrationTest_log4j2.xml} |   11 +-
 ...oleAppenderWithCacheIntegrationTest_log4j2.xml} |   19 +-
 ...derWithSystemOutRuleIntegrationTest_log4j2.xml} |   11 +-
 ...oseMarkerFilterAcceptIntegrationTest_log4j2.xml |    2 +-
 ...rboseMarkerFilterDenyIntegrationTest_log4j2.xml |    2 +-
 ...eWithCustomLogConfigIntegrationTest_log4j2.xml} |    2 +-
 ...=> LogWriterAppenderIntegrationTest_log4j2.xml} |   11 +-
 ...erAppenderWithLimitsIntegrationTest_log4j2.xml} |   13 +-
 ...rWithMemberNameInXmlIntegrationTest_log4j2.xml} |   13 +-
 ...ityLogWriterAppenderIntegrationTest_log4j2.xml} |   18 +-
 .../logging/log4j/CacheLoggingBenchmark.java       |  116 ++
 .../logging/log4j/LogWriterAppenderBenchmark.java  |  124 ++
 .../admin/internal/AdminDistributedSystemImpl.java |   27 +-
 .../apache/geode/admin/jmx/internal/AgentImpl.java |  111 +-
 .../internal/InternalDistributedSystem.java        |  151 +-
 .../distributed/internal/InternalLocator.java      |  107 +-
 .../internal/RuntimeDistributionConfigImpl.java    |   12 +-
 .../java/org/apache/geode/internal/Banner.java     |   94 +-
 .../apache/geode/internal/VersionDescription.java  |   37 +-
 .../internal/admin/remote/TailLogResponse.java     |   38 +-
 .../geode/internal/logging/Configuration.java      |  237 +++
 .../geode/internal/logging/ConfigurationInfo.java  |   56 +
 .../geode/internal/logging/InternalLogWriter.java  |    2 -
 .../geode/internal/logging/LogConfigListener.java} |   25 +-
 .../geode/internal/logging/LogConfigSupplier.java  |   35 +-
 .../org/apache/geode/internal/logging/LogFile.java |   37 +-
 .../geode/internal/logging/LogFileDetails.java     |   21 +-
 .../geode/internal/logging/LogMessageRegex.java    |  106 ++
 .../apache/geode/internal/logging/LogService.java  |  249 +--
 .../geode/internal/logging/LogWriterFactory.java   |   81 +-
 .../geode/internal/logging/LogWriterLevel.java     |   40 +-
 .../geode/internal/logging/LoggingSession.java     |  119 ++
 .../internal/logging/LoggingSessionListener.java   |   58 +
 .../internal/logging/LoggingSessionListeners.java  |  100 ++
 .../geode/internal/logging/ManagerLogWriter.java   |   55 +-
 .../internal/logging/ManagerLogWriterFactory.java  |  176 +++
 .../apache/geode/internal/logging/NullLogFile.java |   41 +-
 .../geode/internal/logging/NullLogWriter.java      |   58 +
 .../internal/logging/NullLoggingSession.java}      |   35 +-
 .../geode/internal/logging/NullProviderAgent.java} |   35 +-
 .../geode/internal/logging/ProviderAgent.java}     |   33 +-
 .../geode/internal/logging/PureLogWriter.java      |    9 +-
 .../geode/internal/logging/SecurityLogWriter.java  |   12 +-
 .../geode/internal/logging/SessionContext.java}    |   50 +-
 .../geode/internal/logging/log4j/Configurator.java |  186 ---
 .../logging/log4j/GeodeConsoleAppender.java        |  305 ++++
 .../geode/internal/logging/log4j/Log4jAgent.java   |  300 ++++
 .../geode/internal/logging/log4j/LogLevel.java     |  162 +-
 .../internal/logging/log4j/LogWriterAppender.java  |  441 ++++--
 .../internal/logging/log4j/LogWriterAppenders.java |  293 ----
 .../logging/log4j/LogWriterLevelConverter.java     |   97 ++
 .../internal/logging/log4j/LogWriterLogger.java    |   23 +-
 .../logging/log4j/MemberNamePatternConverter.java  |   64 +
 .../logging/log4j/MemberNameSupplier.java}         |   26 +-
 .../security/IntegratedSecurityService.java        |    4 +-
 .../security/shiro/SecurityManagerProvider.java    |    4 +-
 .../internal/statistics/GemFireStatSampler.java    |    7 +-
 .../geode/internal/statistics/HostStatSampler.java |   20 +
 .../internal/statistics/StatArchiveHandler.java    |   21 +-
 .../statistics/StatArchiveHandlerConfig.java       |   16 +-
 .../internal/beans/MemberMBeanBridge.java          |    9 +-
 .../cli/commands/DiskStoreCommandsUtils.java       |    3 +-
 .../cli/functions/ChangeLogLevelFunction.java      |   28 +-
 geode-core/src/main/resources/log4j2-cli.xml       |    2 +-
 geode-core/src/main/resources/log4j2.xml           |   18 +-
 .../geode/internal/logging/log4j/log4j2-legacy.xml |    2 +-
 .../sanctioned-geode-core-serializables.txt        |    1 -
 .../java/org/apache/geode/internal/BannerTest.java |   59 +
 .../geode/internal/logging/ConfigurationTest.java  |  382 +++++
 ...essageRegexMatchesStartupConfigurationTest.java |  227 +++
 .../internal/logging/LogMessageRegexTest.java      |  242 +++
 .../geode/internal/logging/LogServiceTest.java     |  129 +-
 .../geode/internal/logging/LogWriterLevelTest.java |   73 +-
 .../geode/internal/logging/LoggingSessionTest.java |  219 +++
 ...terLevelTest.java => ManagerLogWriterTest.java} |   25 +-
 .../geode/internal/logging/log4j/LogLevelTest.java |  183 +--
 .../logging/log4j/LogWriterLevelConverterTest.java |  132 ++
 .../log4j/MemberNamePatternConverterTest.java      |   57 +
 .../org/apache/geode/test/golden/log4j2-test.xml   |    2 +-
 .../apache/geode/test/dunit/LogWriterUtils.java    |    4 +-
 .../geode/test/dunit/standalone/DUnitLauncher.java |    9 +-
 .../internal/logging/TestLogWriterFactory.java     |    5 +-
 .../apache/geode/management/MXBeanAwaitility.java  |    0
 .../accessible/AccessibleTemporaryFolder.java      |   19 +-
 137 files changed, 10629 insertions(+), 4138 deletions(-)

diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshStartLocatorLogAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshStartLocatorLogAcceptanceTest.java
index 01a47c9..4d85ab9 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshStartLocatorLogAcceptanceTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshStartLocatorLogAcceptanceTest.java
@@ -14,46 +14,46 @@
  */
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
 
 import java.io.File;
-import java.nio.charset.StandardCharsets;
 
-import com.google.common.io.Files;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.internal.Banner;
+import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.categories.LoggingTest;
 import org.apache.geode.test.junit.rules.gfsh.GfshExecution;
 import org.apache.geode.test.junit.rules.gfsh.GfshRule;
 import org.apache.geode.test.junit.rules.gfsh.GfshScript;
 
-@Category({GfshTest.class, LoggingTest.class})
+@Category({LoggingTest.class, GfshTest.class})
 public class GfshStartLocatorLogAcceptanceTest {
 
+  private File logFile;
+
   @Rule
   public GfshRule gfshRule = new GfshRule();
 
-  @Test
-  public void bannerOnlyLogsOnce() throws Exception {
-    final String banner = "Licensed to the Apache Software Foundation (ASF)";
-    String lines = getExecutionLogs();
-    assertThat(lines.indexOf(banner)).isEqualTo(lines.lastIndexOf(banner));
+  @Before
+  public void setUp() {
+    GfshExecution gfshExecution = GfshScript.of("start locator").execute(gfshRule);
+    File[] files = gfshExecution.getWorkingDir().listFiles();
+    String logName = files[0].getAbsolutePath() + "/" + files[0].getName() + ".log";
+    logFile = new File(logName);
   }
 
   @Test
-  public void startupConfigsOnlyLogsOnce() throws Exception {
-    final String startupConfigs = "### GemFire Properties using default values ###";
-    String lines = getExecutionLogs();
-    assertThat(lines.indexOf(startupConfigs)).isEqualTo(lines.lastIndexOf(startupConfigs));
+  public void bannerIsLoggedOnlyOnce() {
+    LogFileAssert.assertThat(logFile).containsOnlyOnce(Banner.BannerHeader.displayValues());
   }
 
-  private String getExecutionLogs() throws Exception {
-    GfshExecution gfshExecution = GfshScript.of("start locator").execute(gfshRule);
-    File[] files = gfshExecution.getWorkingDir().listFiles();
-    String logName = files[0].getAbsolutePath() + "/" + files[0].getName() + ".log";
-    return Files.readLines(new File(logName), StandardCharsets.UTF_8).toString();
+  @Test
+  public void startupConfigIsLoggedOnlyOnce() {
+    LogFileAssert.assertThat(logFile).containsOnlyOnce(STARTUP_CONFIGURATION);
   }
 }
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java
new file mode 100644
index 0000000..4734bba
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.geode.internal.logging;
+
+import static java.lang.System.lineSeparator;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.apache.geode.distributed.ConfigurationProperties.DISABLE_AUTO_RECONNECT;
+import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.MAX_WAIT_TIME_RECONNECT;
+import static org.apache.geode.distributed.ConfigurationProperties.MEMBER_TIMEOUT;
+import static org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper.getMembershipManager;
+import static org.apache.geode.internal.Banner.BannerHeader.displayValues;
+import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.getTimeout;
+import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
+import static org.apache.geode.test.dunit.VM.getController;
+import static org.apache.geode.test.dunit.VM.getVM;
+import static org.apache.geode.test.dunit.VM.toArray;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Arrays;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.ForcedDisconnectException;
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.membership.gms.mgr.GMSMembershipManager;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedRule;
+import org.apache.geode.test.junit.categories.LoggingTest;
+import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
+import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
+
+/**
+ * Distributed tests for logging during reconnect.
+ */
+@Category(LoggingTest.class)
+public class LoggingWithReconnectDistributedTest implements Serializable {
+
+  private static final long TIMEOUT = getTimeout().getValueInMS();
+
+  private static LocatorLauncher locatorLauncher;
+  private static ServerLauncher serverLauncher;
+
+  private static InternalDistributedSystem system;
+
+  private VM locatorVM;
+  private VM server1VM;
+  private VM server2VM;
+
+  private String locatorName;
+  private String server1Name;
+  private String server2Name;
+
+  private File locatorDir;
+  private File server1Dir;
+  private File server2Dir;
+
+  @Rule
+  public DistributedRule distributedRule = new DistributedRule();
+
+  @Rule
+  public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();
+
+  @Rule
+  public SerializableTestName testName = new SerializableTestName();
+
+  @Before
+  public void setUp() throws Exception {
+    locatorName = "locator-" + testName.getMethodName();
+    server1Name = "server-" + testName.getMethodName() + "-1";
+    server2Name = "server-" + testName.getMethodName() + "-2";
+
+    locatorVM = getVM(0);
+    server1VM = getVM(1);
+    server2VM = getController();
+
+    locatorDir = temporaryFolder.newFolder(locatorName);
+    server1Dir = temporaryFolder.newFolder(server1Name);
+    server2Dir = temporaryFolder.newFolder(server2Name);
+
+    int locatorPort = locatorVM.invoke(() -> createLocator());
+
+    server1VM.invoke(() -> createServer(server1Name, server1Dir, locatorPort));
+    server2VM.invoke(() -> createServer(server2Name, server2Dir, locatorPort));
+
+    addIgnoredException(ForcedDisconnectException.class);
+    addIgnoredException("Possible loss of quorum");
+  }
+
+  @After
+  public void tearDown() {
+    locatorVM.invoke(() -> {
+      locatorLauncher.stop();
+      locatorLauncher = null;
+      system = null;
+    });
+
+    for (VM vm : toArray(server1VM, server2VM)) {
+      vm.invoke(() -> {
+        serverLauncher.stop();
+        serverLauncher = null;
+        system = null;
+      });
+    }
+  }
+
+  @Test
+  public void logFileContainsBannerOnlyOnce() {
+    locatorVM.invoke(() -> {
+      assertThat(system.getDistributionManager().getDistributionManagerIds()).hasSize(3);
+    });
+
+    server2VM.invoke(() -> {
+      GMSMembershipManager membershipManager = (GMSMembershipManager) getMembershipManager(system);
+      membershipManager.forceDisconnect("Forcing disconnect in " + testName.getMethodName());
+
+      await().until(() -> system.isReconnecting());
+      system.waitUntilReconnected(TIMEOUT, MILLISECONDS);
+      assertThat(system.getReconnectedSystem()).isNotSameAs(system);
+    });
+
+    locatorVM.invoke(() -> {
+      assertThat(system.getDistributionManager().getDistributionManagerIds()).hasSize(3);
+    });
+
+    server2VM.invoke(() -> {
+      File[] files = server2Dir.listFiles((dir, name) -> name.endsWith(".log"));
+      assertThat(files).as(expectedOneLogFile(files)).hasSize(1);
+
+      File logFile = files[0];
+      assertThat(logFile).exists();
+
+      // Banner must be logged only once
+      LogFileAssert.assertThat(logFile).containsOnlyOnce(displayValues());
+
+      // Startup Config must be logged only once
+      String[] startupConfiguration = StringUtils
+          .split(STARTUP_CONFIGURATION + system.getConfig().toLoggerString(), lineSeparator());
+
+      LogFileAssert.assertThat(logFile).containsOnlyOnce(startupConfiguration);
+    });
+  }
+
+  private String expectedOneLogFile(File[] files) {
+    return "Expecting directory:" + lineSeparator() + " " + server2Dir.getAbsolutePath()
+        + lineSeparator() + "to contain only one log file:" + lineSeparator() + " " + server2Name
+        + ".log" + lineSeparator() + "but found multiple log files:" + lineSeparator() + " "
+        + Arrays.asList(files);
+  }
+
+  private int createLocator() {
+    LocatorLauncher.Builder builder = new LocatorLauncher.Builder();
+    builder.setMemberName(locatorName);
+    builder.setWorkingDirectory(locatorDir.getAbsolutePath());
+    builder.setPort(0);
+    builder.set(DISABLE_AUTO_RECONNECT, "false");
+    builder.set(ENABLE_CLUSTER_CONFIGURATION, "false");
+    builder.set(MAX_WAIT_TIME_RECONNECT, "1000");
+    builder.set(MEMBER_TIMEOUT, "2000");
+
+    locatorLauncher = builder.build();
+    locatorLauncher.start();
+
+    system = (InternalDistributedSystem) locatorLauncher.getCache().getDistributedSystem();
+
+    return locatorLauncher.getPort();
+  }
+
+  private void createServer(String serverName, File serverDir, int locatorPort) {
+    ServerLauncher.Builder builder = new ServerLauncher.Builder();
+    builder.setMemberName(serverName);
+    builder.setWorkingDirectory(serverDir.getAbsolutePath());
+    builder.setServerPort(0);
+    builder.set(LOCATORS, "localHost[" + locatorPort + "]");
+    builder.set(DISABLE_AUTO_RECONNECT, "false");
+    builder.set(ENABLE_CLUSTER_CONFIGURATION, "false");
+    builder.set(MAX_WAIT_TIME_RECONNECT, "1000");
+    builder.set(MEMBER_TIMEOUT, "2000");
+
+    serverLauncher = builder.build();
+    serverLauncher.start();
+
+    system = (InternalDistributedSystem) serverLauncher.getCache().getDistributedSystem();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorLauncherIntegrationTestCase.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorLauncherIntegrationTestCase.java
index 61c7313..1e484dc 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorLauncherIntegrationTestCase.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorLauncherIntegrationTestCase.java
@@ -93,7 +93,7 @@ public abstract class LocatorLauncherIntegrationTestCase extends LauncherIntegra
     return givenLocatorLauncher(newBuilder());
   }
 
-  private LocatorLauncher givenLocatorLauncher(final Builder builder) {
+  protected LocatorLauncher givenLocatorLauncher(final Builder builder) {
     return builder.build();
   }
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java
deleted file mode 100644
index 9d0917b..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/InternalLocatorIntegrationTest.java
+++ /dev/null
@@ -1,76 +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.
- */
-
-package org.apache.geode.distributed.internal;
-
-import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
-import static org.apache.geode.distributed.ConfigurationProperties.NAME;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.Properties;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import org.apache.geode.distributed.Locator;
-import org.apache.geode.internal.AvailablePortHelper;
-import org.apache.geode.internal.logging.log4j.LogWriterAppender;
-import org.apache.geode.internal.logging.log4j.LogWriterAppenders;
-
-public class InternalLocatorIntegrationTest {
-
-  private Locator locator;
-  private LogWriterAppender appender;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Test
-  public void testLogWriterAppenderShouldBeRemovedForALocatorWithNoDS() throws Exception {
-    Properties properties = new Properties();
-    properties.setProperty(NAME, "testVM");
-    properties.setProperty(LOG_FILE, temporaryFolder.newFile("testVM.log").getAbsolutePath());
-
-    int port = AvailablePortHelper.getRandomAvailableTCPPort();
-    locator = InternalLocator.startLocator(port, null, null, null, null, false, properties, null);
-
-    appender = LogWriterAppenders.getAppender(LogWriterAppenders.Identifier.MAIN);
-    assertThat(appender).isNotNull();
-
-    locator.stop();
-
-    appender = LogWriterAppenders.getAppender(LogWriterAppenders.Identifier.MAIN);
-    assertThat(appender).isNull();
-  }
-
-  @Test
-  public void testLogWriterAppenderShouldBeRemovedForALocatorWithDS() throws Exception {
-    Properties properties = new Properties();
-    properties.setProperty(NAME, "testVM");
-    properties.setProperty(LOG_FILE, temporaryFolder.newFile("testVM.log").getAbsolutePath());
-
-    int port = AvailablePortHelper.getRandomAvailableTCPPort();
-    locator = InternalLocator.startLocatorAndDS(port, null, properties);
-
-    appender = LogWriterAppenders.getAppender(LogWriterAppenders.Identifier.MAIN);
-    assertThat(appender).isNotNull();
-
-    locator.stop();
-
-    appender = LogWriterAppenders.getAppender(LogWriterAppenders.Identifier.MAIN);
-    assertThat(appender).isNull();
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java
new file mode 100644
index 0000000..04a8c72
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.geode.internal.logging;
+
+import static java.nio.charset.Charset.defaultCharset;
+import static org.apache.commons.io.FileUtils.readLines;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.internal.Banner.BannerHeader.displayValues;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.Banner;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for logging of the {@link Banner}.
+ */
+@Category(LoggingTest.class)
+public class BannerLoggingIntegrationTest {
+
+  private File mainLogFile;
+  private InternalDistributedSystem system;
+  private Logger geodeLogger;
+  private String logMessage;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() {
+    String name = testName.getMethodName();
+    mainLogFile = new File(temporaryFolder.getRoot(), name + "-main.log");
+
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFile.getAbsolutePath());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    geodeLogger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (system != null) {
+      system.disconnect();
+    }
+  }
+
+  @Test
+  public void bannerIsLoggedToFile() {
+    LogFileAssert.assertThat(mainLogFile).contains(displayValues());
+  }
+
+  @Test
+  public void bannerIsLoggedToFileOnlyOnce() {
+    LogFileAssert.assertThat(mainLogFile).containsOnlyOnce(displayValues());
+  }
+
+  /**
+   * Verifies that the banner is logged before any log messages.
+   */
+  @Test
+  public void bannerIsLoggedToFileBeforeLogMessage() throws Exception {
+    geodeLogger.info(logMessage);
+
+    List<String> lines = readLines(mainLogFile, defaultCharset());
+
+    boolean foundBanner = false;
+    boolean foundLogMessage = false;
+
+    for (String line : lines) {
+      if (containsAny(line, displayValues())) {
+        assertThat(foundLogMessage).as("Banner should be logged before log message: " + lines)
+            .isFalse();
+        foundBanner = true;
+      }
+      if (line.contains(logMessage)) {
+        assertThat(foundBanner).as("Log message should be logged after banner: " + lines)
+            .isTrue();
+        foundLogMessage = true;
+      }
+    }
+
+    assertThat(foundBanner).as("Banner not found in: " + lines).isTrue();
+    assertThat(foundLogMessage).as("Log message not found in: " + lines).isTrue();
+  }
+
+  private boolean containsAny(String string, String... values) {
+    for (String value : values) {
+      if (string.contains(value)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java
similarity index 59%
copy from geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
copy to geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java
index 1bede46..3b69302 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java
@@ -14,25 +14,29 @@
  */
 package org.apache.geode.internal.logging;
 
+import static org.apache.geode.internal.logging.ConfigurationInfo.getConfigurationInfo;
 import static org.assertj.core.api.Assertions.assertThat;
 
-import java.io.Serializable;
-
-import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.logging.log4j.Log4jAgent;
+import org.apache.geode.test.junit.categories.LoggingTest;
 
-public class LogWriterLevelTest {
+/**
+ * Integration tests for {@link ConfigurationInfo}.
+ */
+@Category(LoggingTest.class)
+public class ConfigurationInfoIntegrationTest {
 
   @Test
-  public void isSerializable() {
-    assertThat(LogWriterLevel.ALL).isInstanceOf(Serializable.class);
+  public void getConfigurationInfoContainsLog4j2Xml() {
+    assertThat(getConfigurationInfo()).contains("log4j2.xml");
   }
 
   @Test
-  public void serializes() {
-    LogWriterLevel logLevel = (LogWriterLevel) SerializationUtils.clone(LogWriterLevel.ALL);
+  public void getConfigurationInfoMatchesLog4jAgent() {
 
-    assertThat(logLevel).isEqualTo(LogWriterLevel.ALL).isSameAs(LogWriterLevel.ALL);
+    assertThat(getConfigurationInfo()).contains(Log4jAgent.getConfigurationInfo());
   }
-
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationIntegrationTest.java
new file mode 100644
index 0000000..d8bc236
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationIntegrationTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.internal.logging.Configuration.LogLevelUpdateOccurs.ALWAYS;
+import static org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope.ALL_LOGGERS;
+import static org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope.GEODE_AND_APPLICATION_LOGGERS;
+import static org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope.GEODE_AND_SECURITY_LOGGERS;
+import static org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope.GEODE_LOGGERS;
+import static org.apache.geode.internal.logging.Configuration.MAIN_LOGGER_NAME;
+import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.getLoggerConfig;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.logging.log4j.Log4jAgent;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link Configuration}.
+ */
+@Category(LoggingTest.class)
+public class ConfigurationIntegrationTest {
+
+  private static final String APPLICATION_LOGGER_NAME = "com.application";
+
+  private LogConfigSupplier logConfigSupplier;
+  private LogConfig logConfig;
+
+  private Logger geodeLogger;
+  private Logger geodeSecurityLogger;
+  private Logger applicationLogger;
+
+  @Before
+  public void setUp() {
+    logConfigSupplier = mock(LogConfigSupplier.class);
+    logConfig = mock(LogConfig.class);
+
+    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
+    when(logConfig.getLogLevel()).thenReturn(INFO.intLevel());
+    when(logConfig.getSecurityLogLevel()).thenReturn(INFO.intLevel());
+
+    geodeLogger = LogManager.getLogger(MAIN_LOGGER_NAME);
+    geodeSecurityLogger = LogManager.getLogger(SECURITY_LOGGER_NAME);
+    applicationLogger = LogManager.getLogger(APPLICATION_LOGGER_NAME);
+
+    List<LoggerConfig> loggerConfigs = Arrays.asList(getLoggerConfig(geodeLogger),
+        getLoggerConfig(geodeSecurityLogger), getLoggerConfig(applicationLogger));
+
+    Log4jAgent.updateLogLevel(Level.INFO, loggerConfigs.toArray(new LoggerConfig[0]));
+  }
+
+  @Test
+  public void loggerLogLevelIsInfo() {
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.INFO);
+    assertThat(geodeSecurityLogger.getLevel()).isEqualTo(Level.INFO);
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+
+  @Test
+  public void updatesLogLevelForScopeGeodeLoggers() {
+    when(logConfig.getLogLevel()).thenReturn(WARNING.intLevel());
+
+    Configuration configuration = Configuration.create(ALWAYS, GEODE_LOGGERS);
+    configuration.initialize(logConfigSupplier);
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(geodeSecurityLogger.getLevel()).isEqualTo(Level.INFO);
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+
+  @Test
+  public void updatesLogLevelForScopeGeodeAndSecurityLoggers() {
+    when(logConfig.getLogLevel()).thenReturn(WARNING.intLevel());
+
+    Configuration configuration = Configuration.create(ALWAYS, GEODE_AND_SECURITY_LOGGERS);
+    configuration.initialize(logConfigSupplier);
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(geodeSecurityLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+
+  @Test
+  public void updatesLogLevelForScopeAllLoggers() {
+    when(logConfig.getLogLevel()).thenReturn(WARNING.intLevel());
+
+    Configuration configuration = Configuration.create(ALWAYS, ALL_LOGGERS);
+    configuration.initialize(logConfigSupplier);
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(geodeSecurityLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.WARN);
+  }
+
+  @Test
+  public void updatesLogLevelForScopeGeodeAndApplicationLoggers() {
+    when(logConfig.getLogLevel()).thenReturn(WARNING.intLevel());
+
+    Configuration configuration = Configuration.create(ALWAYS, GEODE_AND_APPLICATION_LOGGERS);
+    configuration.initialize(logConfigSupplier);
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+    assertThat(geodeSecurityLogger.getLevel()).isEqualTo(Level.INFO);
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.WARN);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/DistributedSystemLogFileIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/DistributedSystemLogFileIntegrationTest.java
deleted file mode 100755
index dba2b0b..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/DistributedSystemLogFileIntegrationTest.java
+++ /dev/null
@@ -1,1152 +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.
- */
-package org.apache.geode.internal.logging;
-
-import static org.apache.commons.lang3.SystemUtils.LINE_SEPARATOR;
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
-import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
-import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
-import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_FILE;
-import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_LEVEL;
-import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.Properties;
-import java.util.Scanner;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-
-import org.apache.geode.LogWriter;
-import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.internal.logging.log4j.FastLogger;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Connects DistributedSystem and tests logging behavior at a high level.
- */
-@Category(LoggingTest.class)
-public class DistributedSystemLogFileIntegrationTest {
-
-  private static final AtomicInteger COUNTER = new AtomicInteger();
-
-  private File logFile;
-  private String logFileName;
-  private File securityLogFile;
-  private String securityLogFileName;
-
-  private InternalDistributedSystem system;
-
-  private String prefix;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Rule
-  public TestName testName = new TestName();
-
-  @Before
-  public void setUp() {
-    logFile = new File(temporaryFolder.getRoot(),
-        testName.getMethodName() + "-system-" + System.currentTimeMillis() + ".log");
-    logFileName = logFile.getAbsolutePath();
-
-    securityLogFile = new File(temporaryFolder.getRoot(),
-        "security-" + testName.getMethodName() + "-system-" + System.currentTimeMillis() + ".log");
-    securityLogFileName = securityLogFile.getAbsolutePath();
-
-    prefix = "ExpectedStrings: " + testName.getMethodName() + " message logged at ";
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    if (system != null) {
-      system.disconnect();
-    }
-    // We will want to remove this at some point but right now the log context
-    // does not clear out the security logconfig between tests
-    LoggerContext context = (LoggerContext) LogManager.getContext(false);
-    context.stop();
-  }
-
-  @Test
-  public void testDistributedSystemLogWritersWithFilesDetails() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(SECURITY_LOG_FILE, securityLogFileName);
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> {
-      assertThat(logFile).exists();
-      assertThat(securityLogFile).exists();
-    });
-
-    // assertThat logFile is not empty
-    try (FileInputStream fis = new FileInputStream(logFile)) {
-      assertThat(fis.available()).isGreaterThan(0);
-    }
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogFile().getAbsolutePath()).isEqualTo(logFileName);
-    assertThat(distributionConfig.getSecurityLogFile().getAbsolutePath())
-        .isEqualTo(securityLogFileName);
-
-    assertThat(system.getLogWriter()).isInstanceOf(LogWriterLogger.class);
-    assertThat(system.getSecurityLogWriter()).isInstanceOf(LogWriterLogger.class);
-
-    LogWriterLogger logWriterLogger = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriterLogger = (LogWriterLogger) system.getSecurityLogWriter();
-
-    assertThat(logWriterLogger.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(securityLogWriterLogger.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-
-    securityLogWriterLogger.info("test: security log file created at info");
-
-    // assertThat securityLogFile is not empty
-    try (FileInputStream fis = new FileInputStream(securityLogFile)) {
-      assertThat(fis.available()).isGreaterThan(0);
-    }
-
-    LogWriter logWriter = logWriterLogger;
-    assertThat(logWriter.finestEnabled()).isFalse();
-    assertThat(logWriter.finerEnabled()).isFalse();
-    assertThat(logWriter.fineEnabled()).isFalse();
-    assertThat(logWriter.configEnabled()).isTrue();
-    assertThat(logWriter.infoEnabled()).isTrue();
-    assertThat(logWriter.warningEnabled()).isTrue();
-    assertThat(logWriter.errorEnabled()).isTrue();
-    assertThat(logWriter.severeEnabled()).isTrue();
-
-    FastLogger logWriterFastLogger = logWriterLogger;
-    // assertThat(logWriterFastLogger.isDelegating()).isTrue();
-    assertThat(logWriterFastLogger.isTraceEnabled()).isFalse();
-    assertThat(logWriterFastLogger.isDebugEnabled()).isFalse();
-    assertThat(logWriterFastLogger.isInfoEnabled()).isTrue();
-    assertThat(logWriterFastLogger.isWarnEnabled()).isTrue();
-    assertThat(logWriterFastLogger.isErrorEnabled()).isTrue();
-    assertThat(logWriterFastLogger.isFatalEnabled()).isTrue();
-
-    LogWriter securityLogWriter = securityLogWriterLogger;
-    assertThat(securityLogWriter.finestEnabled()).isFalse();
-    assertThat(securityLogWriter.finerEnabled()).isFalse();
-    assertThat(securityLogWriter.fineEnabled()).isFalse();
-    assertThat(securityLogWriter.configEnabled()).isTrue();
-    assertThat(securityLogWriter.infoEnabled()).isTrue();
-    assertThat(securityLogWriter.warningEnabled()).isTrue();
-    assertThat(securityLogWriter.errorEnabled()).isTrue();
-    assertThat(securityLogWriter.severeEnabled()).isTrue();
-
-    FastLogger securityLogWriterFastLogger = logWriterLogger;
-    // assertThat(securityLogWriterFastLogger.isDelegating()).isFalse();
-    assertThat(securityLogWriterFastLogger.isTraceEnabled()).isFalse();
-    assertThat(securityLogWriterFastLogger.isDebugEnabled()).isFalse();
-    assertThat(securityLogWriterFastLogger.isInfoEnabled()).isTrue();
-    assertThat(securityLogWriterFastLogger.isWarnEnabled()).isTrue();
-    assertThat(securityLogWriterFastLogger.isErrorEnabled()).isTrue();
-    assertThat(securityLogWriterFastLogger.isFatalEnabled()).isTrue();
-  }
-
-  @Test
-  public void testDistributedSystemCreatesLogFile() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "config");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-    Logger applicationLogger = LogManager.getLogger("net.customer");
-
-    // -------------------------------------------------------------------------------------------
-    // CONFIG level
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.INFO);
-    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    applicationLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    applicationLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    applicationLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    applicationLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    applicationLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    applicationLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    // -------------------------------------------------------------------------------------------
-    // FINE level
-
-    distributionConfig.setLogLevel(LogWriterLevel.FINE.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-    assertThat(applicationLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    applicationLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    applicationLogger.debug(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    applicationLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    applicationLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    applicationLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    applicationLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    // -------------------------------------------------------------------------------------------
-    // ERROR level
-
-    distributionConfig.setLogLevel(LogWriterLevel.ERROR.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
-    assertThat(applicationLogger.getLevel()).isEqualTo(Level.ERROR);
-
-    message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    applicationLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    applicationLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    applicationLogger.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.WARN);
-    applicationLogger.warn(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    applicationLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    applicationLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-  }
-
-  @Test
-  public void testDistributedSystemWithFineLogLevel() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "fine");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    // -------------------------------------------------------------------------------------------
-    // FINE level
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    // -------------------------------------------------------------------------------------------
-    // ERROR level
-
-    distributionConfig.setLogLevel(LogWriterLevel.ERROR.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
-
-    message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-  }
-
-  @Test
-  public void testDistributedSystemWithDebugLogLevel() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "debug");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    // -------------------------------------------------------------------------------------------
-    // DEBUG LEVEL
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-
-    // -------------------------------------------------------------------------------------------
-    // ERROR LEVEL
-
-    distributionConfig.setLogLevel(LogWriterLevel.ERROR.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.ERROR.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
-
-    message = createMessage(LogWriterLevel.FINEST);
-    logWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    logWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    logWriter.fine(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    logWriter.config(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    logWriter.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    logWriter.warning(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    logWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    logWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-  }
-
-  @Test
-  public void testDistributedSystemWithSecurityLogDefaultLevel() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "fine");
-    config.put(SECURITY_LOG_FILE, securityLogFileName);
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> {
-      assertThat(logFile).exists();
-      assertThat(securityLogFile).exists();
-    });
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(securityLogWriter.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    securityLogWriter.finest(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    securityLogWriter.fine(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    securityLogWriter.info(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-  }
-
-  @Test
-  public void testDistributedSystemWithSecurityLogFineLevel() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "fine");
-    config.put(SECURITY_LOG_FILE, securityLogFileName);
-    config.put(SECURITY_LOG_LEVEL, "fine");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> {
-      assertThat(logFile).exists();
-      assertThat(securityLogFile).exists();
-    });
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(securityLogWriter.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    securityLogWriter.finest(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    securityLogWriter.finer(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    securityLogWriter.fine(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    securityLogWriter.config(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    securityLogWriter.info(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    securityLogWriter.warning(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    securityLogWriter.error(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    securityLogWriter.severe(message);
-    assertThatFileContains(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileDoesNotContain(securityLogFile, message);
-    assertThatFileContains(logFile, message);
-  }
-
-  /**
-   * tests scenario where security log has not been set but a level has been set to a less granular
-   * level than that of the regular log. Verifies that the correct logs for security show up in the
-   * regular log as expected
-   */
-  @Test
-  public void testDistributedSystemWithSecurityInfoLevelAndLogAtFineLevelButNoSecurityLog()
-      throws Exception {
-    Properties CONFIG = new Properties();
-    CONFIG.put(LOG_FILE, logFileName);
-    CONFIG.put(LOG_LEVEL, "fine");
-    CONFIG.put(SECURITY_LOG_LEVEL, "info");
-    CONFIG.put(MCAST_PORT, "0");
-    CONFIG.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(CONFIG);
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(securityLogWriter.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    securityLogWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    securityLogWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    securityLogWriter.fine(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    securityLogWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    securityLogWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    securityLogWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    securityLogWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    securityLogWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-  }
-
-  /**
-   * tests scenario where security log has not been set but a level has been set to a more granular
-   * level than that of the regular log. Verifies that the correct logs for security show up in the
-   * regular log as expected
-   */
-  @Test
-  public void testDistributedSystemWithSecurityFineLevelAndLogAtInfoLevelButNoSecurityLog()
-      throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_FILE, logFileName);
-    config.put(LOG_LEVEL, "info");
-    config.put(SECURITY_LOG_LEVEL, "fine");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "");
-
-    system = (InternalDistributedSystem) DistributedSystem.connect(config);
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
-    Logger geodeLogger = LogService.getLogger();
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel()).isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-
-    assertThat(logWriter.getLogWriterLevel()).isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(securityLogWriter.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.FINE.getLogWriterLevel());
-    assertThat(geodeLogger.getLevel()).isEqualTo(Level.INFO);
-
-    String message = createMessage(LogWriterLevel.FINEST);
-    securityLogWriter.finest(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINER);
-    securityLogWriter.finer(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(LogWriterLevel.FINE);
-    securityLogWriter.fine(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.CONFIG);
-    securityLogWriter.config(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.INFO);
-    securityLogWriter.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.WARNING);
-    securityLogWriter.warning(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.ERROR);
-    securityLogWriter.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(LogWriterLevel.SEVERE);
-    securityLogWriter.severe(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.TRACE);
-    geodeLogger.trace(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.DEBUG);
-    geodeLogger.debug(message);
-    assertThatFileDoesNotContain(logFile, message);
-
-    message = createMessage(Level.INFO);
-    geodeLogger.info(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.WARN);
-    geodeLogger.warn(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.ERROR);
-    geodeLogger.error(message);
-    assertThatFileContains(logFile, message);
-
-    message = createMessage(Level.FATAL);
-    geodeLogger.fatal(message);
-    assertThatFileContains(logFile, message);
-  }
-
-  private String createMessage(LogWriterLevel logLevel) {
-    return prefix + logLevel.name() + " [" + COUNTER.incrementAndGet() + "]";
-  }
-
-  private String createMessage(Level level) {
-    return prefix + level.name() + " [" + COUNTER.incrementAndGet() + "]";
-  }
-
-  private void assertThatFileContains(final File file, final String string)
-      throws IOException {
-    try (Scanner scanner = new Scanner(file)) {
-      while (scanner.hasNextLine()) {
-        if (scanner.nextLine().trim().contains(string)) {
-          return;
-        }
-      }
-    }
-
-    List<String> lines = Files.readAllLines(file.toPath());
-    fail("Expected file " + file.getAbsolutePath() + " to contain " + string + LINE_SEPARATOR
-        + "Actual: " + lines);
-  }
-
-  private void assertThatFileDoesNotContain(final File file, final String string)
-      throws IOException {
-    boolean fail = false;
-    try (Scanner scanner = new Scanner(file)) {
-      while (scanner.hasNextLine()) {
-        if (scanner.nextLine().trim().contains(string)) {
-          fail = true;
-          break;
-        }
-      }
-    }
-    if (fail) {
-      List<String> lines = Files.readAllLines(file.toPath());
-      fail("Expected file " + file.getAbsolutePath() + " to not contain " + string + LINE_SEPARATOR
-          + "Actual: " + lines);
-    }
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LocatorLogFileIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LocatorLogFileIntegrationTest.java
deleted file mode 100644
index 89ac2a0..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LocatorLogFileIntegrationTest.java
+++ /dev/null
@@ -1,123 +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.
- */
-package org.apache.geode.internal.logging;
-
-import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
-import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
-import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
-import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.Properties;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-
-import org.apache.geode.distributed.Locator;
-import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.distributed.internal.InternalDistributedSystem;
-import org.apache.geode.internal.AvailablePort;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Creates Locator and tests logging behavior at a high level.
- */
-@Category(LoggingTest.class)
-public class LocatorLogFileIntegrationTest {
-
-  private File logFile;
-  private String logFileName;
-  private File securityLogFile;
-
-  private int port;
-  private Locator locator;
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Rule
-  public TestName testName = new TestName();
-
-  @Before
-  public void setUp() {
-    logFile = new File(temporaryFolder.getRoot(),
-        testName.getMethodName() + "-system-" + System.currentTimeMillis() + ".log");
-    logFileName = logFile.getAbsolutePath();
-
-    securityLogFile = new File("");
-
-    port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    if (locator != null) {
-      locator.stop();
-    }
-  }
-
-  @Test
-  public void testLocatorCreatesLogFile() throws Exception {
-    Properties config = new Properties();
-    config.put(LOG_LEVEL, "config");
-    config.put(MCAST_PORT, "0");
-    config.put(LOCATORS, "localhost[" + port + "]");
-    config.put(ENABLE_CLUSTER_CONFIGURATION, "false");
-
-    locator = Locator.startLocatorAndDS(port, logFile, config);
-
-    InternalDistributedSystem system = (InternalDistributedSystem) locator.getDistributedSystem();
-
-    await().untilAsserted(() -> assertThat(logFile).exists());
-
-    // assertThat logFile is not empty
-    try (FileInputStream fis = new FileInputStream(logFile)) {
-      assertThat(fis.available()).isGreaterThan(0);
-    }
-
-    DistributionConfig distributionConfig = system.getConfig();
-
-    assertThat(distributionConfig.getLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-    assertThat(distributionConfig.getSecurityLogLevel())
-        .isEqualTo(LogWriterLevel.CONFIG.getLogWriterLevel());
-
-    assertThat(distributionConfig.getLogFile().getAbsolutePath()).isEqualTo(logFileName);
-    assertThat(distributionConfig.getSecurityLogFile().getAbsolutePath())
-        .isEqualTo(securityLogFile.getAbsolutePath());
-
-    assertThat(system.getLogWriter()).isInstanceOf(LogWriterLogger.class);
-    assertThat(system.getSecurityLogWriter()).isInstanceOf(LogWriterLogger.class);
-
-    LogWriterLogger logWriterLogger = (LogWriterLogger) system.getLogWriter();
-    LogWriterLogger securityLogWriterLogger = (LogWriterLogger) system.getSecurityLogWriter();
-
-    assertThat(logWriterLogger.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-    assertThat(securityLogWriterLogger.getLogWriterLevel())
-        .isEqualTo(LogWriterLevel.INFO.getLogWriterLevel());
-
-    assertThat(securityLogFile).doesNotExist();
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java
new file mode 100644
index 0000000..81d1b34
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_LEVEL;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for log level control using {@link DistributionConfig} with lifecycle of
+ * {@link Cache}.
+ */
+@Category(LoggingTest.class)
+public class LogLevelChangesWithCacheIntegrationTest {
+
+  private static final String APPLICATION_LOGGER_NAME = "com.application";
+
+  private InternalCache cache;
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+  private InternalLogWriter mainLogWriter;
+  private InternalLogWriter securityLogWriter;
+  private DistributionConfig distributionConfig;
+  private LogConfig logConfig;
+
+  @Before
+  public void setUp() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_LEVEL, "INFO");
+    config.setProperty(SECURITY_LOG_LEVEL, "INFO");
+
+    cache = (InternalCache) new CacheFactory(config).create();
+    InternalDistributedSystem system = cache.getInternalDistributedSystem();
+
+    distributionConfig = system.getConfig();
+    logConfig = system.getLogConfig();
+
+    mainLogWriter = (InternalLogWriter) cache.getLogger();
+    securityLogWriter = (InternalLogWriter) cache.getSecurityLogger();
+
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogManager.getLogger(APPLICATION_LOGGER_NAME);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (cache != null) {
+      cache.close();
+    }
+  }
+
+  @Test
+  public void mainLogWriterLogLevelIsInfo() {
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void securityLogWriterLogLevelIsInfo() {
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void changesMainLogWriterLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void changesDistributionConfigLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void changesLogConfigLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(logConfig.getLogLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeSecurityLogWriterLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeDistributionConfigSecurityLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeLogConfigSecurityLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void changesGeodeLoggerLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+  }
+
+  @Test
+  public void doesNotChangeApplicationLoggerLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java
new file mode 100644
index 0000000..260c2cf
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_LEVEL;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for log level control using {@link DistributionConfig} with lifecycle of
+ * {@link DistributedSystem}.
+ */
+@Category(LoggingTest.class)
+public class LogLevelChangesWithDistributedSystemIntegrationTest {
+
+  private static final String APPLICATION_LOGGER_NAME = "com.application";
+
+  private InternalDistributedSystem system;
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+  private InternalLogWriter mainLogWriter;
+  private InternalLogWriter securityLogWriter;
+  private DistributionConfig distributionConfig;
+  private LogConfig logConfig;
+
+  @Before
+  public void setUp() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_LEVEL, "INFO");
+    config.setProperty(SECURITY_LOG_LEVEL, "INFO");
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    distributionConfig = system.getConfig();
+    logConfig = system.getLogConfig();
+
+    mainLogWriter = (InternalLogWriter) system.getLogWriter();
+    securityLogWriter = (InternalLogWriter) system.getSecurityLogWriter();
+
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogManager.getLogger(APPLICATION_LOGGER_NAME);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (system != null) {
+      system.disconnect();
+    }
+  }
+
+  @Test
+  public void distributionConfigLogLevelIsInfo() {
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void distributionConfigSecurityLogLevelIsInfo() {
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void logConfigLogLevelIsInfo() {
+    assertThat(logConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void logConfigSecurityLogLevelIsInfo() {
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void mainLogWriterLevelIsInfo() {
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void securityLogWriterLevelIsInfo() {
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void changesMainLogWriterLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void changesDistributionConfigLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void changesLogConfigLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(logConfig.getLogLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeSecurityLogWriterLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeDistributionConfigSecurityLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeLogConfigSecurityLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void changesGeodeLoggerLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+  }
+
+  @Test
+  public void doesNotChangeApplicationLoggerLogLevel() {
+    distributionConfig.setLogLevel(WARNING.intLevel());
+
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogServiceIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogServiceIntegrationTest.java
deleted file mode 100755
index 33fbce5..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogServiceIntegrationTest.java
+++ /dev/null
@@ -1,236 +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.
- */
-package org.apache.geode.internal.logging;
-
-import static org.apache.geode.internal.logging.LogServiceIntegrationTestSupport.writeConfigFile;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.File;
-import java.net.URL;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.contrib.java.lang.system.SystemErrRule;
-import org.junit.contrib.java.lang.system.SystemOutRule;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.ExternalResource;
-import org.junit.rules.TemporaryFolder;
-
-import org.apache.geode.internal.logging.log4j.Configurator;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Integration tests for LogService and how it configures and uses log4j2
- */
-@Category(LoggingTest.class)
-public class LogServiceIntegrationTest {
-
-  private static final String DEFAULT_CONFIG_FILE_NAME = "log4j2.xml";
-  private static final String CLI_CONFIG_FILE_NAME = "log4j2-cli.xml";
-
-  @Rule
-  public SystemErrRule systemErrRule = new SystemErrRule().enableLog();
-
-  @Rule
-  public SystemOutRule systemOutRule = new SystemOutRule().enableLog();
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Rule
-  public ExternalResource externalResource = new ExternalResource() {
-    @Override
-    protected void before() {
-      beforeConfigFileProp = System.getProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-      beforeLevel = StatusLogger.getLogger().getLevel();
-
-      System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-      StatusLogger.getLogger().setLevel(Level.OFF);
-
-      Configurator.shutdown();
-    }
-
-    @Override
-    protected void after() {
-      Configurator.shutdown();
-
-      System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-      if (beforeConfigFileProp != null) {
-        System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, beforeConfigFileProp);
-      }
-      StatusLogger.getLogger().setLevel(beforeLevel);
-
-      LogService.reconfigure();
-      assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-          .isTrue();
-    }
-  };
-
-  private String beforeConfigFileProp;
-  private Level beforeLevel;
-
-  private URL defaultConfigUrl;
-  private URL cliConfigUrl;
-
-  @Before
-  public void setUp() {
-    defaultConfigUrl = LogService.class.getResource(LogService.DEFAULT_CONFIG);
-    cliConfigUrl = LogService.class.getResource(LogService.CLI_CONFIG);
-  }
-
-  @After
-  public void after() {
-    // if either of these fail then log4j2 probably logged a failure to stdout
-    assertThat(systemErrRule.getLog()).isEmpty();
-    assertThat(systemOutRule.getLog()).isEmpty();
-  }
-
-  @Test
-  public void shouldPreferConfigurationFilePropertyIfSet() throws Exception {
-    File configFile = temporaryFolder.newFile(DEFAULT_CONFIG_FILE_NAME);
-    String configFileName = configFile.toURI().toString();
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, configFileName);
-    writeConfigFile(configFile, Level.DEBUG);
-
-    LogService.reconfigure();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-    assertThat(System.getProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY))
-        .isEqualTo(configFileName);
-    assertThat(LogService.getLogger().getName()).isEqualTo(getClass().getName());
-  }
-
-  @Test
-  public void shouldUseDefaultConfigIfNotConfigured() {
-    LogService.reconfigure();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isTrue();
-    assertThat(System.getProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY))
-        .isNullOrEmpty();
-  }
-
-  @Test
-  public void defaultConfigShouldIncludeStdout() {
-    LogService.reconfigure();
-    Logger rootLogger = (Logger) LogService.getRootLogger();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isTrue();
-    assertThat(rootLogger.getAppenders().get(LogService.STDOUT)).isNotNull();
-  }
-
-  @Test
-  public void removeConsoleAppenderShouldRemoveStdout() {
-    LogService.reconfigure();
-    Logger rootLogger = (Logger) LogService.getRootLogger();
-
-    LogService.removeConsoleAppender();
-
-    assertThat(rootLogger.getAppenders().get(LogService.STDOUT)).isNull();
-  }
-
-  @Test
-  public void restoreConsoleAppenderShouldRestoreStdout() {
-    LogService.reconfigure();
-    Logger rootLogger = (Logger) LogService.getRootLogger();
-
-    LogService.removeConsoleAppender();
-
-    assertThat(rootLogger.getAppenders().get(LogService.STDOUT)).isNull();
-
-    LogService.restoreConsoleAppender();
-
-    assertThat(rootLogger.getAppenders().get(LogService.STDOUT)).isNotNull();
-  }
-
-  @Test
-  public void removeAndRestoreConsoleAppenderShouldAffectRootLogger() {
-    LogService.reconfigure();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isTrue();
-
-    Logger rootLogger = (Logger) LogService.getRootLogger();
-
-    // assert "Console" is present for ROOT
-    Appender appender = rootLogger.getAppenders().get(LogService.STDOUT);
-    assertThat(appender).isNotNull();
-
-    LogService.removeConsoleAppender();
-
-    // assert "Console" is not present for ROOT
-    appender = rootLogger.getAppenders().get(LogService.STDOUT);
-    assertThat(appender).isNull();
-
-    LogService.restoreConsoleAppender();
-
-    // assert "Console" is present for ROOT
-    appender = rootLogger.getAppenders().get(LogService.STDOUT);
-    assertThat(appender).isNotNull();
-  }
-
-  @Test
-  public void shouldNotUseDefaultConfigIfCliConfigSpecified() {
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY,
-        cliConfigUrl.toString());
-
-    LogService.reconfigure();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-    assertThat(System.getProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY))
-        .isEqualTo(cliConfigUrl.toString());
-    assertThat(LogService.getLogger().getName()).isEqualTo(getClass().getName());
-  }
-
-  @Test
-  public void isUsingGemFireDefaultConfigShouldBeTrueIfDefaultConfig() {
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY,
-        defaultConfigUrl.toString());
-
-    assertThat(LogService.getConfiguration().getConfigurationSource().toString())
-        .contains(DEFAULT_CONFIG_FILE_NAME);
-    assertThat(LogService.isUsingGemFireDefaultConfig()).isTrue();
-  }
-
-  @Test
-  public void isUsingGemFireDefaultConfigShouldBeFalseIfCliConfig() {
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY,
-        cliConfigUrl.toString());
-
-    assertThat(LogService.getConfiguration().getConfigurationSource().toString())
-        .doesNotContain(DEFAULT_CONFIG_FILE_NAME);
-    assertThat(LogService.isUsingGemFireDefaultConfig()).isFalse();
-  }
-
-  @Test
-  public void shouldUseCliConfigIfCliConfigIsSpecifiedViaClasspath() {
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY,
-        "classpath:" + CLI_CONFIG_FILE_NAME);
-
-    assertThat(LogService.getConfiguration().getConfigurationSource().toString())
-        .contains(CLI_CONFIG_FILE_NAME);
-    assertThat(LogService.isUsingGemFireDefaultConfig()).isFalse();
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithDistributedSystemIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithDistributedSystemIntegrationTest.java
new file mode 100755
index 0000000..4880f5c
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithDistributedSystemIntegrationTest.java
@@ -0,0 +1,1597 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_LEVEL;
+import static org.apache.geode.internal.logging.LogWriterLevel.CONFIG;
+import static org.apache.geode.internal.logging.LogWriterLevel.ERROR;
+import static org.apache.geode.internal.logging.LogWriterLevel.FINE;
+import static org.apache.geode.internal.logging.LogWriterLevel.FINER;
+import static org.apache.geode.internal.logging.LogWriterLevel.FINEST;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.internal.logging.LogWriterLevel.SEVERE;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.getLoggerConfig;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.logging.log4j.FastLogger;
+import org.apache.geode.internal.logging.log4j.Log4jAgent;
+import org.apache.geode.internal.logging.log4j.LogWriterLogger;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for logging with {@link InternalDistributedSystem} lifecycle.
+ */
+@Category(LoggingTest.class)
+public class LoggingWithDistributedSystemIntegrationTest {
+
+  private static final String APPLICATION_LOGGER_NAME = "com.application";
+  private static final AtomicInteger COUNTER = new AtomicInteger();
+
+  private String currentWorkingDirPath;
+  private File mainLogFile;
+  private String mainLogFilePath;
+  private File securityLogFile;
+  private String securityLogFilePath;
+  private InternalDistributedSystem system;
+  private String prefix;
+
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() {
+    File currentWorkingDir = new File("");
+    currentWorkingDirPath = currentWorkingDir.getAbsolutePath();
+
+    String name = testName.getMethodName();
+    mainLogFile = new File(temporaryFolder.getRoot(), name + "-main.log");
+    mainLogFilePath = mainLogFile.getAbsolutePath();
+    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");
+    securityLogFilePath = securityLogFile.getAbsolutePath();
+
+    prefix = "ExpectedStrings: " + testName.getMethodName() + " message logged at level ";
+
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogManager.getLogger(APPLICATION_LOGGER_NAME);
+
+    Log4jAgent.updateLogLevel(Level.INFO, getLoggerConfig(applicationLogger));
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (system != null) {
+      system.disconnect();
+    }
+  }
+
+  @Test
+  public void applicationLoggerLevelIsInfo() {
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+
+  @Test
+  public void defaultConfigForLogging() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    LogConfig logConfig = system.getLogConfig();
+
+    assertThat(logConfig.getName()).isEqualTo("");
+    assertThat(logConfig.getLogFile().getAbsolutePath()).isEqualTo(currentWorkingDirPath);
+    assertThat(logConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(0);
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(0);
+    assertThat(logConfig.getSecurityLogFile().getAbsolutePath()).isEqualTo(currentWorkingDirPath);
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(CONFIG.intLevel());
+  }
+
+  @Test
+  public void bothLogFilesConfigured() throws Exception {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(SECURITY_LOG_FILE, securityLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriterLogger = (LogWriterLogger) system.getLogWriter();
+    LogWriterLogger securityLogWriterLogger = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> {
+      system.getLogWriter().info("log another line");
+
+      assertThat(mainLogFile).exists();
+      assertThat(securityLogFile).exists();
+
+      // assertThat mainLogFile is not empty
+      try (FileInputStream fis = new FileInputStream(mainLogFile)) {
+        assertThat(fis.available()).isGreaterThan(0);
+      }
+    });
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(CONFIG.intLevel());
+
+    assertThat(distributionConfig.getLogFile().getAbsolutePath()).isEqualTo(mainLogFilePath);
+    assertThat(distributionConfig.getSecurityLogFile().getAbsolutePath())
+        .isEqualTo(securityLogFilePath);
+
+    assertThat(system.getLogWriter()).isInstanceOf(LogWriterLogger.class);
+    assertThat(system.getSecurityLogWriter()).isInstanceOf(LogWriterLogger.class);
+
+    assertThat(logWriterLogger.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+    assertThat(securityLogWriterLogger.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    securityLogWriterLogger.info("test: security log file created at info");
+
+    // assertThat securityLogFile is not empty
+    try (FileInputStream fis = new FileInputStream(securityLogFile)) {
+      assertThat(fis.available()).isGreaterThan(0);
+    }
+
+    LogWriter logWriter = logWriterLogger;
+    assertThat(logWriter.finestEnabled()).isFalse();
+    assertThat(logWriter.finerEnabled()).isFalse();
+    assertThat(logWriter.fineEnabled()).isFalse();
+    assertThat(logWriter.configEnabled()).isTrue();
+    assertThat(logWriter.infoEnabled()).isTrue();
+    assertThat(logWriter.warningEnabled()).isTrue();
+    assertThat(logWriter.errorEnabled()).isTrue();
+    assertThat(logWriter.severeEnabled()).isTrue();
+
+    FastLogger logWriterFastLogger = logWriterLogger;
+    assertThat(logWriterFastLogger.isDelegating()).isFalse();
+    assertThat(logWriterFastLogger.isTraceEnabled()).isFalse();
+    assertThat(logWriterFastLogger.isDebugEnabled()).isFalse();
+    assertThat(logWriterFastLogger.isInfoEnabled()).isTrue();
+    assertThat(logWriterFastLogger.isWarnEnabled()).isTrue();
+    assertThat(logWriterFastLogger.isErrorEnabled()).isTrue();
+    assertThat(logWriterFastLogger.isFatalEnabled()).isTrue();
+
+    LogWriter securityLogWriter = securityLogWriterLogger;
+    assertThat(securityLogWriter.finestEnabled()).isFalse();
+    assertThat(securityLogWriter.finerEnabled()).isFalse();
+    assertThat(securityLogWriter.fineEnabled()).isFalse();
+    assertThat(securityLogWriter.configEnabled()).isTrue();
+    assertThat(securityLogWriter.infoEnabled()).isTrue();
+    assertThat(securityLogWriter.warningEnabled()).isTrue();
+    assertThat(securityLogWriter.errorEnabled()).isTrue();
+    assertThat(securityLogWriter.severeEnabled()).isTrue();
+
+    FastLogger securityLogWriterFastLogger = logWriterLogger;
+    assertThat(securityLogWriterFastLogger.isDelegating()).isFalse();
+    assertThat(securityLogWriterFastLogger.isTraceEnabled()).isFalse();
+    assertThat(securityLogWriterFastLogger.isDebugEnabled()).isFalse();
+    assertThat(securityLogWriterFastLogger.isInfoEnabled()).isTrue();
+    assertThat(securityLogWriterFastLogger.isWarnEnabled()).isTrue();
+    assertThat(securityLogWriterFastLogger.isErrorEnabled()).isTrue();
+    assertThat(securityLogWriterFastLogger.isFatalEnabled()).isTrue();
+  }
+
+  @Test
+  public void mainLogWriterLogsToMainLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // CONFIG level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // FINE level
+
+    distributionConfig.setLogLevel(FINE.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+
+    message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(ERROR.intLevel());
+
+    message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void securityLogWriterLogsToMainLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // CONFIG level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // FINE level
+
+    distributionConfig.setLogLevel(FINE.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void geodeLoggerLogsToMainLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // CONFIG level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.INFO);
+
+    String message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // FINE level
+
+    distributionConfig.setLogLevel(FINE.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
+
+    message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void applicationLoggerLogsToMainLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // CONFIG level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+
+    String message = createMessage(Level.TRACE);
+    applicationLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    applicationLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    applicationLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    applicationLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    applicationLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    applicationLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // FINE level
+
+    distributionConfig.setLogLevel(FINE.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+
+    message = createMessage(Level.TRACE);
+    applicationLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    applicationLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    applicationLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    applicationLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    applicationLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    applicationLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+
+    message = createMessage(Level.TRACE);
+    applicationLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    applicationLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    applicationLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    applicationLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    applicationLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    applicationLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void mainLogWriterLogsToMainLogFileWithMainLogLevelFine() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // FINE level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+
+    String message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(ERROR.intLevel());
+
+    message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void securityLogWriterLogsToMainLogFileWithMainLogLevelFine() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void geodeLoggerLogsToMainLogFileWithMainLogLevelFine() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // FINE level
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    String message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR level
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
+
+    message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void mainLogWriterLogsToMainLogFileWithMainLogLevelDebug() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, Level.DEBUG.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // DEBUG LEVEL
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+
+    String message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR LEVEL
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(ERROR.intLevel());
+
+    message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void securityLogWriterLogsToMainLogFileWithMainLogLevelDebug() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, Level.DEBUG.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void geodeLoggerLogsToMainLogFileWithMainLogLevelDebug() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, Level.DEBUG.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    // DEBUG LEVEL
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    String message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    // ERROR LEVEL
+
+    distributionConfig.setLogLevel(ERROR.intLevel());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(ERROR.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.ERROR);
+
+    message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void logsToDifferentLogFilesWithMainLogLevelFine() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+    config.setProperty(SECURITY_LOG_FILE, securityLogFilePath);
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> {
+      assertThat(mainLogFile).exists();
+      assertThat(securityLogFile).exists();
+    });
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(CONFIG.intLevel());
+
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  @Test
+  public void logsToDifferentLogFilesWithBothLogLevelsFine() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+    config.setProperty(SECURITY_LOG_FILE, securityLogFilePath);
+    config.setProperty(SECURITY_LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> {
+      assertThat(mainLogFile).exists();
+      assertThat(securityLogFile).exists();
+    });
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(FINE.intLevel());
+
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(securityLogFile).contains(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a less granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void mainLogWriterLogsToMainLogFileWithHigherSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+    config.setProperty(SECURITY_LOG_LEVEL, INFO.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+
+    String message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a less granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void securityLogWriterLogsToMainLogFileWithHigherSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+    config.setProperty(SECURITY_LOG_LEVEL, INFO.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a less granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void geodeLoggerLogsToMainLogFileWithHigherSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, FINE.name());
+    config.setProperty(SECURITY_LOG_LEVEL, INFO.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(FINE.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.DEBUG);
+
+    String message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a more granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void mainLogWriterLogsToMainLogFileWithLowerSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, INFO.name());
+    config.setProperty(SECURITY_LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger logWriter = (LogWriterLogger) system.getLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(FINE.intLevel());
+
+    assertThat(logWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    String message = createMessage(FINEST);
+    logWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    logWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    logWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(CONFIG);
+    logWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    logWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    logWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    logWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    logWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a more granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void securityLogWriterLogsToMainLogFileWithLowerSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, INFO.name());
+    config.setProperty(SECURITY_LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    LogWriterLogger securityLogWriter = (LogWriterLogger) system.getSecurityLogWriter();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(FINE.intLevel());
+
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(FINE.intLevel());
+
+    String message = createMessage(FINEST);
+    securityLogWriter.finest(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINER);
+    securityLogWriter.finer(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(FINE);
+    securityLogWriter.fine(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(CONFIG);
+    securityLogWriter.config(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(INFO);
+    securityLogWriter.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(WARNING);
+    securityLogWriter.warning(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(ERROR);
+    securityLogWriter.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(SEVERE);
+    securityLogWriter.severe(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  /**
+   * tests scenario where security log has not been set but a level has been set to a more granular
+   * level than that of the regular log. Verifies that the correct logs for security show up in the
+   * regular log as expected
+   */
+  @Test
+  public void geodeLoggerLogsToMainLogFileWithLowerSecurityLogLevel() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFilePath);
+    config.setProperty(LOG_LEVEL, INFO.name());
+    config.setProperty(SECURITY_LOG_LEVEL, FINE.name());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    await().untilAsserted(() -> assertThat(mainLogFile).exists());
+
+    assertThat(distributionConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+    assertThat(distributionConfig.getSecurityLogLevel()).isEqualTo(FINE.intLevel());
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.INFO);
+
+    String message = createMessage(Level.TRACE);
+    geodeLogger.trace(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.DEBUG);
+    geodeLogger.debug(message);
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(message);
+
+    message = createMessage(Level.INFO);
+    geodeLogger.info(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.WARN);
+    geodeLogger.warn(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.ERROR);
+    geodeLogger.error(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+
+    message = createMessage(Level.FATAL);
+    geodeLogger.fatal(message);
+    LogFileAssert.assertThat(mainLogFile).contains(message);
+  }
+
+  private String createMessage(LogWriterLevel logLevel) {
+    return prefix + logLevel.name() + " [" + COUNTER.incrementAndGet() + "]";
+  }
+
+  private String createMessage(Level level) {
+    return prefix + level.name() + " [" + COUNTER.incrementAndGet() + "]";
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java
new file mode 100644
index 0000000..cd1ed35
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.NAME;
+import static org.apache.geode.internal.logging.LogWriterLevel.CONFIG;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.Locator;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.InternalLocator;
+import org.apache.geode.internal.AvailablePort;
+import org.apache.geode.internal.logging.log4j.LogWriterLogger;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for logging with {@link InternalLocator} lifecycle.
+ */
+@Category(LoggingTest.class)
+public class LoggingWithLocatorIntegrationTest {
+
+  private String name;
+  private int port;
+  private String currentWorkingDirPath;
+  private File logFile;
+  private File securityLogFile;
+
+  private InternalLocator locator;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() throws Exception {
+    name = testName.getMethodName();
+
+    File currentWorkingDir = new File("");
+    currentWorkingDirPath = currentWorkingDir.getAbsolutePath();
+    logFile = new File(temporaryFolder.getRoot(),
+        testName.getMethodName() + "-system-" + System.currentTimeMillis() + ".log");
+    securityLogFile = new File("");
+
+    port = AvailablePort.getRandomAvailablePort(AvailablePort.SOCKET);
+  }
+
+  @After
+  public void tearDown() {
+    if (locator != null) {
+      locator.stop();
+    }
+  }
+
+  @Test
+  public void startLocatorDefaultLoggingConfig() throws Exception {
+    Properties config = new Properties();
+
+    locator = InternalLocator.startLocator(port, null, null, null, null, false, config, null);
+
+    LogConfig logConfig = locator.getLogConfig();
+
+    assertThat(logConfig.getName()).isEqualTo("");
+    assertThat(logConfig.getLogFile().getAbsolutePath()).isEqualTo(currentWorkingDirPath);
+    assertThat(logConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(0);
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(0);
+    assertThat(logConfig.getSecurityLogFile().getAbsolutePath())
+        .isEqualTo(currentWorkingDirPath);
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(CONFIG.intLevel());
+  }
+
+  @Test
+  public void startLocatorDefaultLoggingConfigWithLogFile() throws Exception {
+    Properties config = new Properties();
+
+    locator = InternalLocator.startLocator(port, logFile, null, null, null, false, config, null);
+
+    LogConfig logConfig = locator.getLogConfig();
+
+    assertThat(logConfig.getName()).isEqualTo("");
+    assertThat(logConfig.getLogFile().getAbsolutePath()).isEqualTo(logFile.getAbsolutePath());
+    assertThat(logConfig.getLogLevel()).isEqualTo(CONFIG.intLevel());
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(0);
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(0);
+    assertThat(logConfig.getSecurityLogFile().getAbsolutePath())
+        .isEqualTo(currentWorkingDirPath);
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(CONFIG.intLevel());
+  }
+
+  @Test
+  public void startLocatorAndDSCreatesLogFile() throws Exception {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "localhost[" + port + "]");
+    config.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false");
+
+    locator = (InternalLocator) Locator.startLocatorAndDS(port, logFile, config);
+
+    await().untilAsserted(() -> assertThat(logFile).exists());
+
+    // assertThat logFile is not empty
+    try (FileInputStream fis = new FileInputStream(logFile)) {
+      assertThat(fis.available()).isGreaterThan(0);
+    }
+
+    InternalDistributedSystem system = (InternalDistributedSystem) locator.getDistributedSystem();
+
+    assertThat(system.getLogWriter()).isInstanceOf(LogWriterLogger.class);
+    assertThat(system.getSecurityLogWriter()).isInstanceOf(LogWriterLogger.class);
+
+    LogWriterLogger logWriterLogger = (LogWriterLogger) system.getLogWriter();
+    LogWriterLogger securityLogWriterLogger = (LogWriterLogger) system.getSecurityLogWriter();
+
+    assertThat(logWriterLogger.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+    assertThat(securityLogWriterLogger.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    DistributionConfig distributionConfig = system.getConfig();
+
+    assertThat(distributionConfig.getLogFile().getAbsolutePath())
+        .isEqualTo(logFile.getAbsolutePath());
+    assertThat(distributionConfig.getSecurityLogFile().getAbsolutePath())
+        .isEqualTo(currentWorkingDirPath);
+
+    assertThat(securityLogFile).doesNotExist();
+  }
+
+  @Test
+  public void locatorWithNoDS() throws Exception {
+    Properties config = new Properties();
+    config.setProperty(NAME, name);
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+    config.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false");
+
+    locator = InternalLocator.startLocator(port, null, null, null, null, false, config, null);
+    Logger logger = LogService.getLogger();
+
+    // assert that logging goes to logFile
+    String logMessageBeforeClose = "Logging before locator is stopped in " + name;
+    logger.info(logMessageBeforeClose);
+
+    LogFileAssert.assertThat(logFile).contains(logMessageBeforeClose);
+
+    locator.stop();
+
+    // assert that logging stops going to logFile
+    String logMessageAfterClose = "Logging after locator is stopped in " + name;
+    logger.info(logMessageAfterClose);
+    LogFileAssert.assertThat(logFile).doesNotContain(logMessageAfterClose);
+  }
+
+  @Test
+  public void locatorWithDS() throws Exception {
+    Properties config = new Properties();
+    config.setProperty(NAME, name);
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+    config.setProperty(ENABLE_CLUSTER_CONFIGURATION, "false");
+
+    locator = (InternalLocator) InternalLocator.startLocatorAndDS(port, null, config);
+    Logger logger = LogService.getLogger();
+
+    // assert that logging goes to logFile
+    String logMessageBeforeClose = "Logging before locator is stopped in " + name;
+    logger.info(logMessageBeforeClose);
+
+    LogFileAssert.assertThat(logFile).contains(logMessageBeforeClose);
+
+    locator.stop();
+
+    // assert that logging stops going to logFile
+    String logMessageAfterClose = "Logging after locator is stopped in " + name;
+    logger.info(logMessageAfterClose);
+    LogFileAssert.assertThat(logFile).doesNotContain(logMessageAfterClose);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java
new file mode 100644
index 0000000..50d318a
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.logging;
+
+import static org.apache.geode.internal.Banner.BannerHeader.displayValues;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.distributed.LocatorLauncherIntegrationTestCase;
+import org.apache.geode.internal.process.ProcessControllerFactory;
+import org.apache.geode.internal.process.ProcessType;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests of logging with {@link LocatorLauncher}.
+ */
+@Category(LoggingTest.class)
+public class LoggingWithLocatorLauncherIntegrationTest extends LocatorLauncherIntegrationTestCase {
+
+  @Before
+  public void setUp() throws Exception {
+    System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-");
+    assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue();
+
+    givenRunningLocator();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    disconnectFromDS();
+  }
+
+  @Test
+  public void logFileExists() {
+    assertThat(getLogFile()).exists();
+  }
+
+  @Test
+  public void logFileContainsBanner() {
+    LogFileAssert.assertThat(getLogFile()).contains(displayValues());
+  }
+
+  @Test
+  public void logFileContainsBannerOnlyOnce() {
+    LogFileAssert.assertThat(getLogFile()).containsOnlyOnce(displayValues());
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java
new file mode 100644
index 0000000..182e1c4
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.logging;
+
+import static org.apache.geode.internal.Banner.BannerHeader.displayValues;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.distributed.ServerLauncherIntegrationTestCase;
+import org.apache.geode.internal.process.ProcessControllerFactory;
+import org.apache.geode.internal.process.ProcessType;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests of logging with {@link ServerLauncher}.
+ */
+@Category(LoggingTest.class)
+public class LoggingWithServerLauncherIntegrationTest extends ServerLauncherIntegrationTestCase {
+
+  @Before
+  public void setUp() throws Exception {
+    System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-");
+    assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue();
+
+    givenRunningServer();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    disconnectFromDS();
+  }
+
+  @Test
+  public void logFileExists() {
+    assertThat(getLogFile()).exists();
+  }
+
+  @Test
+  public void logFileContainsBanner() {
+    LogFileAssert.assertThat(getLogFile()).contains(displayValues());
+  }
+
+  @Test
+  public void logFileContainsBannerOnlyOnce() {
+    LogFileAssert.assertThat(getLogFile()).containsOnlyOnce(displayValues());
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ManagerLogWriterFactoryIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ManagerLogWriterFactoryIntegrationTest.java
new file mode 100644
index 0000000..d7264f4
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ManagerLogWriterFactoryIntegrationTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.apache.geode.internal.logging.LogWriterLevel.FINE;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.internal.statistics.StatisticsConfig;
+
+/**
+ * Integration tests for {@link ManagerLogWriterFactory}.
+ */
+public class ManagerLogWriterFactoryIntegrationTest {
+
+  private File mainLogFile;
+  private String mainLogFilePath;
+  private File securityLogFile;
+  private String securityLogFilePath;
+  private LogConfig mainLogConfig;
+  private LogConfig securityLogConfig;
+  private StatisticsConfig statisticsConfig;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() {
+    String name = getClass().getSimpleName() + "_" + testName.getMethodName();
+
+    mainLogFile = new File(temporaryFolder.getRoot(), name + "-main.log");
+    mainLogFilePath = mainLogFile.getAbsolutePath();
+
+    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");
+    securityLogFilePath = securityLogFile.getAbsolutePath();
+
+    mainLogConfig = mock(LogConfig.class);
+    securityLogConfig = mock(LogConfig.class);
+    statisticsConfig = mock(StatisticsConfig.class);
+
+    when(mainLogConfig.getLogFile()).thenReturn(mainLogFile);
+    when(mainLogConfig.getLogLevel()).thenReturn(FINE.intLevel());
+
+    when(securityLogConfig.getLogFile()).thenReturn(mainLogFile);
+    when(securityLogConfig.getLogLevel()).thenReturn(FINE.intLevel());
+    when(securityLogConfig.getSecurityLogFile()).thenReturn(securityLogFile);
+    when(securityLogConfig.getSecurityLogLevel()).thenReturn(WARNING.intLevel());
+  }
+
+  @Test
+  public void getLogFileReturnsMainLogFileIfSecurityIsFalse() {
+    File logFile = new ManagerLogWriterFactory().setSecurity(false).getLogFile(mainLogConfig);
+
+    assertThat(logFile.getAbsolutePath()).isEqualTo(mainLogFilePath);
+  }
+
+  @Test
+  public void getLogFileReturnsSecurityLogFileIfSecurityIsTrue() {
+    File logFile = new ManagerLogWriterFactory().setSecurity(true).getLogFile(securityLogConfig);
+
+    assertThat(logFile.getAbsolutePath()).isEqualTo(securityLogFilePath);
+  }
+
+  @Test
+  public void getLogLevelReturnsMainLogLevelIfSecurityIsFalse() {
+    int level = new ManagerLogWriterFactory().setSecurity(false).getLogLevel(mainLogConfig);
+
+    assertThat(level).isEqualTo(FINE.intLevel());
+  }
+
+  @Test
+  public void getLogLevelReturnsSecurityLogLevelIfSecurityIsTrue() {
+    int level = new ManagerLogWriterFactory().setSecurity(true).getLogLevel(securityLogConfig);
+
+    assertThat(level).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void createReturnsManagerLogWriterIfSecurityIsFalse() {
+    ManagerLogWriter logWriter =
+        new ManagerLogWriterFactory().setSecurity(false).create(mainLogConfig, statisticsConfig);
+
+    assertThat(logWriter).isNotInstanceOf(SecurityManagerLogWriter.class);
+  }
+
+  @Test
+  public void createUsesMainLogFileIfSecurityIsFalse() {
+    new ManagerLogWriterFactory().setSecurity(false).create(mainLogConfig, statisticsConfig);
+
+    assertThat(mainLogFile).exists();
+    assertThat(securityLogFile).doesNotExist();
+  }
+
+  @Test
+  public void createReturnsSecurityManagerLogWriterIfSecurityIsTrue() {
+    ManagerLogWriter logWriter =
+        new ManagerLogWriterFactory().setSecurity(true).create(securityLogConfig, statisticsConfig);
+
+    assertThat(logWriter).isInstanceOf(SecurityManagerLogWriter.class);
+  }
+
+  @Test
+  public void createUsesSecurityLogFileIfSecurityIsTrue() {
+    new ManagerLogWriterFactory().setSecurity(true).create(securityLogConfig, statisticsConfig);
+
+    assertThat(mainLogFile).doesNotExist();
+    assertThat(securityLogFile).exists();
+  }
+
+  @Test
+  public void createSetsConfigOnLogWriterIfSecurityIsFalse() {
+    ManagerLogWriter logWriter =
+        new ManagerLogWriterFactory().setSecurity(false).create(mainLogConfig, statisticsConfig);
+
+    assertThat(logWriter.getConfig()).isNotNull();
+    assertThat(logWriter.getConfig().getLogFile().getAbsolutePath()).isSameAs(mainLogFilePath);
+  }
+
+  @Test
+  public void createSetsConfigWithSecurityLogFileIfSecurityIsTrue() {
+    ManagerLogWriter logWriter =
+        new ManagerLogWriterFactory().setSecurity(true).create(securityLogConfig, statisticsConfig);
+
+    assertThat(logWriter.getConfig()).isNotNull().isInstanceOf(SecurityLogConfig.class);
+    assertThat(logWriter.getConfig().getLogFile().getAbsolutePath()).isSameAs(securityLogFilePath);
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/NonBlankStrings.java
similarity index 61%
copy from geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
copy to geode-core/src/integrationTest/java/org/apache/geode/internal/logging/NonBlankStrings.java
index 1bede46..d215caf 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/NonBlankStrings.java
@@ -14,25 +14,14 @@
  */
 package org.apache.geode.internal.logging;
 
-import static org.assertj.core.api.Assertions.assertThat;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
 
-import java.io.Serializable;
+import java.util.List;
+import java.util.stream.Collectors;
 
-import org.apache.commons.lang3.SerializationUtils;
-import org.junit.Test;
+public class NonBlankStrings {
 
-public class LogWriterLevelTest {
-
-  @Test
-  public void isSerializable() {
-    assertThat(LogWriterLevel.ALL).isInstanceOf(Serializable.class);
+  public static List<String> nonBlankStrings(List<String> values) {
+    return values.stream().filter(s -> isNotBlank(s)).collect(Collectors.toList());
   }
-
-  @Test
-  public void serializes() {
-    LogWriterLevel logLevel = (LogWriterLevel) SerializationUtils.clone(LogWriterLevel.ALL);
-
-    assertThat(logLevel).isEqualTo(LogWriterLevel.ALL).isSameAs(LogWriterLevel.ALL);
-  }
-
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java
new file mode 100644
index 0000000..e76b0a0
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.geode.internal.logging;
+
+import static java.lang.System.lineSeparator;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.NAME;
+import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.Banner;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for logging of the startup configuration. Startup configuration consists of
+ * {@link Configuration#STARTUP_CONFIGURATION} and {@link DistributionConfig#toLoggerString()}.
+ */
+@Category(LoggingTest.class)
+public class StartupConfigurationLoggingIntegrationTest {
+
+  private File mainLogFile;
+  private InternalDistributedSystem system;
+  private String banner;
+  private String[] startupConfiguration;
+  private Logger geodeLogger;
+  private String logMessage;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() {
+    String name = testName.getMethodName();
+    mainLogFile = new File(temporaryFolder.getRoot(), name + "-main.log");
+
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFile.getAbsolutePath());
+    config.setProperty(NAME, getClass().getSimpleName() + "_" + testName.getMethodName());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    banner = Banner.getString(null);
+
+    DistributionConfig distributionConfig = system.getConfig();
+    startupConfiguration = StringUtils
+        .split(STARTUP_CONFIGURATION + distributionConfig.toLoggerString(), lineSeparator());
+
+    geodeLogger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (system != null) {
+      system.disconnect();
+    }
+  }
+
+  @Test
+  public void startupConfigurationIsLoggedToFile() {
+    LogFileAssert.assertThat(mainLogFile).contains(startupConfiguration);
+  }
+
+  @Test
+  public void startupConfigurationIsLoggedToFileOnlyOnce() {
+    LogFileAssert.assertThat(mainLogFile).containsOnlyOnce(startupConfiguration);
+  }
+
+  @Test
+  public void startupConfigurationIsLoggedToFileAfterBanner() throws Exception {
+    List<String> bannerLines = Arrays.asList(StringUtils.split(banner, lineSeparator()));
+    List<String> startupConfigLines = Arrays.asList(startupConfiguration);
+    List<String> logLines = FileUtils.readLines(mainLogFile, Charset.defaultCharset());
+
+    boolean foundBanner = false;
+    boolean foundStartupConfig = false;
+
+    for (String line : logLines) {
+      if (bannerLines.contains(line)) {
+        assertThat(foundStartupConfig)
+            .as("Banner should be logged before startup configuration: " + logLines).isFalse();
+        foundBanner = true;
+      }
+      if (startupConfigLines.contains(line)) {
+        assertThat(foundBanner)
+            .as("Startup configuration should be logged before banner: " + logLines).isTrue();
+        foundStartupConfig = true;
+      }
+    }
+
+    assertThat(foundBanner).as("Banner not found in: " + logLines).isTrue();
+    assertThat(foundStartupConfig).as("Startup configuration not found in: " + logLines).isTrue();
+  }
+
+  @Test
+  public void startupConfigurationIsLoggedToFileBeforeLogMessage() throws Exception {
+    geodeLogger.info(logMessage);
+
+    List<String> startupConfigLines = Arrays.asList(startupConfiguration);
+    List<String> logLines = FileUtils.readLines(mainLogFile, Charset.defaultCharset());
+
+    boolean foundStartupConfig = false;
+    boolean foundLogMessage = false;
+
+    for (String line : logLines) {
+      if (startupConfigLines.contains(line)) {
+        assertThat(foundLogMessage)
+            .as("Startup configuration should be before log message: " + logLines).isFalse();
+        foundStartupConfig = true;
+      }
+      if (line.contains(logMessage)) {
+        assertThat(foundStartupConfig)
+            .as("Log message should be after startup configuration: " + logLines).isTrue();
+        foundLogMessage = true;
+      }
+    }
+
+    assertThat(foundStartupConfig).as("Startup configuration not found in: " + logLines).isTrue();
+    assertThat(foundLogMessage).as("Log message not found in: " + logLines).isTrue();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java
new file mode 100644
index 0000000..aded0b4
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.geode.internal.logging;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.PrintStream;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemErrRule;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Verifies behavior of {@code SystemOutRule} and {@code SystemErrRule} that other Geode logging
+ * tests depend on. If this behavior changes, then those tests may also need to change.
+ */
+@Category(LoggingTest.class)
+public class SystemOutRuleAndSystemErrRuleIntegrationTest {
+
+  private static PrintStream systemOutBeforeRule;
+  private static PrintStream systemErrBeforeRule;
+
+  private PrintStream systemOutAfterRule;
+  private PrintStream systemErrAfterRule;
+  private String message;
+
+  @Rule
+  public SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+  @Rule
+  public SystemErrRule systemErrRule = new SystemErrRule().enableLog();
+
+  @BeforeClass
+  public static void beforeClass() {
+    systemOutBeforeRule = System.out;
+    systemErrBeforeRule = System.err;
+  }
+
+  @Before
+  public void setUp() {
+    systemOutAfterRule = System.out;
+    systemErrAfterRule = System.err;
+    message = "simple message";
+  }
+
+  @AfterClass
+  public static void afterClass() {
+    systemOutBeforeRule = null;
+    systemErrBeforeRule = null;
+  }
+
+  @Test
+  public void ruleDoesNotReceiveFromSystemOutBeforeRule() {
+    systemOutBeforeRule.println(message);
+
+    assertThat(systemOutRule.getLog()).doesNotContain(message);
+  }
+
+  @Test
+  public void ruleDoesReceiveFromSystemOutAfterRule() {
+    systemOutAfterRule.println(message);
+
+    assertThat(systemOutRule.getLog()).contains(message);
+  }
+
+  @Test
+  public void ruleDoesNotReceiveFromSystemErrBeforeRule() {
+    systemErrBeforeRule.println(message);
+
+    assertThat(systemErrRule.getLog()).doesNotContain(message);
+  }
+
+  @Test
+  public void ruleDoesReceiveFromSystemErrAfterRule() {
+    systemErrAfterRule.println(message);
+
+    assertThat(systemErrRule.getLog()).contains(message);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest.java
new file mode 100644
index 0000000..b0d55d2
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.internal.logging.Configuration.MAIN_LOGGER_NAME;
+import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.SessionContext;
+import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+import org.apache.geode.test.junit.categories.SecurityTest;
+
+/**
+ * Integration tests for main and security {@link LogWriterAppender}s, loggers, and
+ * {@link ConfigurationProperties#LOG_FILE} and {@link ConfigurationProperties#SECURITY_LOG_FILE}.
+ */
+@Category({LoggingTest.class, SecurityTest.class})
+public class BothLogWriterAppendersIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME = "BothLogWriterAppendersIntegrationTest_log4j2.xml";
+  private static final String MAIN_APPENDER_NAME = "LOGWRITER";
+  private static final String SECURITY_APPENDER_NAME = "SECURITYLOGWRITER";
+
+  private static String configFilePath;
+
+  private File securityLogFile;
+  private Logger mainGeodeLogger;
+  private Logger securityGeodeLogger;
+  private String logMessage;
+  private LogWriterAppender mainLogWriterAppender;
+  private LogWriterAppender securityLogWriterAppender;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    String name = testName.getMethodName();
+    File mainLogFile = new File(temporaryFolder.getRoot(), name + ".log");
+    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");
+
+    LogConfig logConfig = mock(LogConfig.class);
+    when(logConfig.getName()).thenReturn(name);
+    when(logConfig.getLogFile()).thenReturn(mainLogFile);
+    when(logConfig.getSecurityLogFile()).thenReturn(securityLogFile);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
+    when(logConfigSupplier.getStatisticsConfig()).thenReturn(mock(StatisticsConfig.class));
+
+    SessionContext sessionContext = mock(SessionContext.class);
+    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);
+
+    mainGeodeLogger = LogService.getLogger(MAIN_LOGGER_NAME);
+    securityGeodeLogger = LogService.getLogger(SECURITY_LOGGER_NAME);
+
+    logMessage = "Logging in " + testName.getMethodName();
+
+    mainLogWriterAppender = loggerContextRule.getAppender(MAIN_APPENDER_NAME,
+        LogWriterAppender.class);
+    securityLogWriterAppender = loggerContextRule.getAppender(SECURITY_APPENDER_NAME,
+        LogWriterAppender.class);
+
+    mainLogWriterAppender.createSession(sessionContext);
+    mainLogWriterAppender.startSession();
+    mainLogWriterAppender.clearLogEvents();
+
+    securityLogWriterAppender.createSession(sessionContext);
+    securityLogWriterAppender.startSession();
+    securityLogWriterAppender.clearLogEvents();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    mainLogWriterAppender.stopSession();
+    securityLogWriterAppender.stopSession();
+  }
+
+  @Test
+  public void mainLogWriterAppenderLogEventsIsEmptyByDefault() {
+    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void securityLogWriterAppenderLogEventsIsEmptyByDefault() {
+    assertThat(securityLogWriterAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void geodeLoggerAppendsToLogWriterAppender() {
+    mainGeodeLogger.info(logMessage);
+
+    assertThat(mainLogWriterAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void geodeLoggerDoesNotAppendToSecurityLogWriterAppender() {
+    mainGeodeLogger.info(logMessage);
+
+    assertThat(securityLogWriterAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void geodeSecurityLoggerAppendsToSecurityLogWriterAppender() {
+    securityGeodeLogger.info(logMessage);
+
+    assertThat(securityLogWriterAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void geodeSecurityLoggerDoesNotAppendToLogWriterAppender() {
+    securityGeodeLogger.info(logMessage);
+
+    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void securityGeodeLoggerLogsToSecurityLogFile() {
+    securityGeodeLogger.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).exists().contains(logMessage);
+  }
+
+  @Test
+  public void securityGeodeLoggerDoesNotLogToMainLogFile() {
+    securityGeodeLogger.info(logMessage);
+
+    assertThat(mainLogWriterAppender.getLogEvents()).isEmpty();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest.java
similarity index 62%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest.java
index bf9e9d9..e959276 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest.java
@@ -17,6 +17,7 @@ package org.apache.geode.internal.logging.log4j;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
 import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
 import static org.apache.geode.test.util.ResourceUtils.getResource;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -27,6 +28,7 @@ import java.util.Properties;
 import java.util.regex.Pattern;
 
 import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
@@ -40,6 +42,7 @@ import org.junit.contrib.java.lang.system.SystemErrRule;
 import org.junit.contrib.java.lang.system.SystemOutRule;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheFactory;
@@ -47,11 +50,13 @@ import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Integration tests with custom log4j2 configuration.
+ * Integration tests for {@link Cache} with custom {@code log4j2.xml}.
  */
 @Category(LoggingTest.class)
-public class CustomConfigWithCacheIntegrationTest {
+public class CacheWithCustomLogConfigIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "CacheWithCustomLogConfigIntegrationTest_log4j2.xml";
   private static final String CONFIG_LAYOUT_PREFIX = "CUSTOM";
   private static final String CUSTOM_REGEX_STRING =
       "CUSTOM: level=[A-Z]+ time=\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} [^ ]{3} message=.*[\\n]+throwable=.*$";
@@ -59,11 +64,12 @@ public class CustomConfigWithCacheIntegrationTest {
 
   private static String configFilePath;
 
-  private LogWriterLogger logWriterLogger;
-  private String logMessage;
-  private ListAppender listAppender;
-
   private Cache cache;
+  private Logger geodeLogger;
+  private Logger logger;
+  private String infoMessage;
+  private String warnMessage;
+  private ListAppender listAppender;
 
   @ClassRule
   public static SystemOutRule systemOutRule = new SystemOutRule().enableLog();
@@ -77,12 +83,13 @@ public class CustomConfigWithCacheIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        CustomConfigWithCacheIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
@@ -91,16 +98,14 @@ public class CustomConfigWithCacheIntegrationTest {
     Properties config = new Properties();
     config.setProperty(LOCATORS, "");
     config.setProperty(MCAST_PORT, "0");
-    config.setProperty(LOG_LEVEL, "info");
+    config.setProperty(LOG_LEVEL, INFO.name());
 
     cache = new CacheFactory(config).create();
 
-    logWriterLogger = (LogWriterLogger) cache.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
+    geodeLogger = (LogWriterLogger) cache.getLogger();
+    logger = LogService.getLogger();
+    infoMessage = "INFO in " + testName.getMethodName();
+    warnMessage = "WARN in " + testName.getMethodName();
     listAppender = loggerContextRule.getListAppender("CUSTOM");
 
     systemOutRule.clearLog();
@@ -109,27 +114,59 @@ public class CustomConfigWithCacheIntegrationTest {
 
   @After
   public void tearDown() throws Exception {
-    if (cache != null) {
-      cache.close();
-    }
+    cache.close();
   }
 
   @Test
-  public void cacheLogWriterMessageShouldMatchCustomConfig() {
-    logWriterLogger.info(logMessage);
-
-    LogEvent logEvent = findLogEventContaining(logMessage);
-
-    assertThat(logEvent.getLoggerName()).isEqualTo(logWriterLogger.getName());
-    assertThat(logEvent.getLevel()).isEqualTo(Level.INFO);
-    assertThat(logEvent.getMessage().getFormattedMessage()).isEqualTo(logMessage);
+  public void loggedMessageShouldMatchCustomLayout() {
+    geodeLogger.warn(warnMessage);
 
-    assertThat(systemOutRule.getLog()).contains(Level.INFO.name());
-    assertThat(systemOutRule.getLog()).contains(logMessage);
+    assertThat(systemOutRule.getLog()).contains(Level.WARN.name());
+    assertThat(systemOutRule.getLog()).contains(warnMessage);
     assertThat(systemOutRule.getLog()).contains(CONFIG_LAYOUT_PREFIX);
     assertThat(CUSTOM_REGEX.matcher(systemOutRule.getLog()).matches()).isTrue();
   }
 
+  @Test
+  public void cacheLogWriterInfoMessageIsSuppressed() {
+    geodeLogger.info(infoMessage);
+
+    assertThat(findLogEventContaining(infoMessage)).as(logEventContaining(infoMessage)).isNull();
+  }
+
+  @Test
+  public void cacheLogWriterWarnMessageIsLogged() {
+    geodeLogger.warn(warnMessage);
+
+    LogEvent logEvent = findLogEventContaining(warnMessage);
+    assertThat(logEvent).as(logEventContaining(warnMessage)).isNotNull();
+    assertThat(logEvent.getLoggerName()).isEqualTo(geodeLogger.getName());
+    assertThat(logEvent.getLevel()).isEqualTo(Level.WARN);
+    assertThat(logEvent.getMessage().getFormattedMessage()).isEqualTo(warnMessage);
+  }
+
+  @Test
+  public void loggerInfoMessageIsSuppressed() {
+    logger.info(infoMessage);
+
+    assertThat(findLogEventContaining(infoMessage)).as(logEventContaining(infoMessage)).isNull();
+  }
+
+  @Test
+  public void loggerWarnMessageIsLogged() {
+    logger.warn(warnMessage);
+
+    LogEvent logEvent = findLogEventContaining(warnMessage);
+    assertThat(logEvent).as(logEventContaining(warnMessage)).isNotNull();
+    assertThat(logEvent.getLoggerName()).isEqualTo(logger.getName());
+    assertThat(logEvent.getLevel()).isEqualTo(Level.WARN);
+    assertThat(logEvent.getMessage().getFormattedMessage()).isEqualTo(warnMessage);
+  }
+
+  private String logEventContaining(final String logMessage) {
+    return "LogEvent containing " + logMessage;
+  }
+
   private LogEvent findLogEventContaining(final String logMessage) {
     List<LogEvent> logEvents = listAppender.getEvents();
     for (LogEvent logEvent : logEvents) {
@@ -137,7 +174,6 @@ public class CustomConfigWithCacheIntegrationTest {
         return logEvent;
       }
     }
-    throw new AssertionError(
-        "Failed to find LogEvent containing " + logMessage + " in " + logEvents);
+    return null;
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithDefaultAppendersIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithDefaultAppendersIntegrationTest.java
new file mode 100644
index 0000000..0956da9
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CacheWithDefaultAppendersIntegrationTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.ALERT_APPENDER_NAME;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.GEODE_CONSOLE_APPENDER_NAME;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.LOGWRITER_APPENDER_NAME;
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.SECURITY_LOGWRITER_APPENDER_NAME;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Validates the default appenders that should exist when a {@code Cache} is created.
+ */
+@Category(LoggingTest.class)
+public class CacheWithDefaultAppendersIntegrationTest {
+
+  private InternalCache cache;
+  private Configuration configuration;
+
+  @Before
+  public void setUp() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    Logger coreLogger = (Logger) LogManager.getRootLogger();
+    LoggerContext context = coreLogger.getContext();
+
+    configuration = context.getConfiguration();
+  }
+
+  @After
+  public void tearDown() {
+    cache.close();
+  }
+
+  @Test
+  public void hasGeodeConsoleAppenderNamed_GEODE_CONSOLE_APPENDER_NAME() {
+    Appender appender = configuration.getAppender(GEODE_CONSOLE_APPENDER_NAME);
+
+    assertThat(appender).isNotNull().isInstanceOf(GeodeConsoleAppender.class);
+  }
+
+  @Test
+  public void hasAlertAppenderNamed_ALERT_APPENDER_NAME() {
+    Appender appender = configuration.getAppender(ALERT_APPENDER_NAME);
+
+    assertThat(appender).isNotNull().isInstanceOf(AlertAppender.class);
+  }
+
+  @Test
+  public void hasLogWriterAppenderNamed_LOGWRITER_APPENDER_NAME() {
+    Appender appender = configuration.getAppender(LOGWRITER_APPENDER_NAME);
+
+    assertThat(appender).isNotNull().isInstanceOf(LogWriterAppender.class);
+  }
+
+  @Test
+  public void hasLogWriterAppenderNamed_SECURITY_LOGWRITER_APPENDER_NAME() {
+    Appender appender = configuration.getAppender(SECURITY_LOGWRITER_APPENDER_NAME);
+
+    assertThat(appender).isNotNull().isInstanceOf(LogWriterAppender.class);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest.java
new file mode 100644
index 0000000..7509da3
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.internal.logging.Configuration.DEFAULT_LOGWRITER_LEVEL;
+import static org.apache.geode.internal.logging.Configuration.create;
+import static org.apache.geode.internal.logging.InternalLogWriter.FINE_LEVEL;
+import static org.apache.geode.internal.logging.InternalLogWriter.WARNING_LEVEL;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.URL;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.internal.logging.Configuration;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateOccurs;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link Configuration} and log level changes with
+ * {@link GeodeConsoleAppender}.
+ */
+@Category(LoggingTest.class)
+public class ConfigurationWithLogLevelChangesIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "ConfigurationWithLogLevelChangesIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "STDOUT";
+  private static final String APPLICATION_LOGGER_NAME = "com.company.application";
+
+  private static String configFilePath;
+
+  private LogConfig config;
+  private Configuration configuration;
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+  private String logMessage;
+  private GeodeConsoleAppender geodeConsoleAppender;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    config = mock(LogConfig.class);
+    when(config.getLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+    when(config.getSecurityLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(config);
+
+    configuration = create(LogLevelUpdateOccurs.ALWAYS, LogLevelUpdateScope.GEODE_LOGGERS);
+    configuration.initialize(logConfigSupplier);
+
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogService.getLogger(APPLICATION_LOGGER_NAME);
+
+    logMessage = "Logging in " + testName.getMethodName();
+
+    geodeConsoleAppender =
+        loggerContextRule.getAppender(APPENDER_NAME, GeodeConsoleAppender.class);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    geodeConsoleAppender.clearLogEvents();
+    configuration.shutdown();
+  }
+
+  @Test
+  public void geodeLoggerDebugNotLoggedByDefault() {
+    // act
+    geodeLogger.debug(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void geodeLoggerDebugLoggedAfterLoweringLogLevelToFine() {
+    // arrange
+    when(config.getLogLevel()).thenReturn(FINE_LEVEL);
+    configuration.configChanged();
+
+    // act
+    geodeLogger.debug(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+    LogEvent event = geodeConsoleAppender.getLogEvents().get(0);
+    assertThat(event.getLoggerName()).isEqualTo(getClass().getName());
+    assertThat(event.getLevel()).isEqualTo(Level.DEBUG);
+    assertThat(event.getMessage().getFormattedMessage()).isEqualTo(logMessage);
+  }
+
+  @Test
+  public void geodeLoggerDebugNotLoggedAfterRestoringLogLevelToDefault() {
+    // arrange
+    when(config.getLogLevel()).thenReturn(FINE_LEVEL);
+    configuration.configChanged();
+
+    // re-arrange
+    geodeConsoleAppender.clearLogEvents();
+    when(config.getLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+    configuration.configChanged();
+
+    // act
+    geodeLogger.debug(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void applicationLoggerBelowLevelUnaffectedByLoweringLogLevelChanges() {
+    // arrange
+    when(config.getLogLevel()).thenReturn(FINE_LEVEL);
+    configuration.configChanged();
+
+    // act
+    applicationLogger.debug(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void applicationLoggerInfoLoggedByDefault() {
+    // act
+    applicationLogger.info(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+    LogEvent event = geodeConsoleAppender.getLogEvents().get(0);
+    assertThat(event.getLoggerName()).isEqualTo(APPLICATION_LOGGER_NAME);
+    assertThat(event.getLevel()).isEqualTo(Level.INFO);
+    assertThat(event.getMessage().getFormattedMessage()).isEqualTo(logMessage);
+  }
+
+  @Test
+  public void applicationLoggerAboveLevelUnaffectedByLoweringLogLevelChanges() {
+    // arrange
+    geodeConsoleAppender.clearLogEvents();
+    when(config.getLogLevel()).thenReturn(FINE_LEVEL);
+    configuration.configChanged();
+
+    // act
+    applicationLogger.info(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void applicationLoggerAboveLevelUnaffectedByRaisingLogLevelChanges() {
+    // arrange
+    geodeConsoleAppender.clearLogEvents();
+    when(config.getLogLevel()).thenReturn(WARNING_LEVEL);
+    configuration.configChanged();
+
+    // act
+    applicationLogger.info(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void infoStatementNotLoggedAfterRaisingLogLevelToWarning() {
+    // arrange
+    geodeConsoleAppender.clearLogEvents();
+    when(config.getLogLevel()).thenReturn(WARNING_LEVEL);
+    configuration.configChanged();
+
+    // act
+    geodeLogger.info(logMessage);
+
+    // assert
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest.java
index 2001d44..931cb1c 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest.java
@@ -22,87 +22,80 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.net.URL;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LifeCycle;
-import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.appender.DefaultErrorHandler;
 import org.apache.logging.log4j.core.appender.OutputStreamManager;
 import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.contrib.java.lang.system.SystemErrRule;
 import org.junit.contrib.java.lang.system.SystemOutRule;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.test.junit.categories.LoggingTest;
 
+/**
+ * Verifies behavior of {@code SystemOutRule} with {@code LoggerContextRule} that other Geode
+ * logging tests depends on. If this behavior changes, then those tests may also need to change.
+ */
 @Category(LoggingTest.class)
 public class ConsoleAppenderWithLoggerContextRuleIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "STDOUT";
+
   private static String configFilePath;
 
-  private Logger postConfigLogger;
+  private Logger logger;
   private String logMessage;
+  private ConsoleAppender consoleAppender;
 
   @ClassRule
   public static SystemOutRule systemOutRule = new SystemOutRule().enableLog();
 
   @ClassRule
-  public static SystemErrRule systemErrRule = new SystemErrRule().enableLog();
-
-  @ClassRule
   public static TemporaryFolder temporaryFolder = new TemporaryFolder();
 
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        ConsoleAppenderWithLoggerContextRuleIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    postConfigLogger = LogManager.getLogger();
-    logMessage = "this is a log statement";
+    logger = LogManager.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+    consoleAppender = loggerContextRule.getAppender(APPENDER_NAME, ConsoleAppender.class);
 
     systemOutRule.clearLog();
-    systemErrRule.clearLog();
   }
 
   @Test
-  public void delegateConsoleAppenderIsConfigured() {
-    assertThat(loggerContextRule.getListAppender("LIST")).isNotNull();
-
-    ListAppender listAppender = findAppender(ListAppender.class);
-    assertThat(listAppender).isNotNull();
-
-    ConsoleAppender consoleAppender = findAppender(ConsoleAppender.class);
-    assertThat(consoleAppender).isNotNull();
-
+  public void consoleAppenderIsConfigured() {
     assertThat(consoleAppender.getFilter()).isNull();
     assertThat(consoleAppender.getHandler()).isInstanceOf(DefaultErrorHandler.class);
     assertThat(consoleAppender.getImmediateFlush()).isTrue();
     assertThat(consoleAppender.getLayout()).isNotNull();
     assertThat(consoleAppender.getManager()).isInstanceOf(OutputStreamManager.class);
-    assertThat(consoleAppender.getName()).isEqualTo("STDOUT");
+    assertThat(consoleAppender.getName()).isEqualTo(APPENDER_NAME);
     assertThat(consoleAppender.getState()).isSameAs(LifeCycle.State.STARTED);
     assertThat(consoleAppender.getTarget()).isSameAs(ConsoleAppender.Target.SYSTEM_OUT);
 
@@ -116,27 +109,10 @@ public class ConsoleAppenderWithLoggerContextRuleIntegrationTest {
   }
 
   @Test
-  public void staticSystemOutRuleCapturesConsoleAppenderOutputFromPostConfigLogger() {
-    postConfigLogger.info(logMessage);
+  public void staticSystemOutRuleCapturesConsoleAppenderOutput() {
+    logger.info(logMessage);
 
     assertThat(systemOutRule.getLog()).contains(Level.INFO.name().toLowerCase());
     assertThat(systemOutRule.getLog()).contains(logMessage);
-
-    assertThat(systemErrRule.getLog()).isEmpty();
-  }
-
-  private <T extends Appender> T findAppender(Class<T> appenderClass) {
-    LoggerContext loggerContext =
-        ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).getContext();
-    Map<String, Appender> appenders = loggerContext.getConfiguration().getAppenders();
-    List<Class<? extends Appender>> appenderClasses = new ArrayList<>();
-    for (Appender appender : appenders.values()) {
-      appenderClasses.add(appender.getClass());
-      if (appenderClass.isAssignableFrom(appender.getClass())) {
-        return appenderClass.cast(appender);
-      }
-    }
-    assertThat(appenderClasses).contains(appenderClass);
-    return null;
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest.java
deleted file mode 100644
index 22d48a6..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest.java
+++ /dev/null
@@ -1,182 +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.
- */
-package org.apache.geode.internal.logging.log4j;
-
-import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
-import static org.apache.geode.test.util.ResourceUtils.getResource;
-import static org.apache.logging.log4j.core.config.ConfigurationFactory.CONFIGURATION_FILE_PROPERTY;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.LifeCycle;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.appender.ConsoleAppender;
-import org.apache.logging.log4j.core.appender.DefaultErrorHandler;
-import org.apache.logging.log4j.core.appender.OutputStreamManager;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.contrib.java.lang.system.SystemErrRule;
-import org.junit.contrib.java.lang.system.SystemOutRule;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-
-import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Verifies that we can capture output of {@code ConsoleAppender}. If this behavior changes, then
- * Geode logging tests may also need to change.
- */
-@Category(LoggingTest.class)
-public class ConsoleAppenderWithSystemOutRuleIntegrationTest {
-
-  private static final Logger classLoadedLogger = LogManager.getLogger();
-
-  private String beforeConfigFile;
-  private Level beforeLevel;
-
-  private Logger preConfigLogger;
-  private Logger postConfigLogger;
-  private String logMessage;
-
-  @ClassRule
-  public static SystemOutRule systemOutRule = new SystemOutRule().enableLog();
-
-  @ClassRule
-  public static SystemErrRule systemErrRule = new SystemErrRule().enableLog();
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Before
-  public void setUp() throws Exception {
-    preConfigLogger = LogManager.getLogger();
-
-    Configurator.shutdown();
-
-    beforeConfigFile = System.getProperty(CONFIGURATION_FILE_PROPERTY);
-    beforeLevel = StatusLogger.getLogger().getLevel();
-
-    String configFileName = getClass().getSimpleName() + "_log4j2.xml";
-    File configFile = createFileFromResource(getResource(configFileName),
-        temporaryFolder.getRoot(), configFileName);
-
-    System.setProperty(CONFIGURATION_FILE_PROPERTY, configFile.getAbsolutePath());
-    LogService.reconfigure();
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
-    systemOutRule.clearLog();
-    systemErrRule.clearLog();
-
-    postConfigLogger = LogManager.getLogger();
-    logMessage = "this is a log statement";
-  }
-
-  @After
-  public void tearDown() {
-    Configurator.shutdown();
-
-    System.clearProperty(CONFIGURATION_FILE_PROPERTY);
-    if (beforeConfigFile != null) {
-      System.setProperty(CONFIGURATION_FILE_PROPERTY, beforeConfigFile);
-    }
-    StatusLogger.getLogger().setLevel(beforeLevel);
-
-    LogService.reconfigure();
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isTrue();
-  }
-
-  @Test
-  public void delegateConsoleAppenderIsConfigured() {
-    ConsoleAppender consoleAppender = findAppender(ConsoleAppender.class);
-    assertThat(consoleAppender).isNotNull();
-
-    assertThat(consoleAppender.getFilter()).isNull();
-    assertThat(consoleAppender.getHandler()).isInstanceOf(DefaultErrorHandler.class);
-    assertThat(consoleAppender.getImmediateFlush()).isTrue();
-    assertThat(consoleAppender.getLayout()).isNotNull();
-    assertThat(consoleAppender.getManager()).isInstanceOf(OutputStreamManager.class);
-    assertThat(consoleAppender.getName()).isEqualTo("STDOUT");
-    assertThat(consoleAppender.getState()).isSameAs(LifeCycle.State.STARTED);
-    assertThat(consoleAppender.getTarget()).isSameAs(ConsoleAppender.Target.SYSTEM_OUT);
-
-    OutputStreamManager outputStreamManager = consoleAppender.getManager();
-    assertThat(outputStreamManager.isOpen()).isTrue();
-    assertThat(outputStreamManager.getByteBuffer()).isInstanceOf(ByteBuffer.class);
-    assertThat(outputStreamManager.hasOutputStream()).isTrue();
-    assertThat(outputStreamManager.getContentFormat()).isEmpty();
-    assertThat(outputStreamManager.getLoggerContext()).isNull();
-    assertThat(outputStreamManager.getName()).isEqualTo("SYSTEM_OUT.false.false");
-  }
-
-  @Test
-  public void staticSystemOutRuleCapturesConsoleAppenderOutputFromPostConfigLogger() {
-    postConfigLogger.info(logMessage);
-
-    assertThat(systemOutRule.getLog()).contains(Level.INFO.name().toLowerCase());
-    assertThat(systemOutRule.getLog()).contains(logMessage);
-
-    assertThat(systemErrRule.getLog()).isEmpty();
-  }
-
-  @Test
-  public void staticSystemOutRuleFailsToCaptureConsoleAppenderOutputFromPreConfigLogger() {
-    preConfigLogger.info(logMessage);
-
-    assertThat(systemOutRule.getLog()).isEmpty();
-    assertThat(systemErrRule.getLog()).isEmpty();
-  }
-
-  @Test
-  public void staticSystemOutRuleFailsToCaptureConsoleAppenderOutputFromClassLoadedLogger() {
-    classLoadedLogger.info(logMessage);
-
-    assertThat(systemOutRule.getLog()).isEmpty();
-    assertThat(systemErrRule.getLog()).isEmpty();
-  }
-
-  private <T extends Appender> T findAppender(Class<T> appenderClass) {
-    LoggerContext loggerContext =
-        ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).getContext();
-    Map<String, Appender> appenders = loggerContext.getConfiguration().getAppenders();
-    List<Class<? extends Appender>> appenderClasses = new ArrayList<>();
-    for (Appender appender : appenders.values()) {
-      appenderClasses.add(appender.getClass());
-      if (appenderClass.isAssignableFrom(appender.getClass())) {
-        return appenderClass.cast(appender);
-      }
-    }
-    assertThat(appenderClasses).contains(appenderClass);
-    return null;
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest.java
new file mode 100644
index 0000000..28133f8
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_FILE;
+import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for logging of main and security {@code Logger}s and {@link LogWriter}s to
+ * {@link ConfigurationProperties#LOG_FILE} and {@link ConfigurationProperties#SECURITY_LOG_FILE}
+ * with {@link DistributedSystem}.
+ */
+@Category(LoggingTest.class)
+public class DistributedSystemWithBothLogWriterAppendersIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "DistributedSystemWithBothLogWriterAppendersIntegrationTest_log4j2.xml";
+
+  private static String configFilePath;
+
+  private File mainLogFile;
+  private File securityLogFile;
+  private InternalDistributedSystem system;
+  private Logger mainLogger;
+  private Logger securityLogger;
+  private LogWriter mainLogWriter;
+  private LogWriter securityLogWriter;
+  private String logMessage;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    String name = testName.getMethodName();
+    mainLogFile = new File(temporaryFolder.getRoot(), name + "-main.log");
+    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");
+
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, mainLogFile.getAbsolutePath());
+    config.setProperty(SECURITY_LOG_FILE, securityLogFile.getAbsolutePath());
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    mainLogger = LogService.getLogger();
+    securityLogger = LogService.getLogger(SECURITY_LOGGER_NAME);
+
+    mainLogWriter = system.getLogWriter();
+    securityLogWriter = system.getSecurityLogWriter();
+
+    mainLogger.info("Starting {}", getClass().getName());
+    securityLogger.info("Starting {}", getClass().getName());
+
+    await().until(() -> mainLogFile.exists());
+    await().until(() -> securityLogFile.exists());
+
+    logMessage = "Logging " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    system.disconnect();
+  }
+
+  @Test
+  public void mainLogger_debug_notLoggedByDefault() {
+    mainLogger.debug(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void mainLogger_logsTo_mainLogFile() {
+    mainLogger.info(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).contains(logMessage);
+  }
+
+  @Test
+  public void mainLogger_doesNotLogTo_securityLogFile() {
+    mainLogger.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void securityLogger_debug_notLoggedByDefault() {
+    securityLogger.debug(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void securityLogger_logsTo_securityLogFile() {
+    securityLogger.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).contains(logMessage);
+  }
+
+  @Test
+  public void securityLogger_doesNotLogTo_mainLogFile() {
+    securityLogger.info(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void mainLogWriter_fine_notLoggedByDefault() {
+    mainLogWriter.fine(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void mainLogWriter_logsTo_mainLogFile() {
+    mainLogWriter.info(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).contains(logMessage);
+  }
+
+  @Test
+  public void mainLogWriter_doesNotLogTo_securityLogFile() {
+    mainLogWriter.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void securityLogWriter_fine_notLoggedByDefault() {
+    securityLogWriter.fine(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).doesNotContain(logMessage);
+  }
+
+  @Test
+  public void securityLogWriter_logsTo_securityLogFile() {
+    securityLogWriter.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).contains(logMessage);
+  }
+
+  @Test
+  public void securityLogWriter_doesNotLogTo_mainLogFile() {
+    securityLogWriter.info(logMessage);
+
+    LogFileAssert.assertThat(mainLogFile).doesNotContain(logMessage);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest.java
new file mode 100644
index 0000000..cdd7071
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.internal.logging.Configuration.DEFAULT_LOGWRITER_LEVEL;
+import static org.apache.geode.internal.logging.Configuration.LOG_LEVEL_UPDATE_OCCURS_PROPERTY;
+import static org.apache.geode.internal.logging.InternalLogWriter.FINE_LEVEL;
+import static org.apache.geode.internal.logging.InternalLogWriter.WARNING_LEVEL;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateOccurs;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link DistributedSystem} and log level changes with
+ * {@link GeodeConsoleAppender}.
+ */
+@Category(LoggingTest.class)
+public class DistributedSystemWithLogLevelChangesIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "DistributedSystemWithLogLevelChangesIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "STDOUT";
+  private static final String APPLICATION_LOGGER_NAME = "com.company.application";
+
+  private static String configFilePath;
+
+  private InternalDistributedSystem system;
+  private DistributionConfig distributionConfig;
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+  private String logMessage;
+  private GeodeConsoleAppender geodeConsoleAppender;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    System.setProperty(LOG_LEVEL_UPDATE_OCCURS_PROPERTY, LogLevelUpdateOccurs.ALWAYS.name());
+
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+
+    system = (InternalDistributedSystem) DistributedSystem.connect(config);
+
+    distributionConfig = system.getConfig();
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogService.getLogger(APPLICATION_LOGGER_NAME);
+    logMessage = "Logging in " + testName.getMethodName();
+    geodeConsoleAppender =
+        loggerContextRule.getAppender(APPENDER_NAME, GeodeConsoleAppender.class);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    system.disconnect();
+    geodeConsoleAppender.clearLogEvents();
+  }
+
+  @Test
+  public void debugNotLoggedByDefault() {
+    geodeLogger.debug(logMessage);
+
+    assertThatLogEventsDoesNotContain(logMessage, getClass().getName(), Level.DEBUG);
+  }
+
+  @Test
+  public void debugLoggedAfterLoweringLogLevelToFine() {
+    distributionConfig.setLogLevel(FINE_LEVEL);
+
+    geodeLogger.debug(logMessage);
+
+    assertThatLogEventsContains(logMessage, geodeLogger.getName(), Level.DEBUG);
+  }
+
+  @Test
+  public void debugNotLoggedAfterRestoringLogLevelToDefault() {
+    distributionConfig.setLogLevel(FINE_LEVEL);
+
+    system.getConfig().setLogLevel(DEFAULT_LOGWRITER_LEVEL);
+    geodeLogger.debug(logMessage);
+
+    assertThatLogEventsDoesNotContain(logMessage, geodeLogger.getName(), Level.DEBUG);
+  }
+
+  @Test
+  public void applicationLoggerInfoLoggedByDefault() {
+    applicationLogger.info(logMessage);
+
+    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
+  }
+
+  @Test
+  public void applicationLoggerBelowLevelUnaffectedByLoweringLogLevelChanges() {
+    distributionConfig.setLogLevel(FINE_LEVEL);
+
+    applicationLogger.debug(logMessage);
+
+    assertThatLogEventsDoesNotContain(logMessage, applicationLogger.getName(), Level.DEBUG);
+  }
+
+  @Test
+  public void applicationLoggerAboveLevelUnaffectedByLoweringLogLevelChanges() {
+    distributionConfig.setLogLevel(FINE_LEVEL);
+
+    applicationLogger.info(logMessage);
+
+    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
+  }
+
+  @Test
+  public void applicationLoggerAboveLevelUnaffectedByRaisingLogLevelChanges() {
+    distributionConfig.setLogLevel(WARNING_LEVEL);
+
+    applicationLogger.info(logMessage);
+
+    assertThatLogEventsContains(logMessage, applicationLogger.getName(), Level.INFO);
+  }
+
+  @Test
+  public void infoStatementNotLoggedAfterRaisingLogLevelToWarning() {
+    distributionConfig.setLogLevel(WARNING_LEVEL);
+
+    geodeLogger.info(logMessage);
+
+    assertThatLogEventsDoesNotContain(logMessage, geodeLogger.getName(), Level.INFO);
+  }
+
+  private void assertThatLogEventsContains(String message, String loggerName, Level level) {
+    List<LogEvent> logEvents = geodeConsoleAppender.getLogEvents();
+    for (LogEvent logEvent : logEvents) {
+      if (logEvent.getMessage().getFormattedMessage().contains(message)) {
+        assertThat(logEvent.getMessage().getFormattedMessage()).isEqualTo(message);
+        assertThat(logEvent.getLoggerName()).isEqualTo(loggerName);
+        assertThat(logEvent.getLevel()).isEqualTo(level);
+        return;
+      }
+    }
+    fail("Expected message " + message + " not found in " + logEvents);
+  }
+
+  private void assertThatLogEventsDoesNotContain(String message, String loggerName, Level level) {
+    List<LogEvent> logEvents = geodeConsoleAppender.getLogEvents();
+    for (LogEvent logEvent : logEvents) {
+      if (logEvent.getMessage().getFormattedMessage().contains(message) &&
+          logEvent.getLoggerName().equals(loggerName) && logEvent.getLevel().equals(level)) {
+        fail("Expected message " + message + " should not be contained in " + logEvents);
+      }
+    }
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerIntegrationTest.java
index 1fcd650..dd27c20 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerIntegrationTest.java
@@ -14,9 +14,12 @@
  */
 package org.apache.geode.internal.logging.log4j;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
+import static org.apache.geode.internal.logging.Configuration.DEFAULT_LOGWRITER_LEVEL;
+import static org.apache.geode.internal.logging.Configuration.MAIN_LOGGER_NAME;
+import static org.apache.geode.internal.logging.Configuration.create;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -27,21 +30,26 @@ import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.junit.LoggerContextRule;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.contrib.java.lang.system.RestoreSystemProperties;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
 
+import org.apache.geode.internal.logging.Configuration;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateOccurs;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Tests FastLogger isDebugEnabled and isTraceEnabled with various configurations.
+ * Integration tests for {@link FastLogger} with various configurations.
  *
  * <p>
  * For filters see https://logging.apache.org/log4j/2.0/manual/filters.html
@@ -49,53 +57,63 @@ import org.apache.geode.test.junit.categories.LoggingTest;
 @Category(LoggingTest.class)
 public class FastLoggerIntegrationTest {
 
+  /**
+   * This config file is generated dynamically by the test class.
+   */
+  private static final String CONFIG_FILE_NAME = "FastLoggerIntegrationTest_log4j2.xml";
   private static final String TEST_LOGGER_NAME = FastLogger.class.getPackage().getName();
   private static final String ENABLED_MARKER_NAME = "ENABLED";
   private static final String UNUSED_MARKER_NAME = "UNUSED";
 
-  private File configFile;
-  private String configFileLocation;
+  private static File configFile;
+  private static String configFilePath;
+
+  private Configuration configuration;
   private Logger logger;
-  private LoggerContext appenderContext;
   private Marker enabledMarker;
   private Marker unusedMarker;
 
-  @Rule
-  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
 
   @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    configFile = new File(temporaryFolder.getRoot(), CONFIG_FILE_NAME);
+    configFilePath = configFile.getAbsolutePath();
+    writeSimpleConfigFile(configFile, Level.WARN);
+  }
 
   @Before
   public void setUp() throws Exception {
-    System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-    configFile = new File(temporaryFolder.getRoot(), "log4j2-test.xml");
-    configFileLocation = configFile.toURI().toURL().toString();
     enabledMarker = MarkerManager.getMarker(ENABLED_MARKER_NAME);
     unusedMarker = MarkerManager.getMarker(UNUSED_MARKER_NAME);
-    setUpLogService();
+
+    logger = LogService.getLogger(TEST_LOGGER_NAME);
+
+    assertThat(LogService.getLogger(MAIN_LOGGER_NAME).getLevel()).isEqualTo(Level.FATAL);
+    assertThat(logger).isInstanceOf(FastLogger.class);
+    assertThat(logger.getLevel()).isEqualTo(Level.WARN);
+
+    LogConfig logConfig = mock(LogConfig.class);
+    when(logConfig.getLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+    when(logConfig.getSecurityLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
+
+    configuration = create(LogLevelUpdateOccurs.NEVER, LogLevelUpdateScope.GEODE_LOGGERS);
+    configuration.initialize(logConfigSupplier);
   }
 
   @After
-  public void tearDown() {
-    System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-    LogService.reconfigure();
-  }
+  public void tearDown() throws Exception {
+    configuration.shutdown();
 
-  private void setUpLogService() throws Exception {
-    // Load a base config and do some sanity checks
     writeSimpleConfigFile(configFile, Level.WARN);
-    System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, configFileLocation);
-
-    LogService.reconfigure();
-    LogService.getLogger().getName(); // This causes the config file to be loaded
-    logger = LogService.getLogger(TEST_LOGGER_NAME);
-    appenderContext =
-        ((org.apache.logging.log4j.core.Logger) LogService.getRootLogger()).getContext();
-
-    assertThat(LogService.getLogger(LogService.BASE_LOGGER_NAME).getLevel(), is(Level.FATAL));
-    assertThat(logger, is(instanceOf(FastLogger.class)));
-    assertThat(logger.getLevel(), is(Level.WARN));
+    loggerContextRule.reconfigure();
   }
 
   @Test
@@ -297,34 +315,33 @@ public class FastLoggerIntegrationTest {
   private void verifyIsDelegatingForDebugOrLower(final Level level,
       final boolean expectIsDelegating) throws Exception {
     writeSimpleConfigFile(configFile, level);
-    appenderContext.reconfigure();
-
-    assertThat(logger.getLevel(), is(level));
-
-    assertThat(logger.isTraceEnabled(), is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(), is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(), is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(), is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(), is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(), is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    final boolean delegating = ((FastLogger) logger).isDelegating();
-    assertThat(delegating, is(expectIsDelegating));
-    assertThat(delegating, is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(delegating, is(expectIsDelegating));
+    loggerContextRule.reconfigure();
+    configuration.configChanged();
+
+    assertThat(logger.getLevel()).isEqualTo(level);
+
+    assertThat(logger.isTraceEnabled()).isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled()).isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled()).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled()).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled()).isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled()).isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    boolean delegating = ((FastLogger) logger).isDelegating();
+    assertThat(delegating).isEqualTo(expectIsDelegating);
+    assertThat(delegating).isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(delegating).isEqualTo(expectIsDelegating);
   }
 
   /**
@@ -335,47 +352,44 @@ public class FastLoggerIntegrationTest {
    */
   private void verifyIsDelegatingForLoggerFilter(final Level level,
       final boolean expectIsDelegating) throws Exception {
-    assertThat(expectIsDelegating, is(true)); // always true for Logger Filter
+    assertThat(expectIsDelegating).isEqualTo(true); // always true for Logger Filter
 
     writeLoggerFilterConfigFile(configFile, level);
-    appenderContext.reconfigure();
-
-    assertThat(logger.getLevel(), is(level));
-
-    assertThat(logger.isTraceEnabled(), is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(), is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(), is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(), is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(), is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(), is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(((FastLogger) logger).isDelegating(), is(expectIsDelegating));
+    loggerContextRule.reconfigure();
+    configuration.configChanged();
+
+    assertThat(logger.getLevel()).isEqualTo(level);
+
+    assertThat(logger.isTraceEnabled()).isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled()).isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled()).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled()).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled()).isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled()).isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(((FastLogger) logger).isDelegating()).isEqualTo(expectIsDelegating);
   }
 
   /**
@@ -386,37 +400,38 @@ public class FastLoggerIntegrationTest {
    */
   private void verifyIsDelegatingForContextWideFilter(final Level level,
       final boolean expectIsDelegating) throws Exception {
-    assertThat(expectIsDelegating, is(true)); // always true for Context-wide Filter
+    assertThat(expectIsDelegating).isEqualTo(true); // always true for Context-wide Filter
 
     writeContextWideFilterConfigFile(configFile, level);
-    appenderContext.reconfigure();
+    loggerContextRule.reconfigure();
+    configuration.configChanged();
 
-    assertThat(logger.getLevel(), is(level));
+    assertThat(logger.getLevel()).isEqualTo(level);
 
     // note: unlike other filters, Context-wide filters are processed BEFORE isEnabled checks
 
-    assertThat(logger.isTraceEnabled(), is(false));
-    assertThat(logger.isDebugEnabled(), is(false));
-    assertThat(logger.isInfoEnabled(), is(false));
-    assertThat(logger.isWarnEnabled(), is(false));
-    assertThat(logger.isErrorEnabled(), is(false));
-    assertThat(logger.isFatalEnabled(), is(false));
+    assertThat(logger.isTraceEnabled()).isEqualTo(false);
+    assertThat(logger.isDebugEnabled()).isEqualTo(false);
+    assertThat(logger.isInfoEnabled()).isEqualTo(false);
+    assertThat(logger.isWarnEnabled()).isEqualTo(false);
+    assertThat(logger.isErrorEnabled()).isEqualTo(false);
+    assertThat(logger.isFatalEnabled()).isEqualTo(false);
 
-    assertThat(logger.isTraceEnabled(enabledMarker), is(true));
-    assertThat(logger.isDebugEnabled(enabledMarker), is(true));
-    assertThat(logger.isInfoEnabled(enabledMarker), is(true));
-    assertThat(logger.isWarnEnabled(enabledMarker), is(true));
-    assertThat(logger.isErrorEnabled(enabledMarker), is(true));
-    assertThat(logger.isFatalEnabled(enabledMarker), is(true));
+    assertThat(logger.isTraceEnabled(enabledMarker)).isEqualTo(true);
+    assertThat(logger.isDebugEnabled(enabledMarker)).isEqualTo(true);
+    assertThat(logger.isInfoEnabled(enabledMarker)).isEqualTo(true);
+    assertThat(logger.isWarnEnabled(enabledMarker)).isEqualTo(true);
+    assertThat(logger.isErrorEnabled(enabledMarker)).isEqualTo(true);
+    assertThat(logger.isFatalEnabled(enabledMarker)).isEqualTo(true);
 
-    assertThat(logger.isTraceEnabled(unusedMarker), is(false));
-    assertThat(logger.isDebugEnabled(unusedMarker), is(false));
-    assertThat(logger.isInfoEnabled(unusedMarker), is(false));
-    assertThat(logger.isWarnEnabled(unusedMarker), is(false));
-    assertThat(logger.isErrorEnabled(unusedMarker), is(false));
-    assertThat(logger.isFatalEnabled(unusedMarker), is(false));
+    assertThat(logger.isTraceEnabled(unusedMarker)).isEqualTo(false);
+    assertThat(logger.isDebugEnabled(unusedMarker)).isEqualTo(false);
+    assertThat(logger.isInfoEnabled(unusedMarker)).isEqualTo(false);
+    assertThat(logger.isWarnEnabled(unusedMarker)).isEqualTo(false);
+    assertThat(logger.isErrorEnabled(unusedMarker)).isEqualTo(false);
+    assertThat(logger.isFatalEnabled(unusedMarker)).isEqualTo(false);
 
-    assertThat(((FastLogger) logger).isDelegating(), is(expectIsDelegating));
+    assertThat(((FastLogger) logger).isDelegating()).isEqualTo(expectIsDelegating);
   }
 
   /**
@@ -427,47 +442,44 @@ public class FastLoggerIntegrationTest {
    */
   private void verifyIsDelegatingForAppenderFilter(final Level level,
       final boolean expectIsDelegating) throws Exception {
-    assertThat(expectIsDelegating, is(true)); // always true for Appender Filter
+    assertThat(expectIsDelegating).isEqualTo(true); // always true for Appender Filter
 
     writeAppenderFilterConfigFile(configFile, level);
-    appenderContext.reconfigure();
-
-    assertThat(logger.getLevel(), is(level));
-
-    assertThat(logger.isTraceEnabled(), is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(), is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(), is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(), is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(), is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(), is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(((FastLogger) logger).isDelegating(), is(expectIsDelegating));
+    loggerContextRule.reconfigure();
+    configuration.configChanged();
+
+    assertThat(logger.getLevel()).isEqualTo(level);
+
+    assertThat(logger.isTraceEnabled()).isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled()).isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled()).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled()).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled()).isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled()).isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(((FastLogger) logger).isDelegating()).isEqualTo(expectIsDelegating);
   }
 
   /**
@@ -478,47 +490,44 @@ public class FastLoggerIntegrationTest {
    */
   private void verifyIsDelegatingForAppenderRefFilter(final Level level,
       final boolean expectIsDelegating) throws Exception {
-    assertThat(expectIsDelegating, is(true)); // always true for AppenderRef Filter
+    assertThat(expectIsDelegating).isEqualTo(true); // always true for AppenderRef Filter
 
     writeAppenderRefFilterConfigFile(configFile, level);
-    appenderContext.reconfigure();
-
-    assertThat(logger.getLevel(), is(level));
-
-    assertThat(logger.isTraceEnabled(), is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(), is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(), is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(), is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(), is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(), is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(enabledMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(logger.isTraceEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.TRACE)));
-    assertThat(logger.isDebugEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.DEBUG)));
-    assertThat(logger.isInfoEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.INFO)));
-    assertThat(logger.isWarnEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.WARN)));
-    assertThat(logger.isErrorEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.ERROR)));
-    assertThat(logger.isFatalEnabled(unusedMarker),
-        is(level.isLessSpecificThan(Level.FATAL)));
-
-    assertThat(((FastLogger) logger).isDelegating(), is(expectIsDelegating));
+    loggerContextRule.reconfigure();
+    configuration.configChanged();
+
+    assertThat(logger.getLevel()).isEqualTo(level);
+
+    assertThat(logger.isTraceEnabled()).isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled()).isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled()).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled()).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled()).isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled()).isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(enabledMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(enabledMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(logger.isTraceEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.TRACE));
+    assertThat(logger.isDebugEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.DEBUG));
+    assertThat(logger.isInfoEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.INFO));
+    assertThat(logger.isWarnEnabled(unusedMarker)).isEqualTo(level.isLessSpecificThan(Level.WARN));
+    assertThat(logger.isErrorEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.ERROR));
+    assertThat(logger.isFatalEnabled(unusedMarker))
+        .isEqualTo(level.isLessSpecificThan(Level.FATAL));
+
+    assertThat(((FastLogger) logger).isDelegating()).isEqualTo(expectIsDelegating);
   }
 
   private boolean expectDelegating(final boolean value) {
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerWithDefaultConfigIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerWithDefaultConfigIntegrationTest.java
index 99fdea2..ebab71c 100755
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerWithDefaultConfigIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/FastLoggerWithDefaultConfigIntegrationTest.java
@@ -14,49 +14,44 @@
  */
 package org.apache.geode.internal.logging.log4j;
 
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.isEmptyOrNullString;
-import static org.junit.Assert.assertThat;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.contrib.java.lang.system.RestoreSystemProperties;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.internal.logging.Configuration;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateOccurs;
+import org.apache.geode.internal.logging.Configuration.LogLevelUpdateScope;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Integration tests for FastLogger when using the default log4j2 config for GemFire.
+ * Integration tests for {@link FastLogger} when using the default {@code log4j2.xml} for Geode.
  */
 @Category(LoggingTest.class)
 public class FastLoggerWithDefaultConfigIntegrationTest {
 
-  private static final String TEST_LOGGER_NAME = FastLogger.class.getPackage().getName();
-
   private Logger logger;
 
-  @Rule
-  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
-
   @Before
   public void setUp() throws Exception {
-    System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
-    LogService.reconfigure();
-  }
+    LogConfig logConfig = mock(LogConfig.class);
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
 
-  /**
-   * System property "log4j.configurationFile" should be
-   * "/org/apache/geode/internal/logging/log4j/log4j2-default.xml"
-   */
-  @Test
-  public void configurationFilePropertyIsDefaultConfig() {
-    assertThat(System.getProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY),
-        isEmptyOrNullString());
+    when(logConfig.getLogLevel()).thenReturn(INFO.intLevel());
+    when(logConfig.getSecurityLogLevel()).thenReturn(INFO.intLevel());
+    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
+
+    Configuration configuration =
+        Configuration.create(LogLevelUpdateOccurs.ALWAYS, LogLevelUpdateScope.GEODE_LOGGERS);
+    configuration.initialize(logConfigSupplier);
   }
 
   /**
@@ -64,7 +59,7 @@ public class FastLoggerWithDefaultConfigIntegrationTest {
    */
   @Test
   public void isUsingGemFireDefaultConfig() {
-    assertThat(LogService.isUsingGemFireDefaultConfig(), is(true));
+    assertThat(Log4jAgent.isUsingGemFireDefaultConfig()).isTrue();
   }
 
   /**
@@ -72,9 +67,9 @@ public class FastLoggerWithDefaultConfigIntegrationTest {
    */
   @Test
   public void logServiceReturnsFastLoggers() {
-    logger = LogService.getLogger(TEST_LOGGER_NAME);
+    logger = LogService.getLogger();
 
-    assertThat(logger, is(instanceOf(FastLogger.class)));
+    assertThat(logger).isInstanceOf(FastLogger.class);
   }
 
   /**
@@ -82,8 +77,8 @@ public class FastLoggerWithDefaultConfigIntegrationTest {
    */
   @Test
   public void isDelegatingShouldBeFalse() {
-    logger = LogService.getLogger(TEST_LOGGER_NAME);
+    logger = LogService.getLogger();
 
-    assertThat(((FastLogger) logger).isDelegating(), is(false));
+    assertThat(((FastLogger) logger).isDelegating()).isFalse();
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest.java
index 56f3855..b7daa93 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest.java
@@ -32,20 +32,27 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
+/**
+ * Integration tests for using {@link LogMarker#GEMFIRE_VERBOSE} with {@code MarkerFilter} having
+ * {@code onMatch} of {@code ACCEPT} and {@code onMismatch} of {@code DENY}.
+ */
 @Category(LoggingTest.class)
 public class GemfireVerboseMarkerFilterAcceptIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "GemfireVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml";
   private static final String APPENDER_NAME = "LIST";
 
   private static String configFilePath;
 
+  private ListAppender listAppender;
   private Logger logger;
   private String logMessage;
-  private ListAppender listAppender;
 
   @ClassRule
   public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -53,24 +60,21 @@ public class GemfireVerboseMarkerFilterAcceptIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        GemfireVerboseMarkerFilterAcceptIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    logger = LogService.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
     listAppender = loggerContextRule.getListAppender(APPENDER_NAME);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
   }
 
   @Test
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest.java
index 87cec2f..5bc4e23 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest.java
@@ -30,20 +30,27 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
+/**
+ * Integration tests for using {@link LogMarker#GEMFIRE_VERBOSE} with {@code MarkerFilter} having
+ * {@code onMatch} of {@code DENY} and {@code onMismatch} of {@code ACCEPT}.
+ */
 @Category(LoggingTest.class)
 public class GemfireVerboseMarkerFilterDenyIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "GemfireVerboseMarkerFilterDenyIntegrationTest_log4j2.xml";
   private static final String APPENDER_NAME = "LIST";
 
   private static String configFilePath;
 
+  private ListAppender listAppender;
   private Logger logger;
   private String logMessage;
-  private ListAppender listAppender;
 
   @ClassRule
   public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -51,24 +58,21 @@ public class GemfireVerboseMarkerFilterDenyIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        GemfireVerboseMarkerFilterDenyIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    logger = LogService.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
     listAppender = loggerContextRule.getListAppender(APPENDER_NAME);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
   }
 
   @Test
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest.java
new file mode 100644
index 0000000..bf87b27
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.URL;
+import java.nio.ByteBuffer;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LifeCycle;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.appender.DefaultErrorHandler;
+import org.apache.logging.log4j.core.appender.OutputStreamManager;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link GeodeConsoleAppender}.
+ */
+@Category(LoggingTest.class)
+public class GeodeConsoleAppenderIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME = "GeodeConsoleAppenderIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "STDOUT";
+  private static final String OUTPUT_STREAM_MANAGER_NAME = "null.SYSTEM_OUT.false.false";
+  private static final String DELEGATE_APPENDER_NAME = "STDOUT_DELEGATE";
+  private static final String DELEGATE_OUTPUT_STREAM_MANAGER_NAME = "SYSTEM_OUT.false.false";
+
+  private static String configFilePath;
+
+  private GeodeConsoleAppender geodeConsoleAppender;
+  private Logger logger;
+  private String logMessage;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    geodeConsoleAppender =
+        loggerContextRule.getAppender("STDOUT", GeodeConsoleAppender.class);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    geodeConsoleAppender.clearLogEvents();
+  }
+
+  @Test
+  public void getLogEventsIsEmptyByDefault() {
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void getLogEventsReturnsLoggedEvents() {
+    logger.info(logMessage);
+
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+
+    LogEvent event = geodeConsoleAppender.getLogEvents().get(0);
+    assertThat(event.getLoggerName()).isEqualTo(getClass().getName());
+    assertThat(event.getLevel()).isEqualTo(Level.INFO);
+    assertThat(event.getMessage().getFormattedMessage()).isEqualTo(logMessage);
+  }
+
+  @Test
+  public void pausedDoesNotLog() {
+    geodeConsoleAppender.pause();
+
+    logger.info(logMessage);
+
+    assertThat(geodeConsoleAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void resumeAfterPausedLogs() {
+    geodeConsoleAppender.pause();
+    geodeConsoleAppender.resume();
+
+    logger.info(logMessage);
+
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void resumeWithoutPauseStillLogs() {
+    geodeConsoleAppender.resume();
+
+    logger.info(logMessage);
+
+    assertThat(geodeConsoleAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void isPausedReturnsTrueAfterPause() {
+    geodeConsoleAppender.pause();
+
+    assertThat(geodeConsoleAppender.isPaused()).isTrue();
+  }
+
+  @Test
+  public void isPausedReturnsFalseAfterResume() {
+    geodeConsoleAppender.pause();
+    geodeConsoleAppender.resume();
+
+    assertThat(geodeConsoleAppender.isPaused()).isFalse();
+  }
+
+  @Test
+  public void resumeWithoutPauseDoesNothing() {
+    geodeConsoleAppender.resume();
+
+    assertThat(geodeConsoleAppender.isPaused()).isFalse();
+  }
+
+  @Test
+  public void isPausedReturnsFalseByDefault() {
+    assertThat(geodeConsoleAppender.isPaused()).isFalse();
+  }
+
+  @Test
+  public void geodeConsoleAppenderIsConfigured() {
+    assertThat(geodeConsoleAppender).isNotNull();
+
+    assertThat(geodeConsoleAppender.getFilter()).isNull();
+    assertThat(geodeConsoleAppender.getHandler()).isInstanceOf(DefaultErrorHandler.class);
+    assertThat(geodeConsoleAppender.getImmediateFlush()).isTrue();
+    assertThat(geodeConsoleAppender.getLayout()).isNotNull();
+    assertThat(geodeConsoleAppender.getManager()).isInstanceOf(OutputStreamManager.class);
+    assertThat(geodeConsoleAppender.getName()).isEqualTo(APPENDER_NAME);
+    assertThat(geodeConsoleAppender.getState()).isSameAs(LifeCycle.State.STARTED);
+    // assertThat(geodeConsoleAppender.getTarget()).isSameAs(ConsoleAppender.Target.SYSTEM_OUT);
+
+    OutputStreamManager outputStreamManager = geodeConsoleAppender.getManager();
+    assertThat(outputStreamManager.isOpen()).isTrue();
+    assertThat(outputStreamManager.getByteBuffer()).isInstanceOf(ByteBuffer.class);
+    assertThat(outputStreamManager.hasOutputStream()).isTrue();
+    assertThat(outputStreamManager.getContentFormat()).isEmpty();
+    assertThat(outputStreamManager.getLoggerContext()).isNull();
+    assertThat(outputStreamManager.getName()).isEqualTo(OUTPUT_STREAM_MANAGER_NAME);
+  }
+
+  @Test
+  public void delegateConsoleAppenderIsConfigured() {
+    ConsoleAppender consoleAppender = geodeConsoleAppender.getDelegate();
+    assertThat(consoleAppender).isNotNull();
+
+    assertThat(consoleAppender.getFilter()).isNull();
+    assertThat(consoleAppender.getHandler()).isInstanceOf(DefaultErrorHandler.class);
+    assertThat(consoleAppender.getImmediateFlush()).isTrue();
+    assertThat(consoleAppender.getLayout()).isNotNull();
+    assertThat(consoleAppender.getManager()).isInstanceOf(OutputStreamManager.class);
+    assertThat(consoleAppender.getName()).isEqualTo(DELEGATE_APPENDER_NAME);
+    assertThat(consoleAppender.getState()).isSameAs(LifeCycle.State.STARTED);
+    assertThat(consoleAppender.getTarget()).isSameAs(ConsoleAppender.Target.SYSTEM_OUT);
+
+    OutputStreamManager outputStreamManager = consoleAppender.getManager();
+    assertThat(outputStreamManager.isOpen()).isTrue();
+    assertThat(outputStreamManager.getByteBuffer()).isInstanceOf(ByteBuffer.class);
+    assertThat(outputStreamManager.hasOutputStream()).isTrue();
+    assertThat(outputStreamManager.getContentFormat()).isEmpty();
+    assertThat(outputStreamManager.getLoggerContext()).isNull();
+    assertThat(outputStreamManager.getName()).isEqualTo(DELEGATE_OUTPUT_STREAM_MANAGER_NAME);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest.java
new file mode 100644
index 0000000..d1d3568
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static java.lang.System.lineSeparator;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+@Category(LoggingTest.class)
+public class GeodeConsoleAppenderWithCacheIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml";
+
+  private static String configFilePath;
+
+  private InternalCache cache;
+  private GeodeConsoleAppender geodeConsoleAppender;
+  private File logFile;
+  private Logger logger;
+  private String logMessage;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    String name = testName.getMethodName();
+    logFile = new File(temporaryFolder.getRoot(), name + ".log");
+
+    geodeConsoleAppender =
+        loggerContextRule.getAppender("STDOUT", GeodeConsoleAppender.class);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() {
+    if (cache != null) {
+      cache.close();
+    }
+  }
+
+  @Test
+  public void logsToStdoutIfLogFileNotSpecified() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    logger.info(logMessage);
+
+    LogEvent foundLogEvent = null;
+    for (LogEvent logEvent : geodeConsoleAppender.getLogEvents()) {
+      if (logEvent.getMessage().getFormattedMessage().contains(logMessage)) {
+        foundLogEvent = logEvent;
+        break;
+      }
+    }
+    assertThat(foundLogEvent).as(logEventsShouldContain(logMessage, foundLogEvent)).isNotNull();
+  }
+
+  @Test
+  public void stopsLoggingToStdoutWhenLoggingToLogFileStarts() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    logger.info(logMessage);
+
+    LogEvent foundLogEvent = null;
+    for (LogEvent logEvent : geodeConsoleAppender.getLogEvents()) {
+      if (logEvent.getMessage().getFormattedMessage().contains(logMessage)) {
+        foundLogEvent = logEvent;
+        break;
+      }
+    }
+    assertThat(foundLogEvent).as(logEventsShouldNotContain(logMessage, foundLogEvent)).isNull();
+  }
+
+  @Test
+  public void resumesLoggingToStdoutWhenLoggingToLogFileStops() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    cache.close();
+
+    logger.info(logMessage);
+
+    LogEvent foundLogEvent = null;
+    for (LogEvent logEvent : geodeConsoleAppender.getLogEvents()) {
+      if (logEvent.getMessage().getFormattedMessage().contains(logMessage)) {
+        foundLogEvent = logEvent;
+        break;
+      }
+    }
+    assertThat(foundLogEvent).as(logEventsShouldContain(logMessage, foundLogEvent)).isNotNull();
+  }
+
+  private String logEventsShouldContain(String logMessage, LogEvent logEvent) {
+    return "Expecting:" + lineSeparator() + " " + geodeConsoleAppender.getLogEvents() +
+        lineSeparator() + "to contain:" + lineSeparator() + " " + logMessage +
+        lineSeparator() + "but could not find:" + lineSeparator() + " " + logEvent;
+  }
+
+  private String logEventsShouldNotContain(String logMessage, LogEvent logEvent) {
+    return "Expecting:" + lineSeparator() + " " + geodeConsoleAppender.getLogEvents() +
+        lineSeparator() + "to not contain:" + lineSeparator() + " " + logMessage +
+        lineSeparator() + "but found:" + lineSeparator() + " " + logEvent;
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest.java
new file mode 100644
index 0000000..ed24408
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.URL;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.SystemErrRule;
+import org.junit.contrib.java.lang.system.SystemOutRule;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link GeodeConsoleAppender} with {@code SystemOutRule} and
+ * {@code SystemErrRule}.
+ *
+ * <p>
+ * Verifies that {@code SystemOutRule} can capture the output of {@link GeodeConsoleAppender}.
+ * If this behavior changes, then Geode logging tests may also need to change.
+ */
+@Category(LoggingTest.class)
+public class GeodeConsoleAppenderWithSystemOutRuleIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "GeodeConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml";
+
+  private static String configFilePath;
+
+  private Logger logger;
+  private String logMessage;
+
+  @ClassRule
+  public static SystemOutRule systemOutRule = new SystemOutRule().enableLog();
+
+  @ClassRule
+  public static SystemErrRule systemErrRule = new SystemErrRule().enableLog();
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    systemOutRule.clearLog();
+    systemErrRule.clearLog();
+
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @Test
+  public void staticSystemOutRuleCapturesConsoleAppenderOutput() {
+    logger.info(logMessage);
+
+    assertThat(systemOutRule.getLog()).contains(logMessage);
+    assertThat(systemErrRule.getLog()).isEmpty();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest.java
index 00c8da1..a0c9603 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest.java
@@ -32,20 +32,27 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
+/**
+ * Integration tests for using {@link LogMarker#GEODE_VERBOSE} with {@code MarkerFilter} having
+ * {@code onMatch} of {@code ACCEPT} and {@code onMismatch} of {@code DENY}.
+ */
 @Category(LoggingTest.class)
 public class GeodeVerboseMarkerFilterAcceptIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "GeodeVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml";
   private static final String APPENDER_NAME = "LIST";
 
   private static String configFilePath;
 
+  private ListAppender listAppender;
   private Logger logger;
   private String logMessage;
-  private ListAppender listAppender;
 
   @ClassRule
   public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -53,24 +60,21 @@ public class GeodeVerboseMarkerFilterAcceptIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        GeodeVerboseMarkerFilterAcceptIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    logger = LogService.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
     listAppender = loggerContextRule.getListAppender(APPENDER_NAME);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
   }
 
   @Test
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest.java
index 99a00ae..a2015a7 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest.java
@@ -32,20 +32,27 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
+/**
+ * Integration tests for using {@link LogMarker#GEMFIRE_VERBOSE} with {@code MarkerFilter} having
+ * {@code onMatch} of {@code DENY} and {@code onMismatch} of {@code ACCEPT}.
+ */
 @Category(LoggingTest.class)
 public class GeodeVerboseMarkerFilterDenyIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml";
   private static final String APPENDER_NAME = "LIST";
 
   private static String configFilePath;
 
+  private ListAppender listAppender;
   private Logger logger;
   private String logMessage;
-  private ListAppender listAppender;
 
   @ClassRule
   public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -53,24 +60,21 @@ public class GeodeVerboseMarkerFilterDenyIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        GeodeVerboseMarkerFilterDenyIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    logger = LogService.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
-
     listAppender = loggerContextRule.getListAppender(APPENDER_NAME);
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
   }
 
   @Test
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest.java
similarity index 83%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest.java
index 23c6f79..4d04fc0 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.internal.logging.log4j;
 
+import static org.apache.geode.internal.logging.log4j.Log4jAgent.getConfigurationInfo;
 import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
 import static org.apache.geode.test.util.ResourceUtils.getResource;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -35,16 +36,19 @@ import org.junit.contrib.java.lang.system.SystemErrRule;
 import org.junit.contrib.java.lang.system.SystemOutRule;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Integration tests with custom log4j2 configuration.
+ * Integration tests for {@link LogService} with custom logging configuration.
  */
 @Category(LoggingTest.class)
-public class CustomConfigWithLogServiceIntegrationTest {
+public class LogServiceWithCustomLogConfigIntegrationTest {
 
+  private static final String CONFIG_FILE_NAME =
+      "LogServiceWithCustomLogConfigIntegrationTest_log4j2.xml";
   private static final String CONFIG_LAYOUT_PREFIX = "CUSTOM";
   private static final String CUSTOM_REGEX_STRING =
       "CUSTOM: level=[A-Z]+ time=\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3} [^ ]{3} message=.*[\\n]+throwable=.*$";
@@ -68,27 +72,29 @@ public class CustomConfigWithLogServiceIntegrationTest {
   @Rule
   public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
 
+  @Rule
+  public TestName testName = new TestName();
+
   @BeforeClass
   public static void setUpLogConfigFile() throws Exception {
-    String configFileName =
-        CustomConfigWithCacheIntegrationTest.class.getSimpleName() + "_log4j2.xml";
-    URL resource = getResource(configFileName);
-    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), configFileName)
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
         .getAbsolutePath();
   }
 
   @Before
   public void setUp() throws Exception {
-    logger = LogService.getLogger();
-    logMessage = "this is a log statement";
-
-    assertThat(LogService.isUsingGemFireDefaultConfig()).as(LogService.getConfigurationInfo())
-        .isFalse();
+    systemOutRule.clearLog();
+    systemErrRule.clearLog();
 
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
     listAppender = loggerContextRule.getListAppender("CUSTOM");
+  }
 
-    systemOutRule.clearLog();
-    systemErrRule.clearLog();
+  @Test
+  public void isUsingGemFireDefaultConfigIsFalse() {
+    assertThat(Log4jAgent.isUsingGemFireDefaultConfig()).as(getConfigurationInfo()).isFalse();
   }
 
   @Test
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest.java
index 3106d80..0344e35 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest.java
@@ -14,238 +14,193 @@
  */
 package org.apache.geode.internal.logging.log4j;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.regex.Pattern;
-
+import static java.nio.charset.Charset.defaultCharset;
+import static org.apache.commons.io.FileUtils.readLines;
+import static org.apache.geode.internal.logging.NonBlankStrings.nonBlankStrings;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.junit.LoggerContextRule;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
 
-import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.LogMessageRegex;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.PureLogWriter;
+import org.apache.geode.internal.logging.SessionContext;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Tests the LogWriterAppender.
+ * Integration tests for {@link LogWriterAppender}.
  */
 @Category(LoggingTest.class)
 public class LogWriterAppenderIntegrationTest {
 
-  private Level previousLogLevel;
-  private LogWriterAppender appender;
+  private static final String CONFIG_FILE_NAME = "LogWriterAppenderIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "LOGWRITER";
+
+  private static String configFilePath;
+
+  private File logFile;
+  private Logger logger;
+  private String logMessage;
+  private LogWriterAppender logWriterAppender;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
 
   @Before
-  public void setUp() {
-    previousLogLevel = LogService.getBaseLogLevel();
+  public void setUp() throws Exception {
+    String name = testName.getMethodName();
+    logFile = new File(temporaryFolder.getRoot(), name + ".log");
+
+    LogConfig config = mock(LogConfig.class);
+    when(config.getName()).thenReturn(name);
+    when(config.getLogFile()).thenReturn(logFile);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(config);
+
+    SessionContext sessionContext = mock(SessionContext.class);
+    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);
+
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+
+    logWriterAppender =
+        loggerContextRule.getAppender(APPENDER_NAME, LogWriterAppender.class);
+    logWriterAppender.createSession(sessionContext);
+    logWriterAppender.startSession();
   }
 
   @After
   public void tearDown() {
-    LogService.setBaseLogLevel(previousLogLevel);
-    if (appender != null) {
-      appender.stop();
-      Configurator.getLoggerConfig(LogService.BASE_LOGGER_NAME).getAppenders()
-          .remove(appender.getName());
-    }
+    logWriterAppender.stopSession();
+    logWriterAppender.clearLogEvents();
+  }
+
+  @Test
+  public void getLogEventsReturnsLoggedEvents() {
+    logWriterAppender.clearLogEvents();
+
+    logger.info(logMessage);
+
+    assertThat(logWriterAppender.getLogEvents()).hasSize(1);
+    LogEvent event = logWriterAppender.getLogEvents().get(0);
+    assertThat(event.getLoggerName()).isEqualTo(getClass().getName());
+    assertThat(event.getLevel()).isEqualTo(Level.INFO);
+    assertThat(event.getMessage().getFormattedMessage()).isEqualTo(logMessage);
+  }
+
+  @Test
+  public void pausedDoesNotLog() {
+    logWriterAppender.pause();
+    logWriterAppender.clearLogEvents();
+
+    logger.info(logMessage);
+
+    assertThat(logWriterAppender.getLogEvents()).isEmpty();
   }
 
-  /**
-   * Verifies that the appender is correctly added and removed from the Log4j configuration and that
-   * when the configuration is changed the appender is still there.
-   */
   @Test
-  public void testAppenderToConfigHandling() {
-    LogService.setBaseLogLevel(Level.TRACE);
+  public void resumeAfterPausedLogs() {
+    logWriterAppender.pause();
+    logWriterAppender.clearLogEvents();
+    logWriterAppender.resume();
 
-    final AppenderContext rootContext = LogService.getAppenderContext();
+    logger.info(logMessage);
 
-    // Find out home many appenders exist before we get started
-    final int startingSize = rootContext.getLoggerConfig().getAppenders().size();
+    assertThat(logWriterAppender.getLogEvents()).hasSize(1);
+  }
 
-    // System.out.println("Appenders " +
-    // context.getLoggerConfig().getAppenders().values().toString());
+  @Test
+  public void resumeWithoutPauseStillLogs() {
+    logWriterAppender.clearLogEvents();
+    logWriterAppender.resume();
 
-    // Create the appender and verify it's part of the configuration
-    final StringWriter stringWriter = new StringWriter();
-    final PureLogWriter logWriter =
-        new PureLogWriter(InternalLogWriter.FINE_LEVEL, new PrintWriter(stringWriter), "");
+    logger.info(logMessage);
 
-    final AppenderContext[] contexts = new AppenderContext[2];
-    contexts[0] = rootContext; // root context
-    contexts[1] = LogService.getAppenderContext(LogService.BASE_LOGGER_NAME); // "org.apache"
-                                                                              // context
+    assertThat(logWriterAppender.getLogEvents()).hasSize(1);
+  }
 
-    appender =
-        LogWriterAppender.create(contexts, LogService.MAIN_LOGGER_NAME, logWriter, null);
+  @Test
+  public void isPausedReturnsTrueAfterPause() {
+    logWriterAppender.pause();
+    assertThat(logWriterAppender.isPaused()).isTrue();
+  }
 
-    assertEquals(rootContext.getLoggerConfig().getAppenders().values().toString(), startingSize + 1,
-        rootContext.getLoggerConfig().getAppenders().size());
-    assertTrue(rootContext.getLoggerConfig().getAppenders().containsKey(appender.getName()));
+  @Test
+  public void isPausedReturnsFalseAfterResume() {
+    logWriterAppender.pause();
+    logWriterAppender.resume();
 
-    // Modify the config and verify that the appender still exists
-    assertEquals(Level.TRACE, LogService.getLogger(LogService.BASE_LOGGER_NAME).getLevel());
-    LogService.setBaseLogLevel(Level.DEBUG);
-    assertEquals(Level.DEBUG, LogService.getLogger(LogService.BASE_LOGGER_NAME).getLevel());
-    assertTrue(rootContext.getLoggerConfig().getAppenders().containsKey(appender.getName()));
+    assertThat(logWriterAppender.isPaused()).isFalse();
+  }
 
-    // Destroy the appender and verify that it was removed from log4j
-    appender.destroy();
-    assertEquals(rootContext.getLoggerConfig().getAppenders().values().toString(), startingSize,
-        rootContext.getLoggerConfig().getAppenders().size());
-    assertFalse(rootContext.getLoggerConfig().getAppenders().containsKey(appender.getName()));
+  @Test
+  public void resumeWithoutPauseDoesNothing() {
+    logWriterAppender.resume();
+
+    assertThat(logWriterAppender.isPaused()).isFalse();
+  }
+
+  @Test
+  public void isPausedReturnsFalseByDefault() {
+    assertThat(logWriterAppender.isPaused()).isFalse();
   }
 
-  /**
-   * Verifies that writing to a Log4j logger will end up in the LogWriter's output.
-   */
   @Test
-  public void testLogOutput() {
-    // Create the appender
-    final StringWriter stringWriter = new StringWriter();
-    final PureLogWriter logWriter =
-        new PureLogWriter(InternalLogWriter.FINEST_LEVEL, new PrintWriter(stringWriter), "");
-
-    final AppenderContext[] contexts = new AppenderContext[2];
-    contexts[0] = LogService.getAppenderContext(); // root context
-    contexts[1] = LogService.getAppenderContext(LogService.BASE_LOGGER_NAME); // "org.apache"
-                                                                              // context
-
-    appender =
-        LogWriterAppender.create(contexts, LogService.MAIN_LOGGER_NAME, logWriter, null);
-
-    final Logger logger = LogService.getLogger();
-
-    // set the level to TRACE
-    Configurator.setLevel(LogService.BASE_LOGGER_NAME, Level.TRACE);
-    Configurator.setLevel(LogService.MAIN_LOGGER_NAME, Level.TRACE);
-
-    assertEquals(Level.TRACE, logger.getLevel());
-
-    logger.trace("TRACE MESSAGE");
-    assertTrue(Pattern.compile(".*\\[finest .*TRACE MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logger.debug("DEBUG MESSAGE");
-    assertTrue(Pattern.compile(".*\\[fine .*DEBUG MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logger.info("INFO MESSAGE");
-    assertTrue(Pattern.compile(".*\\[info .*INFO MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logger.warn("ExpectedStrings: WARNING MESSAGE");
-    assertTrue(Pattern.compile(".*\\[warning .*WARNING MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logger.error("ExpectedStrings: ERROR MESSAGE");
-    assertTrue(Pattern.compile(".*\\[error .*ERROR MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logger.fatal("ExpectedStrings: FATAL MESSAGE");
-    assertTrue(Pattern.compile(".*\\[severe .*FATAL MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    final Logger lowerLevelLogger =
-        LogService.getLogger(LogService.BASE_LOGGER_NAME + ".subpackage");
-    lowerLevelLogger.fatal("ExpectedStrings: FATAL MESSAGE");
-    assertTrue(Pattern.compile(".*\\[severe .*FATAL MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    appender.destroy();
-    assertFalse(Configurator.getLoggerConfig(LogService.BASE_LOGGER_NAME).getAppenders()
-        .containsKey(appender.getName()));
+  public void logsToFile() throws Exception {
+    logger.info(logMessage);
+
+    assertThat(logFile).exists();
+    String content = FileUtils.readFileToString(logFile, defaultCharset()).trim();
+    assertThat(content).contains(logMessage);
   }
 
-  /**
-   * Verifies that logging occurs at the levels set in the LogWriter
-   */
   @Test
-  public void testLogWriterLevels() {
-    final String loggerName = LogService.MAIN_LOGGER_NAME; // this.getClass().getName();
-    LogService.getLogger(); // Force logging to be initialized
-
-    // Create the LogWriterLogger that will be attached to the appender
-    final LogWriterLogger logWriterLogger = LogWriterLogger.create(loggerName, false);
-    logWriterLogger.setLevel(Level.INFO);
-
-    // Create the appender
-    final StringWriter stringWriter = new StringWriter();
-    final PureLogWriter logWriter =
-        new PureLogWriter(InternalLogWriter.FINEST_LEVEL, new PrintWriter(stringWriter), "");
-
-    final AppenderContext[] contexts = new AppenderContext[2];
-    // root context
-    contexts[0] = LogService.getAppenderContext();
-    // "org.apache" context
-    contexts[1] = LogService.getAppenderContext(LogService.BASE_LOGGER_NAME);
-
-    appender = LogWriterAppender.create(contexts, loggerName, logWriter, null);
-
-    logWriter.finest("DIRECT MESSAGE");
-    assertTrue(Pattern.compile(".*\\[finest .*DIRECT MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerFqcn("NAME")
-        .setLoggerName("NAME").setMessage(new ParameterizedMessage("LOGEVENT MESSAGE")).build();
-    appender.append(event);
-    assertTrue(Pattern.compile(".*\\[info .*LOGEVENT MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logWriterLogger.finest("FINEST MESSAGE");
-    assertFalse(Pattern.compile(".*\\[finest .*FINEST MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logWriterLogger.fine("FINE MESSAGE");
-    assertFalse(Pattern.compile(".*\\[fine .*FINE MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logWriterLogger.info("INFO MESSAGE");
-    assertTrue(stringWriter.toString(),
-        Pattern.compile(".*\\[info .*INFO MESSAGE.*", Pattern.DOTALL)
-            .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    // Change the level
-    logWriterLogger.setLevel(Level.DEBUG);
-
-    logWriterLogger.finest("FINEST MESSAGE");
-    assertFalse(Pattern.compile(".*\\[finest .*FINEST MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logWriterLogger.fine("FINE MESSAGE");
-    assertTrue(Pattern.compile(".*\\[fine .*FINE MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    logWriterLogger.info("INFO MESSAGE");
-    assertTrue(Pattern.compile(".*\\[info .*INFO MESSAGE.*", Pattern.DOTALL)
-        .matcher(stringWriter.toString()).matches());
-    stringWriter.getBuffer().setLength(0);
-
-    appender.destroy();
+  public void linesInFileShouldMatchPatternLayout() throws Exception {
+    logger.info(logMessage);
+
+    assertThat(logFile).exists();
+
+    List<String> lines = nonBlankStrings(readLines(logFile, defaultCharset()));
+    assertThat(lines).hasSize(1);
+
+    for (String line : lines) {
+      assertThat(line).matches(LogMessageRegex.getRegex());
+    }
   }
 }
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest.java
new file mode 100644
index 0000000..06f9af3
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.internal.logging.Configuration.DEFAULT_LOGWRITER_LEVEL;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.SessionContext;
+import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link LogWriterAppender} with
+ * {@link ConfigurationProperties#LOG_FILE_SIZE_LIMIT} and
+ * {@link ConfigurationProperties#LOG_DISK_SPACE_LIMIT}.
+ */
+@Category(LoggingTest.class)
+public class LogWriterAppenderWithLimitsIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "LogWriterAppenderWithLimitsIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "LOGWRITER";
+  private static final int MAX_LOG_DISK_SPACE_LIMIT = 1_000_000;
+  private static final int MAX_LOG_FILE_SIZE_LIMIT = 1_000_000;
+
+  private static String configFilePath;
+
+  private LogWriterAppender logWriterAppender;
+  private LogConfig config;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    logWriterAppender = loggerContextRule.getAppender(APPENDER_NAME,
+        LogWriterAppender.class);
+
+    String name = testName.getMethodName();
+    File logFile = temporaryFolder.newFile(name + ".log");
+
+    config = mock(LogConfig.class);
+    when(config.getName()).thenReturn(name);
+    when(config.getLogFile()).thenReturn(logFile);
+    when(config.getLogLevel()).thenReturn(DEFAULT_LOGWRITER_LEVEL);
+    when(config.getLogDiskSpaceLimit()).thenReturn(MAX_LOG_DISK_SPACE_LIMIT);
+    when(config.getLogFileSizeLimit()).thenReturn(MAX_LOG_FILE_SIZE_LIMIT);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(config);
+    when(logConfigSupplier.getStatisticsConfig()).thenReturn(mock(StatisticsConfig.class));
+
+    SessionContext sessionContext = mock(SessionContext.class);
+    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);
+
+    logWriterAppender.createSession(sessionContext);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    logWriterAppender.clearLogEvents();
+  }
+
+  @Test
+  public void logDiskSpaceLimit() {
+    // log-disk-space-limit starts out as MAX_LOG_DISK_SPACE_LIMIT
+    LogConfig logConfig = logWriterAppender.getLogWriter().getConfig();
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(MAX_LOG_DISK_SPACE_LIMIT);
+
+    // log-disk-space-limit changes to 1_000
+    when(config.getLogDiskSpaceLimit()).thenReturn(1_000);
+    logWriterAppender.configChanged();
+
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(1_000);
+
+    // log-disk-space-limit changes back to MAX_LOG_DISK_SPACE_LIMIT
+    when(config.getLogDiskSpaceLimit()).thenReturn(MAX_LOG_DISK_SPACE_LIMIT);
+    logWriterAppender.configChanged();
+
+    assertThat(logConfig.getLogDiskSpaceLimit()).isEqualTo(MAX_LOG_DISK_SPACE_LIMIT);
+  }
+
+  @Test
+  public void logFileSizeLimit() {
+    // log-file-size-limit starts out as MAX_LOG_FILE_SIZE_LIMIT
+    LogConfig logConfig = logWriterAppender.getLogWriter().getConfig();
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(MAX_LOG_FILE_SIZE_LIMIT);
+
+    // log-file-size-limit changes to 1_000
+    when(config.getLogFileSizeLimit()).thenReturn(1_000);
+    logWriterAppender.configChanged();
+
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(1_000);
+
+    // log-disk-space-limit changes back to MAX_LOG_FILE_SIZE_LIMIT
+    when(config.getLogFileSizeLimit()).thenReturn(MAX_LOG_FILE_SIZE_LIMIT);
+    logWriterAppender.configChanged();
+
+    assertThat(logConfig.getLogFileSizeLimit()).isEqualTo(MAX_LOG_FILE_SIZE_LIMIT);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest.java
new file mode 100644
index 0000000..ee38fec
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static java.lang.System.lineSeparator;
+import static java.nio.charset.Charset.defaultCharset;
+import static org.apache.commons.io.FileUtils.readFileToString;
+import static org.apache.commons.io.FileUtils.readLines;
+import static org.apache.geode.internal.logging.LogMessageRegex.Group;
+import static org.apache.geode.internal.logging.LogMessageRegex.getPattern;
+import static org.apache.geode.internal.logging.NonBlankStrings.nonBlankStrings;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.SessionContext;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link LogWriterAppender} with {@code memberName} in
+ * {@code log4j2.xml}.
+ */
+@Category(LoggingTest.class)
+public class LogWriterAppenderWithMemberNameInXmlIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "LogWriterAppenderWithMemberNameInXmlIntegrationTest_log4j2.xml";
+  private static final String APPENDER_NAME = "LOGWRITERWITHMEMBERNAME";
+  private static final String MEMBER_NAME = "MEMBERNAME";
+
+  private static String configFilePath;
+
+  private LogWriterAppender logWriterAppender;
+  private File logFile;
+  private Logger logger;
+  private String logMessage;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    String logFileName = MEMBER_NAME + ".log";
+    logFile = new File(temporaryFolder.newFolder(testName.getMethodName()), logFileName);
+
+    LogConfig config = mock(LogConfig.class);
+    when(config.getName()).thenReturn("");
+    when(config.getLogFile()).thenReturn(logFile);
+
+    LogConfigSupplier logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(config);
+
+    SessionContext sessionContext = mock(SessionContext.class);
+    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);
+
+    logWriterAppender =
+        loggerContextRule.getAppender(APPENDER_NAME, LogWriterAppender.class);
+    logWriterAppender.createSession(sessionContext);
+    logWriterAppender.startSession();
+
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() {
+    logWriterAppender.stopSession();
+  }
+
+  @Test
+  public void logsToSpecifiedFile() throws Exception {
+    logger.info(logMessage);
+
+    assertThat(logFile).exists();
+    String content = readFileToString(logFile, defaultCharset()).trim();
+    assertThat(content).contains(logMessage);
+  }
+
+  @Test
+  public void logLinesInFileShouldContainMemberName() throws Exception {
+    logger.info(logMessage);
+
+    assertThat(logFile).exists();
+
+    List<String> lines = nonBlankStrings(readLines(logFile, defaultCharset()));
+    assertThat(lines).hasSize(1);
+
+    for (String line : lines) {
+      Matcher matcher = getPattern().matcher(line);
+      assertThat(matcher.matches()).as(failedToMatchRegex(line, getPattern())).isTrue();
+      assertThat(matcher.group(Group.MEMBER_NAME.getName())).isEqualTo(MEMBER_NAME);
+    }
+
+  }
+
+  private String failedToMatchRegex(String line, Pattern pattern) {
+    String $ = lineSeparator();
+    return $ + "Line:" + $ + " " + line + $ + "failed to match regex:" + $ + " " + pattern + $;
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest.java
new file mode 100644
index 0000000..9e3f939
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.test.util.ResourceUtils.createFileFromResource;
+import static org.apache.geode.test.util.ResourceUtils.getResource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogConfigSupplier;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.SessionContext;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.LoggingTest;
+import org.apache.geode.test.junit.categories.SecurityTest;
+
+/**
+ * Integration tests for {@link LogWriterAppender} with security logger and
+ * {@link ConfigurationProperties#SECURITY_LOG_FILE}.
+ */
+@Category({LoggingTest.class, SecurityTest.class})
+public class SecurityLogWriterAppenderIntegrationTest {
+
+  private static final String CONFIG_FILE_NAME =
+      "SecurityLogWriterAppenderIntegrationTest_log4j2.xml";
+  private static final String SECURITY_APPENDER_NAME = "SECURITYLOGWRITER";
+
+  private static String configFilePath;
+
+  private LogWriterAppender securityLogWriterAppender;
+  private File securityLogFile;
+  private SessionContext sessionContext;
+  private LogConfigSupplier logConfigSupplier;
+  private Logger securityGeodeLogger;
+  private String logMessage;
+
+  @ClassRule
+  public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public LoggerContextRule loggerContextRule = new LoggerContextRule(configFilePath);
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @BeforeClass
+  public static void setUpLogConfigFile() throws Exception {
+    URL resource = getResource(CONFIG_FILE_NAME);
+    configFilePath = createFileFromResource(resource, temporaryFolder.getRoot(), CONFIG_FILE_NAME)
+        .getAbsolutePath();
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    securityLogWriterAppender = loggerContextRule.getAppender(SECURITY_APPENDER_NAME,
+        LogWriterAppender.class);
+
+    String name = testName.getMethodName();
+    securityLogFile = new File(temporaryFolder.getRoot(), name + "-security.log");
+
+    LogConfig logConfig = mock(LogConfig.class);
+    when(logConfig.getName()).thenReturn(name);
+    when(logConfig.getSecurityLogFile()).thenReturn(securityLogFile);
+
+    logConfigSupplier = mock(LogConfigSupplier.class);
+    when(logConfigSupplier.getLogConfig()).thenReturn(logConfig);
+
+    sessionContext = mock(SessionContext.class);
+    when(sessionContext.getLogConfigSupplier()).thenReturn(logConfigSupplier);
+
+    securityGeodeLogger = LogService.getLogger(SECURITY_LOGGER_NAME);
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @Test
+  public void securityLogWriterAppenderLogEventsIsEmptyByDefault() {
+    assertThat(securityLogWriterAppender.getLogEvents()).isEmpty();
+  }
+
+  @Test
+  public void geodeSecurityLoggerAppendsToSecurityLogWriterAppender() {
+    securityLogWriterAppender.createSession(sessionContext);
+    securityLogWriterAppender.startSession();
+
+    securityGeodeLogger.info(logMessage);
+
+    assertThat(securityLogWriterAppender.getLogEvents()).hasSize(1);
+  }
+
+  @Test
+  public void securityLogFileIsEmptyByDefault() {
+    securityGeodeLogger.info(logMessage);
+
+    assertThat(securityLogFile).doesNotExist();
+  }
+
+  @Test
+  public void securityGeodeLoggerLogsToSecurityLogFile() {
+    securityLogWriterAppender.createSession(sessionContext);
+    securityLogWriterAppender.startSession();
+
+    securityGeodeLogger.info(logMessage);
+
+    LogFileAssert.assertThat(securityLogFile).exists().contains(logMessage);
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/MemberMXBeanShowLogIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/MemberMXBeanShowLogIntegrationTest.java
new file mode 100644
index 0000000..5c252c0
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/MemberMXBeanShowLogIntegrationTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.geode.management;
+
+import static java.lang.System.lineSeparator;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.management.internal.ManagementConstants.DEFAULT_SHOW_LOG_LINES;
+import static org.apache.geode.management.internal.ManagementConstants.MAX_SHOW_LOG_LINES;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.management.internal.SystemManagementService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+import org.apache.geode.test.junit.categories.ManagementTest;
+
+/**
+ * Integration tests for {@link MemberMXBean} with just a {@link Cache}.
+ */
+@Category({ManagementTest.class, LoggingTest.class})
+public class MemberMXBeanShowLogIntegrationTest {
+
+  private File logFile;
+  private InternalCache cache;
+  private SystemManagementService managementService;
+  private Logger logger;
+  private String logMessage;
+
+  private MemberMXBean memberMXBean;
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Before
+  public void setUp() throws Exception {
+    logFile = new File(temporaryFolder.getRoot(), testName.getMethodName() + ".log");
+    logger = LogService.getLogger();
+    logMessage = "Logging in " + testName.getMethodName();
+  }
+
+  @After
+  public void tearDown() {
+    cache.close();
+  }
+
+  @Test
+  public void showLogWithoutLogFile() {
+    createCacheWithoutLogFile();
+
+    assertThat(memberMXBean.showLog(0)).isEqualTo(
+        "No log file was specified in the configuration, messages will be directed to stdout.");
+  }
+
+  @Test
+  public void showLogIsNeverEmpty() {
+    createCacheWithLogFile();
+
+    assertThat(memberMXBean.showLog(-20)).isNotEmpty();
+    assertThat(memberMXBean.showLog(0)).isNotEmpty();
+    assertThat(memberMXBean.showLog(DEFAULT_SHOW_LOG_LINES)).isNotEmpty();
+    assertThat(memberMXBean.showLog(MAX_SHOW_LOG_LINES)).isNotEmpty();
+  }
+
+  @Test
+  public void showLogZeroUsesDefault() {
+    createCacheWithLogFile();
+
+    String log = memberMXBean.showLog(0);
+
+    // splitting on lineSeparator() results in a length near 30
+    assertThat(log.split(lineSeparator()).length).as("Log: " + log).isGreaterThan(25)
+        .isLessThan(35);
+  }
+
+  @Test
+  public void showLogNegativeUsesDefault() {
+    createCacheWithLogFile();
+
+    String log = memberMXBean.showLog(-20);
+
+    // splitting on lineSeparator() results in a length near 30
+    assertThat(log.split(lineSeparator()).length).as("Log: " + log).isGreaterThan(25)
+        .isLessThan(35);
+  }
+
+  @Test
+  public void showLogDefault() {
+    createCacheWithLogFile();
+
+    String log = memberMXBean.showLog(DEFAULT_SHOW_LOG_LINES);
+
+    // splitting on lineSeparator() results in a length near 30
+    assertThat(log.split(lineSeparator()).length).as("Log: " + log).isGreaterThan(25)
+        .isLessThan(35);
+  }
+
+  @Test
+  public void showLogMaxLinesCount() {
+    createCacheWithLogFile();
+
+    String log = memberMXBean.showLog(MAX_SHOW_LOG_LINES);
+
+    // splitting on lineSeparator() results in a length near 100
+    assertThat(log.split(lineSeparator()).length).as("Log: " + log).isGreaterThan(90)
+        .isLessThan(110);
+  }
+
+  @Test
+  public void showLogGreaterThanMaxUsesMax() {
+    createCacheWithLogFile();
+
+    String log = memberMXBean.showLog(MAX_SHOW_LOG_LINES * 10);
+
+    // splitting on lineSeparator() results in a length near 100
+    assertThat(log.split(lineSeparator()).length).as("Log: " + log).isGreaterThan(90)
+        .isLessThan(110);
+  }
+
+  @Test
+  public void showLogContainsMostRecentlyLoggedMessage() {
+    createCacheWithLogFile();
+    logger.info(logMessage);
+
+    String log = memberMXBean.showLog(0);
+
+    assertThat(log).contains(logMessage);
+  }
+
+  private void createCacheWithLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    managementService =
+        (SystemManagementService) ManagementService.getExistingManagementService(cache);
+    await().until(() -> managementService.getMemberMXBean() != null);
+    memberMXBean = managementService.getMemberMXBean();
+    assertThat(memberMXBean).isNotNull();
+  }
+
+  private void createCacheWithoutLogFile() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+
+    cache = (InternalCache) new CacheFactory(config).create();
+
+    managementService =
+        (SystemManagementService) ManagementService.getExistingManagementService(cache);
+    await().until(() -> managementService.getMemberMXBean() != null);
+    memberMXBean = managementService.getMemberMXBean();
+    assertThat(memberMXBean).isNotNull();
+  }
+}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunctionIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunctionIntegrationTest.java
new file mode 100644
index 0000000..29276db
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunctionIntegrationTest.java
@@ -0,0 +1,164 @@
+/*
+ * 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.geode.management.internal.cli.functions;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_LOG_LEVEL;
+import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogConfig;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Integration tests for {@link ChangeLogLevelFunction}.
+ */
+@Category(LoggingTest.class)
+public class ChangeLogLevelFunctionIntegrationTest {
+
+  private static final String APPLICATION_LOGGER_NAME = "com.application";
+
+  private InternalCache cache;
+  private Logger geodeLogger;
+  private Logger applicationLogger;
+  private InternalLogWriter mainLogWriter;
+  private InternalLogWriter securityLogWriter;
+  private LogConfig logConfig;
+  private FunctionContext functionContext;
+
+  private ChangeLogLevelFunction changeLogLevelFunction;
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+  @Before
+  public void setUp() {
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_LEVEL, Level.INFO.name());
+    config.setProperty(SECURITY_LOG_LEVEL, Level.INFO.name());
+
+    cache = (InternalCache) new CacheFactory(config).create();
+    InternalDistributedSystem system = cache.getInternalDistributedSystem();
+
+    mainLogWriter = (InternalLogWriter) cache.getLogger();
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    securityLogWriter = (InternalLogWriter) cache.getSecurityLogger();
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+
+    geodeLogger = LogService.getLogger();
+    applicationLogger = LogManager.getLogger(APPLICATION_LOGGER_NAME);
+
+    logConfig = system.getLogConfig();
+    assertThat(logConfig.getLogLevel()).isEqualTo(INFO.intLevel());
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+
+    functionContext = mock(FunctionContext.class);
+    when(functionContext.getCache()).thenReturn(cache);
+    when(functionContext.getArguments()).thenReturn(new Object[] {Level.WARN.name()});
+    when(functionContext.getResultSender()).thenReturn(mock(ResultSender.class));
+
+    changeLogLevelFunction = new ChangeLogLevelFunction();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (cache != null) {
+      cache.close();
+    }
+  }
+
+  @Test
+  public void changesMainLogWriterLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(mainLogWriter.getLogWriterLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void changesLogConfigLogLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(logConfig.getLogLevel()).isEqualTo(WARNING.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeSecurityLogWriterLogLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(securityLogWriter.getLogWriterLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void doesNotChangeLogConfigSecurityLogLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(logConfig.getSecurityLogLevel()).isEqualTo(INFO.intLevel());
+  }
+
+  @Test
+  public void changesGeodeLoggerLogLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(geodeLogger.getLevel()).isEqualTo(Level.WARN);
+  }
+
+  @Test
+  public void doesNotChangeApplicationLoggerLogLevel() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(applicationLogger.getLevel()).isEqualTo(Level.INFO);
+  }
+
+  @Test
+  public void changesGemFireLogLevelSystemProperty() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(System.getProperty(DistributionConfig.GEMFIRE_PREFIX + LOG_LEVEL))
+        .isEqualTo(Level.WARN.name());
+  }
+
+  @Test
+  public void doesNotChangeGemFireSecurityLogLevelSystemProperty() {
+    changeLogLevelFunction.execute(functionContext);
+
+    assertThat(System.getProperty(DistributionConfig.GEMFIRE_PREFIX + SECURITY_LOG_LEVEL)).isNull();
+  }
+}
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
index f67da94..96d78f6 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/codeAnalysis/excludedClasses.txt
@@ -14,11 +14,14 @@ org/apache/geode/distributed/internal/membership/gms/mgr/GMSMembershipManager$Bo
 org/apache/geode/distributed/internal/tcpserver/LocatorCancelException
 org/apache/geode/internal/AbstractConfig$SortedProperties
 org/apache/geode/internal/AvailablePort$Keeper
+org/apache/geode/internal/Banner$BannerHeader
 org/apache/geode/internal/DSCODE
 org/apache/geode/internal/ExitCode
 org/apache/geode/internal/JarDeployer
 org/apache/geode/internal/ObjIdConcurrentMap
 org/apache/geode/internal/ObjIdConcurrentMap$Segment
+org/apache/geode/internal/alerting/AlertLevel
+org/apache/geode/internal/alerting/AlertingSession$State
 org/apache/geode/internal/cache/DiskStoreMonitor$DiskState
 org/apache/geode/internal/cache/InitialImageOperation$GIITestHook
 org/apache/geode/internal/cache/Oplog$OPLOG_TYPE
@@ -47,8 +50,12 @@ org/apache/geode/internal/hll/HyperLogLogPlus$Builder
 org/apache/geode/internal/hll/HyperLogLogPlus$Format
 org/apache/geode/internal/hll/HyperLogLogPlus$HyperLogLogPlusMergeException
 org/apache/geode/internal/hll/HyperLogLogPlus$SerializationHolder
+org/apache/geode/internal/logging/Configuration$LogLevelUpdateOccurs
+org/apache/geode/internal/logging/Configuration$LogLevelUpdateScope
+org/apache/geode/internal/logging/LogMessageRegex$Group
+org/apache/geode/internal/logging/LogWriterLevel
+org/apache/geode/internal/logging/SessionContext$State
 org/apache/geode/internal/logging/log4j/FastLogger
-org/apache/geode/internal/logging/log4j/LogWriterAppenders$Identifier
 org/apache/geode/internal/logging/log4j/LogWriterLogger
 org/apache/geode/internal/logging/log4j/message/GemFireParameterizedMessage
 org/apache/geode/internal/logging/log4j/message/GemFireParameterizedMessageFactory
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest_log4j2.xml
similarity index 65%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest_log4j2.xml
index 5a32d9c..06baee9 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/BothLogWriterAppendersIntegrationTest_log4j2.xml
@@ -13,23 +13,32 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="LOGWRITER" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
+        <GeodeLogWriter name="SECURITYLOGWRITER" security="true" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
+        <Logger name="org.apache.geode.security" level="INFO" additivity="false">
+            <AppenderRef ref="SECURITYLOGWRITER"/>
+        </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="LOGWRITER"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest_log4j2.xml
similarity index 86%
rename from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest_log4j2.xml
rename to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest_log4j2.xml
index e57f9d4..6994f40 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithLogServiceIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CacheWithCustomLogConfigIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j.custom">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j.custom">
     <Properties>
         <Property name="custom-pattern">CUSTOM: level=%level time=%date{yyyy/MM/dd HH:mm:ss.SSS z} message=%message%nthrowable=%throwable%n
         </Property>
@@ -25,15 +25,15 @@
         <List name="CUSTOM"/>
     </Appenders>
     <Loggers>
-        <Logger name="com.gemstone" level="INFO" additivity="true"/>
-        <Logger name="org.apache.geode" level="INFO" additivity="true">
+        <Logger name="com.gemstone" level="WARN" additivity="true"/>
+        <Logger name="org.apache.geode" level="WARN" additivity="true">
             <filters>
                 <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
-        <Logger name="org.apache.geode.internal.logging.log4j.custom" level="DEBUG" additivity="true"/>
+        <Logger name="org.apache.geode.internal.logging.log4j.custom" level="WARN" additivity="true"/>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
-        <Root level="INFO">
+        <Root level="WARN">
             <AppenderRef ref="CUSTOM"/>
             <AppenderRef ref="STDOUT"/>
         </Root>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest_log4j2.xml
similarity index 75%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest_log4j2.xml
index 5a32d9c..c77540b 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConfigurationWithLogLevelChangesIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeConsole name="STDOUT" target="SYSTEM_OUT" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeConsole>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="STDOUT"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml
index 87196fe..58aaa1c 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml
@@ -1,21 +1,19 @@
 <?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
+  ~ 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
+  ~ 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.
+  ~ 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 status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j,org.apache.logging.log4j.test.appender">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j,org.apache.logging.log4j.test.appender">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
@@ -23,7 +21,6 @@
         <Console name="STDOUT" target="SYSTEM_OUT">
             <PatternLayout pattern="${geode-pattern}"/>
         </Console>
-        <List name="LIST"/>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
@@ -36,7 +33,6 @@
         <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
             <AppenderRef ref="STDOUT"/>
-            <AppenderRef ref="LIST"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest_log4j2.xml
similarity index 66%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest_log4j2.xml
index 5a32d9c..8eab155 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithBothLogWriterAppendersIntegrationTest_log4j2.xml
@@ -13,23 +13,32 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="LOGWRITER">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
+        <GeodeLogWriter name="SECURITYLOGWRITER" security="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
+        <Logger name="org.apache.geode.security" level="INFO" additivity="false">
+            <AppenderRef ref="SECURITYLOGWRITER"/>
+        </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="LOGWRITER"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest_log4j2.xml
similarity index 75%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest_log4j2.xml
index 5a32d9c..c77540b 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/DistributedSystemWithLogLevelChangesIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeConsole name="STDOUT" target="SYSTEM_OUT" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeConsole>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="STDOUT"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
index 2d6534a..6757bf7 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
index 8509b41..a741d10 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GemfireVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest_log4j2.xml
similarity index 81%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest_log4j2.xml
index 5a32d9c..edfa2d8 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeConsole name="STDOUT" target="SYSTEM_OUT" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeConsole>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="STDOUT"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml
similarity index 69%
rename from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml
rename to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml
index 7f38e14..76940ec 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml
@@ -15,14 +15,22 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-default">true</Property>
     </Properties>
     <Appenders>
-        <Console name="STDOUT" target="SYSTEM_OUT">
+        <GeodeConsole name="STDOUT" target="SYSTEM_OUT" debug="true">
             <PatternLayout pattern="${geode-pattern}"/>
-        </Console>
+        </GeodeConsole>
+        <GeodeLogWriter name="LOGWRITER">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
+        <GeodeLogWriter name="SECURITYLOGWRITER" security="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
+        <GeodeAlert name="ALERT"/>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
@@ -31,10 +39,15 @@
                 <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
+        <Logger name="org.apache.geode.security" level="INFO" additivity="false">
+            <AppenderRef ref="SECURITYLOGWRITER"/>
+        </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
         <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
             <AppenderRef ref="STDOUT"/>
+            <AppenderRef ref="LOGWRITER"/>
+            <AppenderRef ref="ALERT"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml
similarity index 81%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml
index 5a32d9c..fca1e70 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithSystemOutRuleIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeConsole name="STDOUT" target="SYSTEM_OUT">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeConsole>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="STDOUT"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
index f73ea4b..cfeba88 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterAcceptIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
index 5a32d9c..08cee94 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
         <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest_log4j2.xml
similarity index 96%
rename from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest_log4j2.xml
rename to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest_log4j2.xml
index e57f9d4..a6d2d12 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/CustomConfigWithCacheIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogServiceWithCustomLogConfigIntegrationTest_log4j2.xml
@@ -13,7 +13,7 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j.custom">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j.custom">
     <Properties>
         <Property name="custom-pattern">CUSTOM: level=%level time=%date{yyyy/MM/dd HH:mm:ss.SSS z} message=%message%nthrowable=%throwable%n
         </Property>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest_log4j2.xml
similarity index 79%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest_log4j2.xml
index 5a32d9c..2b06d9f 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderIntegrationTest_log4j2.xml
@@ -15,21 +15,24 @@
   -->
 <Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="LOGWRITER" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="LOGWRITER"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest_log4j2.xml
similarity index 76%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest_log4j2.xml
index 5a32d9c..6aee268 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithLimitsIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="LOGWRITER" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="LOGWRITER"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest_log4j2.xml
similarity index 74%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest_log4j2.xml
index 5a32d9c..a734805 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/LogWriterAppenderWithMemberNameInXmlIntegrationTest_log4j2.xml
@@ -13,23 +13,26 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="LOGWRITERWITHMEMBERNAME" memberName="MEMBERNAME">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
         <Root level="INFO">
-            <AppenderRef ref="LIST"/>
+            <AppenderRef ref="LOGWRITERWITHMEMBERNAME"/>
         </Root>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest_log4j2.xml
similarity index 69%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
copy to geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest_log4j2.xml
index 5a32d9c..c0dac6a 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeVerboseMarkerFilterDenyIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/SecurityLogWriterAppenderIntegrationTest_log4j2.xml
@@ -13,23 +13,27 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
+<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
     <Properties>
-        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
+        <Property name="geode-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} %memberName &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
     </Properties>
     <Appenders>
-        <List name="LIST"/>
+        <GeodeLogWriter name="SECURITYLOGWRITER" security="true" debug="true">
+            <PatternLayout pattern="${geode-pattern}"/>
+        </GeodeLogWriter>
     </Appenders>
     <Loggers>
         <Logger name="com.gemstone" level="INFO" additivity="true"/>
         <Logger name="org.apache.geode" level="INFO" additivity="true">
             <filters>
-                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="ACCEPT"/>
+                <MarkerFilter marker="GEODE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
             </filters>
         </Logger>
+        <Logger name="org.apache.geode.security" level="INFO" additivity="false">
+            <AppenderRef ref="SECURITYLOGWRITER"/>
+        </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
-        <Root level="INFO">
-            <AppenderRef ref="LIST"/>
-        </Root>
+        <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
+        <Root level="INFO"/>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/jmh/java/org/apache/geode/internal/logging/log4j/CacheLoggingBenchmark.java b/geode-core/src/jmh/java/org/apache/geode/internal/logging/log4j/CacheLoggingBenchmark.java
new file mode 100644
index 0000000..e9684aa
--- /dev/null
+++ b/geode-core/src/jmh/java/org/apache/geode/internal/logging/log4j/CacheLoggingBenchmark.java
@@ -0,0 +1,116 @@
+/*
+ * 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.geode.internal.logging.log4j;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.geode.cache.RegionShortcut.LOCAL;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
+import static org.apache.logging.log4j.Level.INFO;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.logging.log4j.LogManager;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.cache.Region;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.rules.accessible.AccessibleTemporaryFolder;
+
+@Measurement(iterations = 1, time = 1, timeUnit = MINUTES)
+@Warmup(iterations = 1, time = 1, timeUnit = MINUTES)
+@Fork(1)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(SECONDS)
+@State(Scope.Benchmark)
+@SuppressWarnings("unused")
+public class CacheLoggingBenchmark {
+
+  private FastLogger fastLogger;
+  private String message;
+
+  private AccessibleTemporaryFolder temporaryFolder;
+  private InternalCache cache;
+  private Region<String, String> region;
+  private String key;
+  private String value;
+
+  @Setup(Level.Trial)
+  public void setUp() throws Throwable {
+    temporaryFolder = new AccessibleTemporaryFolder();
+    temporaryFolder.before();
+
+    String name = getClass().getSimpleName();
+    File logFile = new File(temporaryFolder.getRoot(), name + ".log");
+
+    Properties config = new Properties();
+    config.setProperty(LOCATORS, "");
+    config.setProperty(LOG_LEVEL, "INFO");
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
+
+    assertThat(logFile).doesNotExist();
+    cache = (InternalCache) new CacheFactory(config).create();
+    assertThat(logFile).exists();
+
+    region = cache.<String, String>createRegionFactory(LOCAL).create(name + "-region");
+
+    fastLogger = new FastLogger(LogManager.getLogger());
... 8361 lines suppressed ...