geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [geode] 01/02: GEODE-6964: Move geode log4j core classes to geode-log4j
Date Tue, 24 Sep 2019 16:18:13 GMT
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 efc2362d2bae0877a427ce2c29beae94118d6567
Author: Kirk Lund <klund@apache.org>
AuthorDate: Thu Aug 8 15:17:54 2019 -0700

    GEODE-6964: Move geode log4j core classes to geode-log4j
    
    Introduce new Logging and Alerting SPIs. Extract all log4j-core code to
    geode-log4j module.
    
    The geode-core module no longer contains log4j2.xml and no longer has a
    dependency on log4j-core.
    
    All code that uses log4j-core has moved to the new module geode-log4j.
    The log4j2.xml for Geode now lives in geode-log4j as well. These
    changes ensure that users have better control over logging including
    which backend to use. This should improve user experience when using
    Spring Boot.
    
    Co-authored-by: Mark Hanson <mhanson@pivotal.io>
---
 .../src/test/resources/expected-pom.xml            |   6 +
 .../release/session/bin/modify_war                 |   1 +
 geode-assembly/build.gradle                        |  15 +-
 .../apache/geode/session/tests/TomcatInstall.java  |   7 +-
 .../GfshCommandRedactionAcceptanceTest.java        | 118 +++++++++++
 .../GfshStartLocatorLogAcceptanceTest.java         |   2 +-
 .../session/tests/GenericAppServerContainer.java   |  14 +-
 .../integrationTest/resources/assembly_content.txt |   1 +
 .../resources/dependency_classpath.txt             |   1 +
 geode-core/build.gradle                            |  27 +--
 .../api}/AlertingServiceDistributedTest.java       |  31 ++-
 ...rtingServiceWithoutListenerDistributedTest.java |  11 +-
 .../geode/cache/ConnectionPoolDUnitTest.java       |   2 +-
 .../geode/cache30/PartitionedRegionDUnitTest.java  |   2 +-
 ...overWithMixedVersionServersDistributedTest.java |  33 ++-
 .../LoggingWithReconnectDistributedTest.java       |   4 +-
 ...butedSystemMXBeanWithAlertsDistributedTest.java |  12 +-
 .../cli/util/MergeLogsDistributedTest.java         |   1 -
 .../security/ClientAuthenticationDUnitTest.java    |  13 +-
 .../AlertingServiceWithClusterIntegrationTest.java |  10 +-
 .../AlertingServiceWithLonerIntegrationTest.java   |   4 +-
 .../client/internal/QueueManagerJUnitTest.java     |   2 +-
 .../pooling/ConnectionManagerJUnitTest.java        |   2 +-
 .../internal/InternalLocatorIntegrationTest.java   |   2 +-
 .../adapter/GMSMembershipManagerJUnitTest.java     |   4 +-
 .../cache/PartitionedRegionIntegrationTest.java    |  57 +-----
 .../ManagerLogWriterFactoryIntegrationTest.java    |   5 +-
 .../logging/MergeLogFilesIntegrationTest.java      |   2 +-
 .../internal}/BannerLoggingIntegrationTest.java    |   4 +-
 .../ConfigurationInfoIntegrationTest.java          |   4 +-
 .../internal}/FileSystemCanaryIntegrationTest.java |  22 +-
 ...StartupConfigurationLoggingIntegrationTest.java |   6 +-
 ...stemOutRuleAndSystemErrRuleIntegrationTest.java |   2 +-
 .../LogLevelChangesWithCacheIntegrationTest.java   |   9 +-
 ...hangesWithDistributedSystemIntegrationTest.java |   9 +-
 ...ollingWithDistributedSystemIntegrationTest.java |   2 +-
 .../api}/LoggingWithLocatorIntegrationTest.java    |  10 +-
 .../LoggingWithLocatorLauncherIntegrationTest.java |   2 +-
 .../LoggingWithServerLauncherIntegrationTest.java  |   2 +-
 .../DistributedSystemMXBeanIntegrationTest.java    |  28 ++-
 .../cli/commands/GfshCommandIntegrationTest.java   |  82 ++++----
 .../ChangeLogLevelFunctionIntegrationTest.java     |   6 +-
 .../apache/geode/codeAnalysis/excludedClasses.txt  |  18 +-
 ...moteWithCustomLoggingIntegrationTest_log4j2.xml |  22 +-
 ...soleAppenderWithCacheIntegrationTest_log4j2.xml |  53 -----
 .../admin/internal/AdminDistributedSystemImpl.java |   4 +-
 .../internal/DistributedSystemConfigImpl.java      |   4 +-
 .../apache/geode/admin/jmx/internal/AgentImpl.java |   8 +-
 .../log4j => alerting/internal}/AlertListener.java |  13 +-
 .../internal}/AlertListenerMessageFactory.java     |  12 +-
 .../internal/AlertMessaging.java}                  |  19 +-
 .../internal}/AlertingSession.java                 |  32 +--
 .../internal/AlertingSessionNotifier.java}         |  16 +-
 .../internal/AlertingSessionRegistryProvider.java} |  52 ++---
 .../internal/ClusterAlertMessaging.java}           |  50 +++--
 .../alerting/internal/ClusterAlertingService.java  | 128 ++++++++++++
 .../internal/InternalAlertingService.java}         |  11 +-
 .../internal/InternalAlertingServiceFactory.java}  |  11 +-
 .../internal/NullAlertMessaging.java}              |  19 +-
 .../internal/NullAlertingService.java}             |  47 ++++-
 .../internal/api/AlertingService.java}             |  17 +-
 .../internal}/log4j/AlertLevelConverter.java       |  20 +-
 .../internal/spi}/AlertLevel.java                  |   8 +-
 .../internal/spi}/AlertingAction.java              |  17 +-
 .../internal/spi}/AlertingSessionListener.java     |  17 +-
 .../internal/spi/AlertingSessionRegistry.java}     |  29 ++-
 .../internal/AbstractDistributionConfig.java       |   2 +-
 .../internal/ClusterDistributionManager.java       |   2 +-
 .../distributed/internal/DistributionConfig.java   |   4 +-
 .../distributed/internal/DistributionManager.java  |   2 +-
 .../internal/InternalDistributedSystem.java        |  37 ++--
 .../distributed/internal/InternalLocator.java      |  10 +-
 .../internal/LonerDistributionManager.java         |   4 +-
 .../geode/distributed/internal/ProductUseLog.java  |   2 +-
 .../distributed/internal/direct/DirectChannel.java |   2 +-
 .../membership/adapter/GMSMembershipManager.java   |   3 -
 .../membership/gms/messenger/JGroupsMessenger.java |   2 +-
 .../main/java/org/apache/geode/i18n/StringId.java  |   3 +-
 .../org/apache/geode/internal/ClassPathLoader.java |  88 ++++----
 .../internal/admin/remote/AdminConsoleMessage.java |   2 +-
 .../admin/remote/AlertLevelChangeMessage.java      |   2 +-
 .../admin/remote/AlertListenerMessage.java         |   6 +-
 .../geode/internal/admin/remote/RemoteAlert.java   |   2 +-
 .../internal/admin/remote/TailLogResponse.java     |   2 +-
 .../alerting/AlertingProviderRegistry.java         |  84 --------
 .../geode/internal/alerting/AlertingService.java   |  57 ------
 .../internal/alerting/NullAlertingService.java     |  50 -----
 .../EntriesCollection.java}                        |  14 +-
 .../apache/geode/internal/cache/EntriesSet.java    |   2 +-
 .../internal/cache/xmlcache/CacheCreation.java     |   2 +-
 .../geode/internal/jta/TransactionUtils.java       |   2 +-
 .../org/apache/geode/internal/logging/Banner.java  |   1 +
 .../geode/internal/logging/DateFormatter.java      |  20 +-
 .../internal/logging/DefaultProviderChecker.java   |  82 --------
 .../geode/internal/logging/GemFireFormatter.java   |   1 +
 .../geode/internal/logging/GemFireHandler.java     |   2 +-
 .../geode/internal/logging/LogFileParser.java      |   2 +-
 .../apache/geode/internal/logging/LogService.java  |  55 ++---
 .../geode/internal/logging/LogWriterFactory.java   |  24 ++-
 .../geode/internal/logging/LoggingExecutors.java   |  20 +-
 .../geode/internal/logging/LoggingThread.java      |  20 +-
 .../internal/logging/LoggingThreadFactory.java     |  20 +-
 .../geode/internal/logging/LoggingThreadGroup.java |   2 +-
 .../logging/LoggingUncaughtExceptionHandler.java   |  20 +-
 .../geode/internal/logging/ManagerLogWriter.java   |   6 +-
 .../internal/logging/ManagerLogWriterFactory.java  |   1 +
 .../internal/logging/ProviderAgentLoader.java      | 135 -------------
 .../geode/internal/logging/SecurityLogConfig.java  |   2 +
 .../internal/logging/SecurityManagerLogWriter.java |   2 +
 .../apache/geode/internal/logging/SortLogFile.java |   1 -
 .../internal/logging/log4j/PausableAppender.java   |  26 ---
 .../security/IntegratedSecurityService.java        |   2 +-
 .../security/shiro/SecurityManagerProvider.java    |   2 +-
 .../internal/statistics/GemFireStatSampler.java    |   2 +-
 .../geode/internal/statistics/HostStatSampler.java |   2 +-
 .../internal/statistics/StatArchiveHandler.java    |   4 +-
 .../statistics/StatArchiveHandlerConfig.java       |   2 +-
 .../internal/statistics/StatisticsConfig.java      |   2 +-
 .../org/apache/geode/internal/tcp/Connection.java  |   2 +-
 .../apache/geode/internal/tcp/ConnectionTable.java |   2 +-
 .../org/apache/geode/internal/tcp/TCPConduit.java  |   2 +-
 .../internal/util/CollectingServiceLoader.java     |  20 +-
 .../internal/util/ListCollectingServiceLoader.java |  25 ++-
 .../concurrent/CustomEntryConcurrentHashMap.java   |   1 -
 .../internal}/Configuration.java                   |  65 +++---
 .../internal}/ConfigurationInfo.java               |  10 +-
 .../internal/InternalSessionContext.java}          |   9 +-
 .../internal}/LogMessageRegex.java                 |  18 +-
 .../logging/internal/LoggingProviderLoader.java    | 104 ++++++++++
 .../internal}/LoggingSession.java                  |  40 ++--
 .../logging/internal/LoggingSessionNotifier.java   |  49 +++++
 .../internal/LoggingSessionRegistryProvider.java}  |  23 ++-
 .../logging => logging/internal}/NullLogFile.java  |   4 +-
 .../internal}/NullLoggingSession.java              |  14 +-
 .../internal/SimpleLoggingProvider.java}           |  25 ++-
 .../internal}/log4j/GemFireLogger.java             |   2 +-
 .../internal}/log4j/LogLevel.java                  |   4 +-
 .../internal}/log4j/LogWriterLevelConverter.java   |  21 +-
 .../internal}/log4j/LogWriterLogger.java           |  47 ++---
 .../internal/spi}/LogConfig.java                   |   3 +-
 .../internal/spi}/LogConfigListener.java           |   2 +-
 .../internal/spi}/LogConfigSupplier.java           |   2 +-
 .../logging => logging/internal/spi}/LogFile.java  |   2 +-
 .../internal/spi}/LogFileDetails.java              |   2 +-
 .../internal/spi}/LogLevelUpdateOccurs.java        |   2 +-
 .../internal/spi}/LogLevelUpdateScope.java         |   2 +-
 .../internal/spi}/LogWriterLevel.java              |   3 +-
 .../internal/spi/LoggingProvider.java}             |  38 +++-
 .../internal/spi}/LoggingSessionListener.java      |   4 +-
 .../internal/spi/LoggingSessionRegistry.java}      |  23 +--
 .../internal/spi/SessionContext.java}              |   9 +-
 .../management/internal/ManagerStartupMessage.java |   2 +-
 .../geode/management/internal/MemberMessenger.java |   2 +-
 .../internal/beans/MemberMBeanBridge.java          |   4 +-
 .../cli/commands/AlterRuntimeConfigCommand.java    |   2 +-
 .../cli/commands/ChangeLogLevelCommand.java        |   2 +-
 .../cli/commands/DiskStoreCommandsUtils.java       |  10 +-
 .../cli/commands/ExportLogsInterceptor.java        |   2 +-
 .../cli/functions/ChangeLogLevelFunction.java      |   2 +-
 .../internal/cli/functions/ExportLogsFunction.java |   2 +-
 .../internal/cli/util/LogLevelExtractor.java       |   2 +-
 .../internal/cli/util/ReadWriteFile.java           |   2 +-
 .../geode/internal/logging/log4j/log4j2-legacy.xml |  19 --
 .../sanctioned-geode-core-serializables.txt        |   1 +
 .../internal/DistributedSystemConfigImplTest.java  |   4 +-
 .../internal}/AlertLevelTest.java                  |  17 +-
 .../internal}/AlertListenerMessageFactoryTest.java |  18 +-
 .../internal/ClusterAlertMessagingTest.java}       |  72 ++++---
 .../internal/ClusterAlertingServiceTest.java       | 162 +++++++++++++++
 .../internal/api/AlertingDependenciesTest.java     |  43 ++++
 .../internal}/log4j/AlertLevelConverterTest.java   |  10 +-
 .../internal/spi}/AlertingActionTest.java          |  29 ++-
 .../client/internal/OpExecutorImplJUnitTest.java   |   2 +-
 .../internal/ServerLocatorJUnitTest.java           |   2 +-
 .../MembershipDependenciesJUnitTest.java           |   2 +-
 .../alerting/AlertingProviderRegistryTest.java     |  94 ---------
 .../internal/alerting/AlertingServiceTest.java     |  75 -------
 .../alerting/NullAlertingProviderTest.java         |  48 -----
 .../geode/internal/{ => logging}/BannerTest.java   |  26 +--
 .../logging/DefaultProviderCheckerTest.java        | 152 --------------
 .../geode/internal/logging/LogServiceTest.java     |  85 +-------
 .../internal/logging/LogWriterFactoryTest.java     |  77 +++++++
 .../geode/internal/logging/LogWriterImplTest.java  |  24 +--
 .../geode/internal/logging/LogWriterLevelTest.java |  25 +--
 .../internal/logging/LoggingThreadFactoryTest.java |   4 +-
 .../geode/internal/logging/LoggingThreadTest.java  |   4 +-
 .../LoggingUncaughtExceptionHandlerTest.java       |   4 +-
 .../internal/logging/ManagerLogWriterTest.java     |  11 +-
 .../internal/logging/NullProviderAgentTest.java    |  40 ----
 .../internal/logging/ProviderAgentLoaderTest.java  | 131 ------------
 .../geode/internal/logging/SortLogFileTest.java    |  22 +-
 .../internal/logging/log4j/AlertAppenderTest.java  | 193 ------------------
 .../geode/internal/logging/log4j/LogLevelTest.java |   3 +-
 .../logging/log4j/LogWriterLevelConverterTest.java |   7 +-
 .../internal/statistics/HostStatSamplerTest.java   |   2 +-
 .../geode/internal/tcp/ConnectionJUnitTest.java    |   2 +-
 .../geode/logging/api/LoggingDependenciesTest.java |  43 ++++
 .../internal}/ConfigurationTest.java               |  23 ++-
 ...essageRegexMatchesStartupConfigurationTest.java |  46 +++--
 .../internal}/LogMessageRegexTest.java             |  46 +++--
 .../internal/LoggingProviderLoaderTest.java        | 114 +++++++++++
 .../internal}/LoggingSessionTest.java              |  26 +--
 .../internal/SimpleLoggingProviderTest.java}       |  26 ++-
 .../bean/stats/MemberLevelStatsTest.java           |   2 +-
 .../management/internal/FederatingManagerTest.java |   2 +-
 .../management/internal/LocalManagerTest.java      |   2 +-
 .../cli/functions/ExportLogsFunctionTest.java      |   2 +-
 .../internal/cli/shell/GfshInitFileJUnitTest.java  |   2 +-
 geode-core/src/test/resources/expected-pom.xml     |  30 ---
 .../resources/log4j2-ignore.xml}                   |   9 +-
 .../org/apache/geode/test/golden/log4j2-test.xml   |  24 +--
 .../rollingupgrade/RollingUpgradeDUnitTest.java    |  19 +-
 .../managing/logging/how_logging_works.html.md.erb |   2 +-
 geode-dunit/build.gradle                           |   5 +-
 .../apache/geode/security/SecurityTestUtils.java   | 223 ++++++++++-----------
 .../geode/test/dunit/internal/DUnitLauncher.java   |   6 +-
 .../geode/test/dunit/internal/ProcessManager.java  |   7 +-
 geode-dunit/src/test/resources/expected-pom.xml    |  16 +-
 geode-log4j/build.gradle                           | 104 ++++++++++
 .../impl}/AlertAppenderIntegrationTest.java        | 136 ++++++-------
 .../AlertListenerRegistrationIntegrationTest.java  |  50 ++---
 .../BothLogWriterAppendersIntegrationTest.java     |  18 +-
 .../CacheWithCustomLogConfigIntegrationTest.java   |  12 +-
 .../CacheWithDefaultAppendersIntegrationTest.java  |  34 ++--
 .../impl}/ConfigurationIntegrationTest.java        |  30 +--
 ...gurationWithLogLevelChangesIntegrationTest.java |  26 +--
 ...penderWithLoggerContextRuleIntegrationTest.java |  26 ++-
 ...mWithBothLogWriterAppendersIntegrationTest.java |  10 +-
 ...edSystemWithLogLevelChangesIntegrationTest.java |  18 +-
 .../internal/impl}/FastLoggerIntegrationTest.java  |  21 +-
 ...FastLoggerWithDefaultConfigIntegrationTest.java |  19 +-
 ...reVerboseMarkerFilterAcceptIntegrationTest.java |  44 +++-
 ...fireVerboseMarkerFilterDenyIntegrationTest.java |  21 +-
 .../impl}/GeodeConsoleAppenderIntegrationTest.java |  32 ++-
 ...odeConsoleAppenderWithCacheIntegrationTest.java |  26 ++-
 ...leAppenderWithSystemOutRuleIntegrationTest.java |  35 ++--
 ...deVerboseMarkerFilterAcceptIntegrationTest.java |  32 ++-
 ...eodeVerboseMarkerFilterDenyIntegrationTest.java |  32 ++-
 ...gServiceWithCustomLogConfigIntegrationTest.java |  11 +-
 .../impl}/LogWriterAppenderIntegrationTest.java    |  16 +-
 ...LogWriterAppenderWithLimitsIntegrationTest.java |  14 +-
 ...AppenderWithMemberNameInXmlIntegrationTest.java |  16 +-
 ...oggingWithDistributedSystemIntegrationTest.java |  36 ++--
 .../log4j/internal/impl}/NonBlankStrings.java      |   6 +-
 .../SecurityLogWriterAppenderIntegrationTest.java  |  14 +-
 .../impl}/AlertAppenderIntegrationTest_log4j2.xml  |   2 +-
 ...othLogWriterAppendersIntegrationTest_log4j2.xml |   2 +-
 ...heWithCustomLogConfigIntegrationTest_log4j2.xml |   3 +-
 ...onWithLogLevelChangesIntegrationTest_log4j2.xml |   2 +-
 ...WithLoggerContextRuleIntegrationTest_log4j2.xml |   2 +-
 ...othLogWriterAppendersIntegrationTest_log4j2.xml |   2 +-
 ...emWithLogLevelChangesIntegrationTest_log4j2.xml |   2 +-
 ...oseMarkerFilterAcceptIntegrationTest_log4j2.xml |   2 +-
 ...rboseMarkerFilterDenyIntegrationTest_log4j2.xml |   2 +-
 .../GeodeConsoleAppenderIntegrationTest_log4j2.xml |   2 +-
 ...soleAppenderWithCacheIntegrationTest_log4j2.xml |  11 +-
 ...nderWithSystemOutRuleIntegrationTest_log4j2.xml |   2 +-
 ...oseMarkerFilterAcceptIntegrationTest_log4j2.xml |   2 +-
 ...rboseMarkerFilterDenyIntegrationTest_log4j2.xml |   2 +-
 ...ceWithCustomLogConfigIntegrationTest_log4j2.xml |   2 +-
 .../LogWriterAppenderIntegrationTest_log4j2.xml    |   2 +-
 ...terAppenderWithLimitsIntegrationTest_log4j2.xml |   2 +-
 ...erWithMemberNameInXmlIntegrationTest_log4j2.xml |   2 +-
 ...rityLogWriterAppenderIntegrationTest_log4j2.xml |   2 +-
 .../FastLoggerDisabledLevelBenchmark.java          |   2 +-
 .../internal}/FastLoggerEnabledLevelBenchmark.java |   2 +-
 .../FastLoggerParameterTypeBenchmark.java          |   2 +-
 .../internal/impl}/CacheLoggingBenchmark.java      |  36 ++--
 .../internal/impl}/LogWriterAppenderBenchmark.java |  50 +++--
 .../log4j/internal/impl}/AlertAppender.java        | 201 ++++++-------------
 .../geode/logging/log4j/internal}/FastLogger.java  |   5 +-
 .../log4j/internal/impl}/AppenderContext.java      |  13 +-
 .../log4j/internal/impl/DebuggableAppender.java    |  15 +-
 .../log4j/internal/impl}/GeodeConsoleAppender.java |  22 +-
 .../impl}/HexThreadIdPatternConverter.java         |   2 +-
 .../log4j/internal/impl/Log4jLoggingProvider.java  |  70 +++++--
 .../log4j/internal/impl}/LogWriterAppender.java    |  36 ++--
 .../internal/impl}/MemberNamePatternConverter.java |   2 +-
 .../log4j/internal/impl}/MemberNameSupplier.java   |   2 +-
 .../log4j/internal/impl}/NullLogWriter.java        |  13 +-
 .../log4j/internal/impl/PausableAppender.java      |  13 +-
 .../impl}/message/GemFireParameterizedMessage.java |  14 +-
 .../GemFireParameterizedMessageFactory.java        |  14 +-
 ...ache.geode.logging.internal.spi.LoggingProvider |  14 ++
 .../src/main/resources/log4j2-cli.xml              |  24 +--
 .../src/main/resources/log4j2.xml                  |  24 +--
 .../geode/internal/logging/LogServiceTest.java     |  63 +-----
 .../logging/log4j/internal}/FastLoggerTest.java    |  85 ++++----
 .../impl}/HexThreadIdPatternConverterTest.java     |  22 +-
 .../internal/impl/LoggingProviderLoaderTest.java   |  61 ++++++
 .../impl}/MemberNamePatternConverterTest.java      |   2 +-
 geode-log4j/src/test/resources/expected-pom.xml    |  89 ++++++++
 geode-pulse/build.gradle                           |  17 +-
 geode-pulse/src/main/resources/log4j2.xml          |  20 +-
 settings.gradle                                    |   2 +
 295 files changed, 3213 insertions(+), 3355 deletions(-)

diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml b/boms/geode-all-bom/src/test/resources/expected-pom.xml
index 64775f8..7b14170 100644
--- a/boms/geode-all-bom/src/test/resources/expected-pom.xml
+++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml
@@ -825,6 +825,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.geode</groupId>
+        <artifactId>geode-log4j</artifactId>
+        <version>1.11.0-SNAPSHOT</version>
+        <scope>compile</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.geode</groupId>
         <artifactId>geode-lucene</artifactId>
         <version>1.11.0-SNAPSHOT</version>
         <scope>compile</scope>
diff --git a/extensions/geode-modules-assembly/release/session/bin/modify_war b/extensions/geode-modules-assembly/release/session/bin/modify_war
index ea7e8e0..f7f632b 100755
--- a/extensions/geode-modules-assembly/release/session/bin/modify_war
+++ b/extensions/geode-modules-assembly/release/session/bin/modify_war
@@ -264,6 +264,7 @@ declare -a OTHER_JARS
 OTHER_JARS=(${GEODE}/lib/geode-core-${VERSION}.jar \
     ${GEODE}/lib/geode-serialization-${VERSION}.jar \
     ${GEODE}/lib/geode-common-${VERSION}.jar \
+    ${GEODE}/lib/geode-log4j-${VERSION}.jar \
     ${GEODE}/lib/geode-management-${VERSION}.jar \
     ${GEODE}/lib/antlr-@ANTLR_VERSION@.jar \
     ${GEODE}/lib/log4j-core-@LOG4J_VERSION@.jar \
diff --git a/geode-assembly/build.gradle b/geode-assembly/build.gradle
index 90de2ee..131261e 100755
--- a/geode-assembly/build.gradle
+++ b/geode-assembly/build.gradle
@@ -32,6 +32,7 @@ def dependentProjectNames = [
   ':geode-serialization',
   ':geode-core',
   ':geode-cq',
+  ':geode-log4j',
   ':geode-lucene',
   ':geode-memcached',
   ':geode-old-client-support',
@@ -39,7 +40,7 @@ def dependentProjectNames = [
   ':geode-protobuf-messages',
   ':geode-rebalancer',
   ':geode-redis',
-  ':geode-wan',
+  ':geode-wan'
 ]
 
 // These other dependencies are explicitly referenced throughout other copySpec
@@ -160,6 +161,7 @@ dependencies {
   geodeArchives project(':geode-connectors')
   geodeArchives project(':geode-core')
   geodeArchives project(':geode-cq')
+  geodeArchives project(':geode-log4j')
   geodeArchives project(':geode-lucene')
   geodeArchives project(':geode-management')
   geodeArchives project(':geode-memcached')
@@ -186,6 +188,9 @@ dependencies {
   testCompile(project(':geode-junit')) {
     exclude module: 'geode-core'
   }
+  testCompile(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
   testRuntime(project(':geode-old-versions'))
 
 
@@ -193,6 +198,9 @@ dependencies {
 
 
   integrationTestCompile(project(':geode-core'))
+  integrationTestCompile(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
   integrationTestCompile(project(':geode-junit')) {
     exclude module: 'geode-core'
   }
@@ -209,6 +217,9 @@ dependencies {
 
   distributedTestImplementation(project(':geode-serialization'))
   distributedTestCompile(project(':geode-core'))
+  distributedTestCompile(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
   distributedTestCompile(project(':geode-dunit')){
     exclude module: 'geode-core'
   }
@@ -517,7 +528,7 @@ distributions {
         into('config')
         from defaultCacheConfig
         from defaultDistributionConfig
-        from(project(':geode-core').sourceSets.main.resources.files.find {
+        from(project(':geode-log4j').sourceSets.main.resources.files.find {
           it.name == 'log4j2.xml'
         })
       }
diff --git a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
index 32b7e08..825d86c 100644
--- a/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
+++ b/geode-assembly/geode-assembly-test/src/main/java/org/apache/geode/session/tests/TomcatInstall.java
@@ -97,10 +97,9 @@ public class TomcatInstall extends ContainerInstall {
    */
   private static final String[] tomcatRequiredJars =
       {"antlr", "commons-io", "commons-lang", "commons-validator", "fastutil", "geode-common",
-          "geode-core", "geode-management", "geode-serialization", "javax.transaction-api",
-          "jgroups", "log4j-api",
-          "log4j-core", "log4j-jul", "micrometer", "shiro-core", "jetty-server", "jetty-util",
-          "jetty-http", "jetty-io"};
+          "geode-core", "geode-log4j", "geode-management", "geode-serialization",
+          "javax.transaction-api", "jgroups", "log4j-api", "log4j-core", "log4j-jul", "micrometer",
+          "shiro-core", "jetty-server", "jetty-util", "jetty-http", "jetty-io"};
 
   private final TomcatVersion version;
 
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandRedactionAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandRedactionAcceptanceTest.java
new file mode 100644
index 0000000..5f2ef39
--- /dev/null
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandRedactionAcceptanceTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.commands;
+
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+public class GfshCommandRedactionAcceptanceTest {
+
+  private static final String LOCATOR_NAME = "locator";
+
+  private int locatorPort;
+  private int unusedPort;
+  private Path locatorFolder;
+  private LocatorLauncher locatorLauncher;
+
+  @Rule
+  public GfshCommandRule gfshCommandRule = new GfshCommandRule();
+
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Before
+  public void setUp() throws Exception {
+    int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+    locatorPort = ports[0];
+    unusedPort = ports[1];
+    locatorFolder = temporaryFolder.newFolder(LOCATOR_NAME).toPath().toAbsolutePath();
+
+    locatorLauncher = new LocatorLauncher.Builder()
+        .setMemberName(LOCATOR_NAME)
+        .setWorkingDirectory(locatorFolder.toString())
+        .setPort(locatorPort)
+        .build();
+    locatorLauncher.start();
+  }
+
+  @After
+  public void tearDown() {
+    locatorLauncher.stop();
+  }
+
+  @Test
+  public void commandsAreLoggedAndRedacted() throws Exception {
+    Path logFile = locatorFolder.resolve(LOCATOR_NAME + ".log");
+
+    gfshCommandRule.connectAndVerify(locatorPort, GfshCommandRule.PortType.locator);
+    gfshCommandRule.executeAndAssertThat(
+        "start locator --properties-file=unknown --J=-Dgemfire.security-password=bob")
+        .statusIsError();
+    gfshCommandRule.executeAndAssertThat("disconnect")
+        .statusIsSuccess();
+    gfshCommandRule.executeAndAssertThat(
+        "connect --jmx-manager=localhost[" + unusedPort + "] --password=secret")
+        .statusIsError();
+
+    Pattern startLocatorPattern = Pattern.compile(
+        "Executing command: start locator --properties-file=unknown --J=-Dgemfire.security-password=\\*\\*\\*\\*\\*\\*\\*\\*");
+    Pattern connectPattern = Pattern.compile(
+        "Executing command: connect --jmx-manager=localhost\\[" + unusedPort
+            + "] --password=\\*\\*\\*\\*\\*\\*\\*\\*");
+
+    Predicate<String> isRelevantLine = startLocatorPattern.asPredicate()
+        .or(connectPattern.asPredicate());
+
+    await().untilAsserted(() -> {
+      List<String> foundPatterns = Files
+          .lines(logFile)
+          .filter(isRelevantLine)
+          .collect(Collectors.toList());
+
+      assertThat(foundPatterns)
+          .as("Log file " + logFile + " includes one line matching each of "
+              + startLocatorPattern + " and " + connectPattern)
+          .hasSize(2);
+
+      assertThat(foundPatterns)
+          .as("lines in the log file")
+          .withFailMessage("%n Expect line matching %s %n but was %s",
+              startLocatorPattern.pattern(), foundPatterns)
+          .anyMatch(startLocatorPattern.asPredicate())
+          .withFailMessage("%n Expect line matching %s %n but was %s",
+              connectPattern.pattern(), foundPatterns)
+          .anyMatch(connectPattern.asPredicate());
+    });
+  }
+}
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 6062773..ac97fa1 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,7 +14,7 @@
  */
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
+import static org.apache.geode.logging.internal.Configuration.STARTUP_CONFIGURATION;
 
 import java.io.File;
 
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerContainer.java b/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerContainer.java
index 50e24ec..ba191c6 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerContainer.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerContainer.java
@@ -14,6 +14,9 @@
  */
 package org.apache.geode.session.tests;
 
+import static java.lang.System.lineSeparator;
+import static java.nio.charset.Charset.defaultCharset;
+import static org.apache.commons.io.FileUtils.readLines;
 import static org.apache.geode.session.tests.ContainerInstall.GEODE_BUILD_HOME;
 import static org.apache.geode.session.tests.ContainerInstall.TMP_DIR;
 
@@ -154,8 +157,15 @@ public class GenericAppServerContainer extends ServerContainer {
     int exitCode = process.waitFor();
     // Throw error if bad exit
     if (exitCode != 0) {
-      throw new IOException("Unable to run modify_war script, command: " + builder.command()
-          + "\ncheck log file: " + modifyWarScriptLog.getAbsolutePath());
+      StringBuilder sb = new StringBuilder();
+      sb.append("Unable to run modify_war script, command: ").append(builder.command());
+      sb.append(lineSeparator());
+      sb.append("check log file: ");
+      for (String line : readLines(modifyWarScriptLog, defaultCharset())) {
+        sb.append(lineSeparator());
+        sb.append(line);
+      }
+      throw new IOException(sb.toString());
     }
   }
 
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 0afc215..eabad85 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -955,6 +955,7 @@ lib/geode-cq-0.0.0.jar
 lib/geode-dependencies.jar
 lib/geode-http-service-0.0.0.jar
 lib/geode-jca-0.0.0.rar
+lib/geode-log4j-0.0.0.jar
 lib/geode-lucene-0.0.0.jar
 lib/geode-management-0.0.0.jar
 lib/geode-memcached-0.0.0.jar
diff --git a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index 41b01f9..3681913 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -3,6 +3,7 @@ geode-connectors-0.0.0.jar
 geode-core-0.0.0.jar
 geode-cq-0.0.0.jar
 geode-http-service-0.0.0.jar
+geode-log4j-0.0.0.jar
 geode-lucene-0.0.0.jar
 geode-management-0.0.0.jar
 geode-memcached-0.0.0.jar
diff --git a/geode-core/build.gradle b/geode-core/build.gradle
index 7f2bdea..448b6a8 100755
--- a/geode-core/build.gradle
+++ b/geode-core/build.gradle
@@ -260,28 +260,12 @@ dependencies {
 
   //Log4j is used everywhere
   implementation('org.apache.logging.log4j:log4j-api')
-  implementation('org.apache.logging.log4j:log4j-core') {
-    ext.optional = true
-  }
 
   //Jansi is used by the CLI (maybe? it is a runtime dependency)
   runtimeOnly('org.fusesource.jansi:jansi') {
     ext.optional = true
   }
 
-  //This routes slf4j logs to log4j. Shiro and micrometer use slf4j
-  runtimeOnly('org.apache.logging.log4j:log4j-slf4j-impl') {
-    exclude module: 'slf4j-api'
-    ext.optional = true
-  }
-  //This routes commons logging logs to log4j. Several apache commons dependencies use commons logging
-  runtimeOnly('org.apache.logging.log4j:log4j-jcl') {
-    ext.optional = true
-  }
-  //This routes jdk logs to log4j. Several dependencies use JDK logs (jackson, jaxb, ...)
-  runtimeOnly('org.apache.logging.log4j:log4j-jul') {
-    ext.optional = true
-  }
   runtimeOnly('io.swagger:swagger-annotations') {
     ext.optional = true
   }
@@ -333,7 +317,6 @@ dependencies {
   //copied into it, so it is an API dependency
   api(project(':geode-management'))
 
-  jcaAnnotationProcessor 'org.apache.logging.log4j:log4j-core'
 
   jcaCompile(sourceSets.main.output)
 
@@ -367,10 +350,11 @@ dependencies {
   integrationTestCompile(project(':geode-dunit')) {
     exclude module: 'geode-core'
   }
+  integrationTestImplementation(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
   integrationTestCompile(project(':geode-concurrency-test'))
   integrationTestCompile('org.apache.bcel:bcel')
-  integrationTestCompile('org.apache.logging.log4j:log4j-core::tests')
-  integrationTestCompile('org.apache.logging.log4j:log4j-core::test-sources')
   integrationTestCompile('org.powermock:powermock-core')
   integrationTestCompile('org.powermock:powermock-module-junit4')
   integrationTestCompile('org.powermock:powermock-api-mockito2')
@@ -387,6 +371,9 @@ dependencies {
   distributedTestCompile(project(':geode-dunit')) {
     exclude module: 'geode-core'
   }
+  distributedTestImplementation(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
   distributedTestCompile('pl.pragmatists:JUnitParams')
   distributedTestCompile('com.jayway.jsonpath:json-path-assert')
   distributedTestCompile('net.openhft:compiler')
@@ -400,11 +387,13 @@ dependencies {
   }
 
   upgradeTestRuntime(project(':geode-old-versions'))
+  upgradeTestRuntime(project(':geode-log4j'))
 
 
   performanceTestCompile(project(':geode-junit')) {
     exclude module: 'geode-core'
   }
+  performanceTestImplementation(project(':geode-log4j'))
 }
 
 jmh {
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceDistributedTest.java
similarity index 93%
rename from geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceDistributedTest.java
rename to geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceDistributedTest.java
index 487a43f..01e59fb 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceDistributedTest.java
@@ -1,22 +1,22 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * 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.
+ * 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.alerting;
+package org.apache.geode.alerting.internal.api;
 
 import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
@@ -24,8 +24,6 @@ import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_S
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.addListener;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.removeListener;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
 import static org.apache.geode.management.JMXNotificationType.SYSTEM_ALERT;
 import static org.apache.geode.management.internal.MBeanJMXAdapter.getDistributedSystemName;
 import static org.apache.geode.management.internal.MBeanJMXAdapter.mbeanServer;
@@ -61,6 +59,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.mockito.ArgumentCaptor;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.admin.remote.AlertListenerMessage;
@@ -75,8 +74,8 @@ import org.apache.geode.test.junit.categories.ManagementTest;
 import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
 
 /**
- * Distributed tests for {@link AlertingService} with {@link DistributedSystemMXBean} in the
- * JMX Manager.
+ * Distributed tests for {@link AlertingService} with {@link DistributedSystemMXBean} in the JMX
+ * Manager.
  */
 @Category({AlertingTest.class, ManagementTest.class})
 public class AlertingServiceDistributedTest implements Serializable {
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceWithoutListenerDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithoutListenerDistributedTest.java
similarity index 95%
rename from geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceWithoutListenerDistributedTest.java
rename to geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithoutListenerDistributedTest.java
index 07f6401..fee7ca5 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/alerting/AlertingServiceWithoutListenerDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithoutListenerDistributedTest.java
@@ -12,9 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.api;
 
 import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
@@ -22,8 +24,6 @@ import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_S
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.addListener;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.removeListener;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
 import static org.apache.geode.management.internal.MBeanJMXAdapter.getDistributedSystemName;
 import static org.apache.geode.management.internal.MBeanJMXAdapter.mbeanServer;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
@@ -51,6 +51,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.mockito.ArgumentCaptor;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.admin.remote.AlertListenerMessage;
@@ -64,8 +65,8 @@ import org.apache.geode.test.junit.categories.ManagementTest;
 import org.apache.geode.test.junit.rules.serializable.SerializableTestName;
 
 /**
- * Distributed tests for {@link AlertingService} with {@link DistributedSystemMXBean} in the
- * JMX Manager without any {@code NotificationListener}s.
+ * Distributed tests for {@link AlertingService} with {@link DistributedSystemMXBean} in the JMX
+ * Manager without any {@code NotificationListener}s.
  */
 @Category({AlertingTest.class, ManagementTest.class})
 public class AlertingServiceWithoutListenerDistributedTest implements Serializable {
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/ConnectionPoolDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/ConnectionPoolDUnitTest.java
index e9b795a..90ad00b 100755
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache/ConnectionPoolDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/ConnectionPoolDUnitTest.java
@@ -15,7 +15,7 @@
 package org.apache.geode.cache;
 
 import static org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier.getInstance;
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
 import static org.apache.geode.test.dunit.Assert.assertEquals;
 import static org.apache.geode.test.dunit.Assert.assertFalse;
 import static org.apache.geode.test.dunit.Assert.assertNotNull;
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/PartitionedRegionDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/PartitionedRegionDUnitTest.java
index 3198486..52173af 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/PartitionedRegionDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/PartitionedRegionDUnitTest.java
@@ -15,7 +15,7 @@
 package org.apache.geode.cache30;
 
 import static org.apache.geode.distributed.ConfigurationProperties.SERIALIZABLE_OBJECT_FILTER;
-import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClientServerTransactionFailoverWithMixedVersionServersDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClientServerTransactionFailoverWithMixedVersionServersDistributedTest.java
index 8b28d4c..bd020b5 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClientServerTransactionFailoverWithMixedVersionServersDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/internal/cache/ClientServerTransactionFailoverWithMixedVersionServersDistributedTest.java
@@ -17,6 +17,7 @@ package org.apache.geode.internal.cache;
 import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
 import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_NETWORK_PARTITION_DETECTION;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE;
 import static org.apache.geode.distributed.ConfigurationProperties.USE_CLUSTER_CONFIGURATION;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.apache.geode.test.dunit.VM.getHostName;
@@ -77,6 +78,10 @@ public class ClientServerTransactionFailoverWithMixedVersionServersDistributedTe
   private int locatorPort;
   private File locatorLog;
   private Host host;
+  private File server1Log;
+  private File server2Log;
+  private File server3Log;
+  private File server4Log;
 
   @Rule
   public DistributedRule distributedRule = new DistributedRule(VM_COUNT);
@@ -95,6 +100,11 @@ public class ClientServerTransactionFailoverWithMixedVersionServersDistributedTe
 
   @Before
   public void setup() throws Exception {
+    server1Log = temporaryFolder.getRoot().toPath().resolve("server1.log").toFile();
+    server2Log = temporaryFolder.getRoot().toPath().resolve("server2.log").toFile();
+    server3Log = temporaryFolder.getRoot().toPath().resolve("server3.log").toFile();
+    server4Log = temporaryFolder.getRoot().toPath().resolve("server4.log").toFile();
+
     host = Host.getHost(0);
     String startingVersion = "1.6.0";
     server1 = host.getVM(startingVersion, 0);
@@ -150,17 +160,17 @@ public class ClientServerTransactionFailoverWithMixedVersionServersDistributedTe
 
   private void setupPartiallyRolledVersion() throws Exception {
     locatorPort = locator.invoke(() -> startLocator());
-    server1.invoke(() -> createCacheServer());
-    server2.invoke(() -> createCacheServer());
-    server3.invoke(() -> createCacheServer());
-    server4.invoke(() -> createCacheServer());
+    server1.invoke(() -> createCacheServer(server1Log));
+    server2.invoke(() -> createCacheServer(server2Log));
+    server3.invoke(() -> createCacheServer(server3Log));
+    server4.invoke(() -> createCacheServer(server4Log));
     client.invoke(() -> createClientCache());
 
     // roll locator
     locator = rollLocatorToCurrent(locator);
     // roll server1
-    server1 = rollServerToCurrent(server1);
-    server2 = rollServerToCurrent(server2);
+    server1 = rollServerToCurrent(server1, server1Log);
+    server2 = rollServerToCurrent(server2, server2Log);
   }
 
   private int startLocator() throws IOException {
@@ -178,17 +188,18 @@ public class ClientServerTransactionFailoverWithMixedVersionServersDistributedTe
     return config;
   }
 
-  private void createCacheServer() throws Exception {
-    cacheRule.createCache(createServerConfig());
+  private void createCacheServer(File logFile) throws Exception {
+    cacheRule.createCache(createServerConfig(logFile));
 
     CacheServer server = cacheRule.getCache().addCacheServer();
     server.setPort(0);
     server.start();
   }
 
-  private Properties createServerConfig() {
+  private Properties createServerConfig(File logFile) {
     Properties config = createLocatorConfig();
     config.setProperty(LOCATORS, hostName + "[" + locatorPort + "]");
+    config.setProperty(LOG_FILE, logFile.getAbsolutePath());
     return config;
   }
 
@@ -208,11 +219,11 @@ public class ClientServerTransactionFailoverWithMixedVersionServersDistributedTe
     Locator.getLocator().stop();
   }
 
-  private VM rollServerToCurrent(VM oldServer) {
+  private VM rollServerToCurrent(VM oldServer, File logFile) {
     // Roll the server
     oldServer.invoke(() -> cacheRule.getCache().close());
     VM rollServer = host.getVM(VersionManager.CURRENT_VERSION, oldServer.getId());
-    rollServer.invoke(() -> createCacheServer());
+    rollServer.invoke(() -> createCacheServer(logFile));
     return rollServer;
   }
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
similarity index 98%
rename from geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java
rename to geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
index a58fbec..32ad2d6 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/internal/logging/LoggingWithReconnectDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/logging/internal/LoggingWithReconnectDistributedTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import static java.lang.System.lineSeparator;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -23,7 +23,7 @@ import static org.apache.geode.distributed.ConfigurationProperties.MAX_WAIT_TIME
 import static org.apache.geode.distributed.ConfigurationProperties.MEMBER_TIMEOUT;
 import static org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper.getMembership;
 import static org.apache.geode.internal.logging.Banner.BannerHeader.displayValues;
-import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
+import static org.apache.geode.logging.internal.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;
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/DistributedSystemMXBeanWithAlertsDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/DistributedSystemMXBeanWithAlertsDistributedTest.java
index fb16425..696a44c 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/DistributedSystemMXBeanWithAlertsDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/DistributedSystemMXBeanWithAlertsDistributedTest.java
@@ -15,15 +15,15 @@
 package org.apache.geode.management;
 
 import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.ERROR;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.WARNING;
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_START;
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
-import static org.apache.geode.internal.alerting.AlertLevel.ERROR;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
-import static org.apache.geode.internal.alerting.AlertLevel.WARNING;
 import static org.apache.geode.management.JMXNotificationType.SYSTEM_ALERT;
 import static org.apache.geode.management.JMXNotificationUserData.ALERT_LEVEL;
 import static org.apache.geode.management.ManagementService.getManagementService;
@@ -62,10 +62,10 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.mockito.ArgumentCaptor;
 
+import org.apache.geode.alerting.internal.api.AlertingService;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.alerting.AlertLevel;
-import org.apache.geode.internal.alerting.AlertingService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.dunit.IgnoredException;
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDistributedTest.java
index d181e08..d7e4670 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDistributedTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/cli/util/MergeLogsDistributedTest.java
@@ -11,7 +11,6 @@
  * 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.util;
 
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/security/ClientAuthenticationDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/security/ClientAuthenticationDUnitTest.java
index 9ae0f79..8b18825 100644
--- a/geode-core/src/distributedTest/java/org/apache/geode/security/ClientAuthenticationDUnitTest.java
+++ b/geode-core/src/distributedTest/java/org/apache/geode/security/ClientAuthenticationDUnitTest.java
@@ -22,6 +22,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
 
 import org.apache.geode.test.junit.categories.SecurityTest;
 import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory;
@@ -34,23 +36,22 @@ import org.apache.geode.test.version.VersionManager;
  *
  * @since GemFire 5.5
  */
-@Category({SecurityTest.class})
+@Category(SecurityTest.class)
 @RunWith(Parameterized.class)
-@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
+@UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
 public class ClientAuthenticationDUnitTest extends ClientAuthenticationTestCase {
-  @Parameterized.Parameters(name = "{0}")
+
+  @Parameters(name = "{0}")
   public static Collection<String> data() {
     List<String> result = VersionManager.getInstance().getVersions();
     if (result.size() < 1) {
       throw new RuntimeException("No older versions of Geode were found to test against");
-    } else {
-      System.out.println("running against these versions: " + result);
     }
+    System.out.println("running against these versions: " + result);
     return result;
   }
 
   public ClientAuthenticationDUnitTest(String version) {
-    super();
     clientVersion = version;
   }
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithClusterIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithClusterIntegrationTest.java
similarity index 96%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithClusterIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithClusterIntegrationTest.java
index 58b2b6a..3e481fd 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithClusterIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithClusterIntegrationTest.java
@@ -12,17 +12,17 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.api;
 
+import static org.apache.geode.alerting.internal.spi.AlertLevel.ERROR;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.WARNING;
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
 import static org.apache.geode.distributed.ConfigurationProperties.START_LOCATOR;
 import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.addListener;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.removeListener;
-import static org.apache.geode.internal.alerting.AlertLevel.ERROR;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
-import static org.apache.geode.internal.alerting.AlertLevel.WARNING;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.getTimeout;
 import static org.apache.geode.test.dunit.NetworkUtils.getServerHostName;
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithLonerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithLonerIntegrationTest.java
similarity index 96%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithLonerIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithLonerIntegrationTest.java
index 1b8e8f5..97d1a7c 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/alerting/AlertingServiceWithLonerIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/alerting/internal/api/AlertingServiceWithLonerIntegrationTest.java
@@ -12,12 +12,12 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.api;
 
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.addListener;
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.removeListener;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/QueueManagerJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/QueueManagerJUnitTest.java
index 804ea70..c4baa1c 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/QueueManagerJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/QueueManagerJUnitTest.java
@@ -16,7 +16,7 @@ package org.apache.geode.cache.client.internal;
 
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static org.apache.geode.internal.logging.LogWriterLevel.FINEST;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINEST;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/pooling/ConnectionManagerJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/pooling/ConnectionManagerJUnitTest.java
index 2145475..4f20d91 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/pooling/ConnectionManagerJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/pooling/ConnectionManagerJUnitTest.java
@@ -17,7 +17,7 @@ package org.apache.geode.cache.client.internal.pooling;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
-import static org.apache.geode.internal.logging.LogWriterLevel.FINEST;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINEST;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
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
index b651d42..6a1b0b7 100644
--- 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
@@ -37,7 +37,7 @@ import org.mockito.junit.MockitoRule;
 import org.mockito.quality.Strictness;
 
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LoggingSession;
+import org.apache.geode.logging.internal.LoggingSession;
 
 public class InternalLocatorIntegrationTest {
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManagerJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManagerJUnitTest.java
index 58619fa..60c3468 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManagerJUnitTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManagerJUnitTest.java
@@ -38,9 +38,9 @@ import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Properties;
@@ -218,7 +218,7 @@ public class GMSMembershipManagerJUnitTest {
   @Test
   public void testSendAdminMessageFailsDuringShutdown() throws Exception {
     AlertListenerMessage m = AlertListenerMessage.create(mockMembers[0], 1,
-        new Date(System.currentTimeMillis()), "thread", "", 1L, "", "");
+        Instant.now(), "thread", "", 1L, "", "");
     manager.getGMSManager().start();
     manager.getGMSManager().started();
     manager.getGMSManager().installView(createView(myMemberId, 1, members));
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionIntegrationTest.java
index 8a0b222..818a855 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionIntegrationTest.java
@@ -15,48 +15,25 @@
 
 package org.apache.geode.internal.cache;
 
-import static org.apache.geode.internal.cache.PartitionedRegionHelper.MAX_PARTITIONED_REGION_ID;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
 
-import java.util.List;
 import java.util.concurrent.ScheduledExecutorService;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
 
 import org.apache.geode.cache.EvictionAction;
 import org.apache.geode.cache.EvictionAttributes;
 import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.distributed.DistributedLockService;
 import org.apache.geode.test.junit.rules.ServerStarterRule;
 
 public class PartitionedRegionIntegrationTest {
 
   @Rule
-  public TestName testName = new TestName();
-
-  @Rule
-  public TemporaryFolder temporaryFolder = new TemporaryFolder();
-
-  @Rule
-  public ServerStarterRule server = new ServerStarterRule().withNoCacheServer();
+  public ServerStarterRule server = new ServerStarterRule().withNoCacheServer().withAutoStart();
 
   @Test
   public void bucketSorterShutdownAfterRegionDestroy() {
-    server.startServer();
     PartitionedRegion region =
         (PartitionedRegion) server.createRegion(RegionShortcut.PARTITION, "PR1",
             f -> f.setEvictionAttributes(
@@ -72,42 +49,10 @@ public class PartitionedRegionIntegrationTest {
 
   @Test
   public void bucketSorterIsNotCreatedIfNoEviction() {
-    server.startServer();
     PartitionedRegion region =
         (PartitionedRegion) server.createRegion(RegionShortcut.PARTITION, "PR1",
             rf -> rf.setOffHeap(false));
     ScheduledExecutorService bucketSorter = region.getBucketSorter();
     assertThat(bucketSorter).isNull();
   }
-
-  @Test
-  // See GEODE-7106
-  public void generatePRIdShouldNotThrowNumberFormatExceptionIfAnErrorOccursWhileReleasingTheLock() {
-    ListAppender listAppender = new ListAppender("ListAppender");
-    Logger partitionRegionLogger = (Logger) LogManager.getLogger(PartitionedRegion.class);
-    partitionRegionLogger.addAppender(listAppender);
-    listAppender.start();
-
-    String methodName = testName.getMethodName();
-    DistributedLockService mockLockService = mock(DistributedLockService.class);
-    doReturn(true).when(mockLockService).lock(any(), anyLong(), anyLong());
-    doThrow(new RuntimeException("Mock Exception")).when(mockLockService).unlock(any());
-
-    server.withProperty("log-level", "FINE").startServer();
-    PartitionedRegion region =
-        spy((PartitionedRegion) server.createRegion(RegionShortcut.PARTITION, methodName));
-    doReturn(mockLockService).when(region).getPartitionedRegionLockService();
-
-    assertThatCode(() -> region.generatePRId(server.getCache().getInternalDistributedSystem()))
-        .doesNotThrowAnyException();
-    List<LogEvent> logEvents = listAppender.getEvents();
-    assertThat(logEvents.stream().anyMatch(logEvent -> logEvent.getMessage().getFormattedMessage()
-        .contains("java.lang.NumberFormatException"))).isFalse();
-    assertThat(logEvents.stream()
-        .anyMatch(logEvent -> logEvent.getMessage().getFormattedMessage().contains(
-            "releasePRIDLock: unlocking " + MAX_PARTITIONED_REGION_ID + " caught an exception")))
-                .isTrue();
-
-    partitionRegionLogger.removeAppender(listAppender);
-  }
 }
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
index d7264f4..8929aea 100644
--- 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
@@ -14,8 +14,8 @@
  */
 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.apache.geode.logging.internal.spi.LogWriterLevel.FINE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -29,6 +29,7 @@ import org.junit.rules.TemporaryFolder;
 import org.junit.rules.TestName;
 
 import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.logging.internal.spi.LogConfig;
 
 /**
  * Integration tests for {@link ManagerLogWriterFactory}.
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesIntegrationTest.java
index bbff6bc..13dc3fd 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/MergeLogFilesIntegrationTest.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.internal.logging;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/BannerLoggingIntegrationTest.java
similarity index 96%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/BannerLoggingIntegrationTest.java
index 434fee3..6e1110a 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/BannerLoggingIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/BannerLoggingIntegrationTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import static java.nio.charset.Charset.defaultCharset;
 import static org.apache.commons.io.FileUtils.readLines;
@@ -36,6 +36,8 @@ import org.junit.rules.TestName;
 
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.logging.Banner;
+import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/ConfigurationInfoIntegrationTest.java
similarity index 92%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/ConfigurationInfoIntegrationTest.java
index 527ee90..6ee056d 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/ConfigurationInfoIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/ConfigurationInfoIntegrationTest.java
@@ -12,9 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-import static org.apache.geode.internal.logging.ConfigurationInfo.getConfigurationInfo;
+import static org.apache.geode.logging.internal.ConfigurationInfo.getConfigurationInfo;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.junit.Test;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/FileSystemCanaryIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/FileSystemCanaryIntegrationTest.java
similarity index 70%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/FileSystemCanaryIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/FileSystemCanaryIntegrationTest.java
index 9d62800..eb28d94 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/FileSystemCanaryIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/FileSystemCanaryIntegrationTest.java
@@ -1,20 +1,18 @@
 /*
- * 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
  *
- * 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.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
similarity index 96%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
index c3ba898..8160b73 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/StartupConfigurationLoggingIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/StartupConfigurationLoggingIntegrationTest.java
@@ -12,13 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 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.apache.geode.logging.internal.Configuration.STARTUP_CONFIGURATION;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.File;
@@ -41,6 +41,8 @@ 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.Banner;
+import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/SystemOutRuleAndSystemErrRuleIntegrationTest.java
similarity index 98%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/SystemOutRuleAndSystemErrRuleIntegrationTest.java
index aded0b4..f49f609 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/SystemOutRuleAndSystemErrRuleIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/SystemOutRuleAndSystemErrRuleIntegrationTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithCacheIntegrationTest.java
similarity index 93%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithCacheIntegrationTest.java
index 81d1b34..f989e80 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithCacheIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithCacheIntegrationTest.java
@@ -12,13 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 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.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Properties;
@@ -36,6 +36,9 @@ 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.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.logging.internal.spi.LogConfig;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithDistributedSystemIntegrationTest.java
similarity index 93%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithDistributedSystemIntegrationTest.java
index 260c2cf..ff46d41 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogLevelChangesWithDistributedSystemIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogLevelChangesWithDistributedSystemIntegrationTest.java
@@ -12,13 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 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.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Properties;
@@ -34,6 +34,9 @@ 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.internal.logging.InternalLogWriter;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.logging.internal.spi.LogConfig;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogRollingWithDistributedSystemIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogRollingWithDistributedSystemIntegrationTest.java
similarity index 99%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogRollingWithDistributedSystemIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogRollingWithDistributedSystemIntegrationTest.java
index 90c77e9..5ffd406 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LogRollingWithDistributedSystemIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LogRollingWithDistributedSystemIntegrationTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
 import static org.apache.geode.distributed.ConfigurationProperties.LOG_DISK_SPACE_LIMIT;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
similarity index 95%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
index 114d526..cfc3107 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorIntegrationTest.java
@@ -12,14 +12,14 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 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.logging.internal.spi.LogWriterLevel.CONFIG;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -41,7 +41,9 @@ 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.internal.logging.LogService;
+import org.apache.geode.logging.internal.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.spi.LogConfig;
 import org.apache.geode.test.assertj.LogFileAssert;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorLauncherIntegrationTest.java
similarity index 97%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorLauncherIntegrationTest.java
index 3310128..3a03d2b 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithLocatorLauncherIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithLocatorLauncherIntegrationTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 import static org.apache.geode.internal.logging.Banner.BannerHeader.displayValues;
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithServerLauncherIntegrationTest.java
similarity index 97%
rename from geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java
rename to geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithServerLauncherIntegrationTest.java
index bb4bc20..b90638e 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/internal/logging/LoggingWithServerLauncherIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/logging/internal/api/LoggingWithServerLauncherIntegrationTest.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.api;
 
 import static org.apache.geode.internal.logging.Banner.BannerHeader.displayValues;
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/DistributedSystemMXBeanIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/DistributedSystemMXBeanIntegrationTest.java
index d694c00..3bbe795 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/DistributedSystemMXBeanIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/DistributedSystemMXBeanIntegrationTest.java
@@ -1,23 +1,23 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.management;
 
 import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
 import static javax.management.JMX.newMXBeanProxy;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.WARNING;
 import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER;
 import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
@@ -25,8 +25,6 @@ import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_S
 import static org.apache.geode.distributed.ConfigurationProperties.NAME;
 import static org.apache.geode.distributed.ConfigurationProperties.START_LOCATOR;
 import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.WARNING;
 import static org.apache.geode.management.JMXNotificationType.SYSTEM_ALERT;
 import static org.apache.geode.management.internal.MBeanJMXAdapter.getDistributedSystemName;
 import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
@@ -55,11 +53,11 @@ import org.junit.experimental.categories.Category;
 import org.junit.rules.TestName;
 import org.mockito.ArgumentCaptor;
 
+import org.apache.geode.alerting.internal.api.AlertingService;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystem;
-import org.apache.geode.internal.alerting.AlertLevel;
-import org.apache.geode.internal.alerting.AlertingService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.test.junit.categories.AlertingTest;
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java
index d7a8a7b..3eed091 100644
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/cli/commands/GfshCommandIntegrationTest.java
@@ -12,68 +12,64 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.List;
+import java.nio.file.Path;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.test.appender.ListAppender;
-import org.junit.ClassRule;
+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.apache.geode.management.internal.cli.remote.CommandExecutor;
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.internal.AvailablePortHelper;
 import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.rules.GfshCommandRule;
-import org.apache.geode.test.junit.rules.LocatorStarterRule;
 
-@Category({GfshTest.class})
+@Category(GfshTest.class)
 public class GfshCommandIntegrationTest {
-  @ClassRule
-  public static LocatorStarterRule locator = new LocatorStarterRule().withAutoStart();
+
+  private static final String LOCATOR_NAME = "locator";
+
+  private int locatorPort;
+  private LocatorLauncher locatorLauncher;
 
   @Rule
-  public GfshCommandRule gfsh = new GfshCommandRule();
+  public GfshCommandRule gfshCommandRule = new GfshCommandRule();
 
-  @Test
-  public void invalidCommandWhenNotConnected() throws Exception {
-    gfsh.executeAndAssertThat("abc").statusIsError().containsOutput("Command 'abc' not found");
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Before
+  public void setUp() throws Exception {
+    Path locatorFolder = temporaryFolder.newFolder(LOCATOR_NAME).toPath().toAbsolutePath();
+    locatorPort = AvailablePortHelper.getRandomAvailableTCPPort();
+
+    locatorLauncher = new LocatorLauncher.Builder()
+        .setMemberName(LOCATOR_NAME)
+        .setWorkingDirectory(locatorFolder.toString())
+        .setPort(locatorPort)
+        .build();
+    locatorLauncher.start();
   }
 
-  @Test
-  public void invalidCommandWhenConnected() throws Exception {
-    gfsh.connectAndVerify(locator);
-    gfsh.executeAndAssertThat("abc").statusIsError().containsOutput("Command 'abc' not found");
+  @After
+  public void tearDown() {
+    locatorLauncher.stop();
   }
 
   @Test
-  public void commandsAreLoggedAndRedacted() {
-    Logger logger = (Logger) LogManager.getLogger(CommandExecutor.class);
-    ListAppender listAppender = new ListAppender("ListAppender");
-    logger.addAppender(listAppender);
-    listAppender.start();
-
-    gfsh.executeAndAssertThat(
-        "start locator --properties-file=unknown --J=-Dgemfire.security-password=bob")
-        .statusIsError();
-    gfsh.executeAndAssertThat("connect --jmx-manager=localhost[999] --password=secret")
-        .statusIsError();
-
-    List<LogEvent> logEvents = listAppender.getEvents();
-    assertThat(logEvents.size()).as("There should be exactly 2 log events").isEqualTo(2);
-
-    String logMessage = logEvents.get(0).getMessage().getFormattedMessage();
-    assertThat(logEvents.get(0).getMessage().getFormattedMessage()).isEqualTo(
-        "Executing command: start locator --properties-file=unknown --J=-Dgemfire.security-password=********");
-    assertThat(logEvents.get(1).getMessage().getFormattedMessage())
-        .isEqualTo("Executing command: connect --jmx-manager=localhost[999] --password=********");
+  public void invalidCommandWhenNotConnected() {
+    gfshCommandRule.executeAndAssertThat("abc").statusIsError()
+        .containsOutput("Command 'abc' not found");
+  }
 
-    logger.removeAppender(listAppender);
+  @Test
+  public void invalidCommandWhenConnected() throws Exception {
+    gfshCommandRule.connectAndVerify(locatorPort, GfshCommandRule.PortType.locator);
+    gfshCommandRule.executeAndAssertThat("abc").statusIsError()
+        .containsOutput("Command 'abc' not found");
   }
 }
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
index 29276db..afe1542 100644
--- 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
@@ -17,8 +17,8 @@ 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.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -42,8 +42,8 @@ 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.logging.internal.spi.LogConfig;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
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 86b00c6..c0b5a13 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
@@ -1,5 +1,7 @@
 org/apache/geode/GemFireCacheException
 org/apache/geode/admin/AlertLevel
+org/apache/geode/alerting/internal/AlertingSession$State
+org/apache/geode/alerting/internal/spi/AlertLevel
 org/apache/geode/cache/operations/internal/UpdateOnlyMap
 org/apache/geode/cache/query/internal/index/CompactRangeIndex$1
 org/apache/geode/cache/query/internal/DefaultQuery$TestHook$SPOTS
@@ -18,8 +20,6 @@ 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
@@ -42,15 +42,6 @@ org/apache/geode/internal/cache/xmlcache/RegionAttributesCreation
 org/apache/geode/internal/datasource/FacetsJCAConnectionManagerImpl
 org/apache/geode/internal/exception/InvalidExecutionContextException
 org/apache/geode/internal/logging/Banner$BannerHeader
-org/apache/geode/internal/logging/LogLevelUpdateOccurs
-org/apache/geode/internal/logging/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/LogWriterLogger
-org/apache/geode/internal/logging/log4j/message/GemFireParameterizedMessage
-org/apache/geode/internal/logging/log4j/message/GemFireParameterizedMessageFactory
 org/apache/geode/internal/offheap/RefCountChangeInfo
 org/apache/geode/internal/process/ProcessStreamReader$ReadingMode
 org/apache/geode/internal/process/ProcessType
@@ -68,6 +59,11 @@ org/apache/geode/internal/shared/TCPSocketOptions
 org/apache/geode/internal/statistics/platform/LinuxProcFsStatistics$CPU
 org/apache/geode/internal/tcp/VersionedByteBufferInputStream
 org/apache/geode/internal/util/concurrent/StoppableReadWriteLock
+org/apache/geode/logging/internal/LogMessageRegex$Group
+org/apache/geode/logging/internal/log4j/LogWriterLogger
+org/apache/geode/logging/internal/spi/LogLevelUpdateOccurs
+org/apache/geode/logging/internal/spi/LogLevelUpdateScope
+org/apache/geode/logging/internal/spi/LogWriterLevel
 org/apache/geode/management/api/ClusterManagementException
 org/apache/geode/management/api/ClusterManagementRealizationException
 org/apache/geode/management/internal/cli/commands/ShowMetricsCommand$Category
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest_log4j2.xml
index 4010458..8fe96e7 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest_log4j2.xml
+++ b/geode-core/src/integrationTest/resources/org/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest_log4j2.xml
@@ -1,19 +1,17 @@
 <?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.custom">
     <Properties>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml b/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml
deleted file mode 100644
index 76940ec..0000000
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/GeodeConsoleAppenderWithCacheIntegrationTest_log4j2.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one or more
-  ~ contributor license agreements.  See the NOTICE file distributed with
-  ~ this work for additional information regarding copyright ownership.
-  ~ The ASF licenses this file to You under the Apache License, Version 2.0
-  ~ (the "License"); you may not use this file except in compliance with
-  ~ the License.  You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<Configuration 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>
-        <GeodeConsole name="STDOUT" target="SYSTEM_OUT" debug="true">
-            <PatternLayout pattern="${geode-pattern}"/>
-        </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"/>
-        <Logger name="org.apache.geode" level="INFO" additivity="true">
-            <filters>
-                <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/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
index a981f01..f292f3e 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/internal/AdminDistributedSystemImpl.java
@@ -95,10 +95,10 @@ import org.apache.geode.internal.logging.Banner;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LogWriterFactory;
-import org.apache.geode.internal.logging.LoggingSession;
-import org.apache.geode.internal.logging.NullLoggingSession;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.util.concurrent.FutureResult;
+import org.apache.geode.logging.internal.LoggingSession;
+import org.apache.geode.logging.internal.NullLoggingSession;
 
 /**
  * Represents a GemFire distributed system for remote administration/management.
diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributedSystemConfigImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributedSystemConfigImpl.java
index aa74af3..91eb302 100755
--- a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributedSystemConfigImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributedSystemConfigImpl.java
@@ -52,11 +52,11 @@ import org.apache.geode.admin.DistributionLocatorConfig;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionConfigImpl;
 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.internal.logging.LogWriterImpl;
-import org.apache.geode.internal.logging.log4j.LogLevel;
 import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.logging.internal.log4j.LogLevel;
+import org.apache.geode.logging.internal.spi.LogConfig;
 
 /**
  * An implementation of the configuration object for an <code>AdminDistributedSystem</code>. After a
diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
index b7c3f59..a90c852 100644
--- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/AgentImpl.java
@@ -61,15 +61,15 @@ import org.apache.geode.internal.ExitCode;
 import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.admin.remote.TailLogResponse;
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LogConfig;
-import org.apache.geode.internal.logging.LogConfigListener;
-import org.apache.geode.internal.logging.LogConfigSupplier;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LogWriterFactory;
-import org.apache.geode.internal.logging.LoggingSession;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.logging.internal.LoggingSession;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigListener;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
 
 /**
  * The GemFire JMX Agent provides the ability to administrate one GemFire distributed system via
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListener.java
similarity index 84%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertListener.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListener.java
index b847cfe..7ce09d1 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListener.java
@@ -12,30 +12,31 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.alerting.internal;
 
 import org.apache.logging.log4j.Level;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.DistributedMember;
 
 /**
  * Simple value object which holds a {@link DistributedMember} and {@link Level} pair.
  */
-class AlertListener {
+public class AlertListener {
 
-  private final Level level;
+  private final AlertLevel level;
   private final DistributedMember member;
 
-  AlertListener(final Level level, final DistributedMember member) {
+  public AlertListener(final AlertLevel level, final DistributedMember member) {
     this.level = level;
     this.member = member;
   }
 
-  Level getLevel() {
+  public AlertLevel getLevel() {
     return level;
   }
 
-  DistributedMember getMember() {
+  public DistributedMember getMember() {
     return member;
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertListenerMessageFactory.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListenerMessageFactory.java
similarity index 85%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertListenerMessageFactory.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListenerMessageFactory.java
index 10e64b0..82ea2cc 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertListenerMessageFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertListenerMessageFactory.java
@@ -12,12 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
 import static org.apache.geode.internal.admin.remote.AlertListenerMessage.create;
 
-import java.util.Date;
+import java.time.Instant;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.admin.remote.AlertListenerMessage;
@@ -26,14 +27,15 @@ class AlertListenerMessageFactory {
 
   AlertListenerMessage createAlertListenerMessage(final DistributedMember member,
       final AlertLevel alertLevel,
-      final Date date,
+      final Instant timestamp,
       final String connectionName,
       final String threadName,
+      final long threadId,
       final String formattedMessage,
       final String stackTrace) {
     verifyDistributedMemberCanReceiveMessage(member);
-    return create(member, alertLevel.intLevel(), date, connectionName, threadName,
-        Thread.currentThread().getId(), formattedMessage, stackTrace);
+    return create(member, alertLevel.intLevel(), timestamp, connectionName, threadName, threadId,
+        formattedMessage, stackTrace);
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertMessaging.java
similarity index 61%
copy from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertMessaging.java
index 3e9a831..3c48982 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertMessaging.java
@@ -12,16 +12,19 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
-/**
- * Defines the lifecycle callbacks of an {@code AlertingSession}.
- */
-public interface AlertingSessionListener {
+import java.time.Instant;
 
-  void createSession(final AlertMessaging alertMessaging);
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.distributed.DistributedMember;
 
-  void startSession();
+/**
+ * Provides the ability to send messages about {@code Alert}s to local or remote {@code Alert}
+ * listeners.
+ */
+public interface AlertMessaging {
 
-  void stopSession();
+  void sendAlert(DistributedMember member, AlertLevel alertLevel, Instant timestamp,
+      String threadName, long threadId, String formattedMessage, String stackTrace);
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSession.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSession.java
similarity index 75%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSession.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSession.java
index c46a3d3..82edba3 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSession.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSession.java
@@ -12,8 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
+import org.apache.geode.alerting.internal.api.AlertingService;
 import org.apache.geode.annotations.VisibleForTesting;
 
 /**
@@ -22,12 +23,13 @@ import org.apache.geode.annotations.VisibleForTesting;
  *
  * <p>
  * During initialization of {@code DistributedSystem} a new {@code AlertingSession} is instantiated
- * and {@code createSession} will be invoked with a new instance of {@code AlertMessaging}. After
+ * and {@code createSession} will be invoked with a new instance of {@code ClusterAlertMessaging}.
+ * After
  * a {@code DistributionConfig} exists, it will then invoke {@code startSession}. During disconnect,
  * it will invoke {@code stopSession}.
  *
  * <p>
- * The {@code AlertAppender} will capture the {@code AlertMessaging} in order to send out
+ * The {@code AlertAppender} will capture the {@code ClusterAlertMessaging} in order to send out
  * {@code Alert} messages to registered {@code Alert} listeners. {@code startSession} will cause
  * the appender to unpause and begin processing all incoming log events. Any log event that meets
  * the {@code AlertLevel} of one or more {@code Alert} listeners will result in the generation of
@@ -35,44 +37,44 @@ import org.apache.geode.annotations.VisibleForTesting;
  */
 public class AlertingSession {
 
-  private final AlertingSessionListeners alertingSessionListeners;
+  private final AlertingSessionNotifier alertingSessionNotifier;
   private State state = State.STOPPED;
 
   public static AlertingSession create() {
-    return create(AlertingSessionListeners.get());
+    return create(AlertingSessionRegistryProvider.get());
   }
 
   @VisibleForTesting
-  static AlertingSession create(final AlertingSessionListeners alertingSessionListeners) {
+  static AlertingSession create(AlertingSessionNotifier alertingSessionListeners) {
     return new AlertingSession(alertingSessionListeners);
   }
 
-  private AlertingSession(final AlertingSessionListeners alertingSessionListeners) {
-    this.alertingSessionListeners = alertingSessionListeners;
+  private AlertingSession(AlertingSessionNotifier alertingSessionNotifier) {
+    this.alertingSessionNotifier = alertingSessionNotifier;
   }
 
-  public synchronized void createSession(final AlertMessaging alertMessaging) {
+  public synchronized void createSession(AlertingService alertingService) {
     state = state.changeTo(State.CREATED);
-    alertingSessionListeners.createSession(alertMessaging);
+    alertingSessionNotifier.createSession(alertingService);
   }
 
   public synchronized void startSession() {
     state = state.changeTo(State.STARTED);
-    alertingSessionListeners.startSession();
+    alertingSessionNotifier.startSession();
   }
 
   public synchronized void stopSession() {
     state = state.changeTo(State.STOPPED);
-    alertingSessionListeners.stopSession();
+    alertingSessionNotifier.stopSession();
   }
 
   public synchronized void shutdown() {
-    // nothing?
+    // nothing
   }
 
   @VisibleForTesting
-  AlertingSessionListeners getAlertingSessionListeners() {
-    return alertingSessionListeners;
+  AlertingSessionNotifier getAlertingSessionNotifier() {
+    return alertingSessionNotifier;
   }
 
   synchronized State getState() {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionNotifier.java
similarity index 73%
copy from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionNotifier.java
index 3e9a831..08c7fac 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionNotifier.java
@@ -12,14 +12,18 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
-/**
- * Defines the lifecycle callbacks of an {@code AlertingSession}.
- */
-public interface AlertingSessionListener {
+import org.apache.geode.alerting.internal.api.AlertingService;
+
+public interface AlertingSessionNotifier {
+
+  /**
+   * Removes all {@code AlertingSessionListener}s that are registered.
+   */
+  void clear();
 
-  void createSession(final AlertMessaging alertMessaging);
+  void createSession(AlertingService alertingService);
 
   void startSession();
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListeners.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionRegistryProvider.java
similarity index 58%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListeners.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionRegistryProvider.java
index ba52607..e9fd324 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListeners.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/AlertingSessionRegistryProvider.java
@@ -12,70 +12,72 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
 import java.util.LinkedHashSet;
 import java.util.Set;
 
+import org.apache.geode.alerting.internal.api.AlertingService;
+import org.apache.geode.alerting.internal.spi.AlertingSessionListener;
+import org.apache.geode.alerting.internal.spi.AlertingSessionRegistry;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 
-/**
- * Manages a collection of registered {@code AlertingSessionListener}s and forwards
- * {@code AlertingSession} lifecycle callbacks to each listener.
- */
-public class AlertingSessionListeners {
+public class AlertingSessionRegistryProvider
+    implements AlertingSessionRegistry, AlertingSessionNotifier {
 
   @MakeNotStatic
-  private static final AlertingSessionListeners INSTANCE = new AlertingSessionListeners();
+  private static final AlertingSessionRegistryProvider INSTANCE =
+      new AlertingSessionRegistryProvider();
 
-  public static AlertingSessionListeners get() {
+  public static AlertingSessionRegistryProvider get() {
     return INSTANCE;
   }
 
   private final Set<AlertingSessionListener> listeners;
 
-  AlertingSessionListeners() {
+  AlertingSessionRegistryProvider() {
     listeners = new LinkedHashSet<>();
   }
 
-  /**
-   * Adds the {@code AlertingSessionListener} and returns true if it was not already
-   * registered.
-   */
-  public synchronized boolean addAlertingSessionListener(final AlertingSessionListener listener) {
-    return listeners.add(listener);
+  @Override
+  public synchronized void addAlertingSessionListener(final AlertingSessionListener listener) {
+    listeners.add(listener);
   }
 
-  /**
-   * Removes the {@code AlertingSessionListener} and returns true if it was registered.
-   */
-  public synchronized boolean removeAlertingSessionListener(
+  @Override
+  public synchronized void removeAlertingSessionListener(
       final AlertingSessionListener listener) {
-    return listeners.remove(listener);
+    listeners.remove(listener);
   }
 
-  /**
-   * Removes all {@code AlertingSessionListener}s that are registered.
-   */
+  @Override
   public synchronized void clear() {
     listeners.clear();
   }
 
-  public synchronized void createSession(final AlertMessaging alertMessaging) {
+  @Override
+  public synchronized void createSession(final AlertingService alertingService) {
     for (AlertingSessionListener listener : listeners) {
-      listener.createSession(alertMessaging);
+      listener.createSession(alertingService);
     }
   }
 
+  @Override
   public synchronized void startSession() {
     for (AlertingSessionListener listener : listeners) {
       listener.startSession();
     }
   }
 
+  @Override
   public synchronized void stopSession() {
     for (AlertingSessionListener listener : listeners) {
       listener.stopSession();
     }
   }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertMessaging.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertMessaging.java
similarity index 71%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertMessaging.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertMessaging.java
index df07aad..ac49dbd 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertMessaging.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertMessaging.java
@@ -12,12 +12,14 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
-import java.util.Date;
+import java.time.Instant;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.DistributionManager;
@@ -26,11 +28,7 @@ import org.apache.geode.internal.admin.remote.AlertListenerMessage;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.tcp.ReenteredConnectException;
 
-/**
- * Provides the ability to send messages about {@code Alert}s to local or remote {@code Alert}
- * listeners.
- */
-public class AlertMessaging {
+public class ClusterAlertMessaging implements AlertMessaging {
 
   private static final Logger logger = LogService.getLogger();
 
@@ -38,11 +36,14 @@ public class AlertMessaging {
   private final DistributionManager dm;
   private final AlertListenerMessageFactory alertListenerMessageFactory;
 
-  public AlertMessaging(final InternalDistributedSystem system) {
-    this(system, system.getDistributionManager(), new AlertListenerMessageFactory());
+  public ClusterAlertMessaging(final InternalDistributedSystem system) {
+    this(system,
+        system.getDistributionManager(),
+        new AlertListenerMessageFactory());
   }
 
-  AlertMessaging(final InternalDistributedSystem system,
+  @VisibleForTesting
+  ClusterAlertMessaging(final InternalDistributedSystem system,
       final DistributionManager dm,
       final AlertListenerMessageFactory alertListenerMessageFactory) {
     this.system = system;
@@ -50,28 +51,33 @@ public class AlertMessaging {
     this.alertListenerMessageFactory = alertListenerMessageFactory;
   }
 
+  @Override
   public void sendAlert(final DistributedMember member,
       final AlertLevel alertLevel,
-      final Date date,
+      final Instant timestamp,
       final String threadName,
+      final long threadId,
       final String formattedMessage,
       final String stackTrace) {
     try {
       String connectionName = system.getConfig().getName();
 
-      AlertListenerMessage message = alertListenerMessageFactory.createAlertListenerMessage(member,
-          alertLevel, date, connectionName, threadName, formattedMessage, stackTrace);
+      AlertListenerMessage message =
+          alertListenerMessageFactory.createAlertListenerMessage(member, alertLevel, timestamp,
+              connectionName, threadName, threadId, formattedMessage, stackTrace);
 
       if (member.equals(system.getDistributedMember())) {
         // process in local member
-        logger.debug("Processing local alert message: {}, {}, {}, {}, {}, [{}], [{}].",
-            member, alertLevel, date, connectionName, threadName, formattedMessage, stackTrace);
+        logger.debug("Processing local alert message: {}, {}, {}, {}, {}, {}, [{}], [{}].",
+            member, alertLevel, timestamp, connectionName, threadName, threadId, formattedMessage,
+            stackTrace);
         processAlertListenerMessage(message);
 
       } else {
         // send to remote member
-        logger.debug("Sending remote alert message: {}, {}, {}, {}, {}, [{}], [{}].",
-            member, alertLevel, date, connectionName, threadName, formattedMessage, stackTrace);
+        logger.debug("Sending remote alert message: {}, {}, {}, {}, {}, {}, [{}], [{}].",
+            member, alertLevel, timestamp, connectionName, threadName, threadId, formattedMessage,
+            stackTrace);
         dm.putOutgoing(message);
       }
     } catch (ReenteredConnectException ignore) {
@@ -80,6 +86,16 @@ public class AlertMessaging {
     }
   }
 
+  public void close() {
+    // nothing
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getName() + "@" + Integer.toHexString(hashCode());
+  }
+
+  @VisibleForTesting
   void processAlertListenerMessage(final AlertListenerMessage message) {
     verifyDistributionManagerCanProcessMessage();
     message.process((ClusterDistributionManager) dm);
diff --git a/geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertingService.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertingService.java
new file mode 100644
index 0000000..672247e
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/ClusterAlertingService.java
@@ -0,0 +1,128 @@
+/*
+ * 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.alerting.internal;
+
+import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.distributed.DistributedMember;
+
+public class ClusterAlertingService implements InternalAlertingService {
+
+  private static final Logger logger = LogManager.getLogger();
+
+  // Listeners are ordered with the narrowest levels (e.g. FATAL) at the end
+  private final CopyOnWriteArrayList<AlertListener> listeners = new CopyOnWriteArrayList<>();
+
+  private final AtomicReference<AlertMessaging> alertMessagingRef =
+      new AtomicReference<>(new NullAlertMessaging());
+
+  public ClusterAlertingService() {
+    // nothing
+  }
+
+  @Override
+  public void useAlertMessaging(AlertMessaging alertMessaging) {
+    alertMessagingRef.set(alertMessaging);
+  }
+
+  @Override
+  public void sendAlerts(final AlertLevel alertLevel,
+      final Instant timestamp,
+      final String threadName,
+      final long threadId,
+      final String formattedMessage,
+      final String stackTrace) {
+
+    for (AlertListener listener : listeners) {
+      if (alertLevel.meetsOrExceeds(listener.getLevel())) {
+        break;
+      }
+
+      logger.trace("Sending alert message for {} to {}.", formattedMessage, listener.getMember());
+
+      alertMessagingRef.get()
+          .sendAlert(listener.getMember(), alertLevel, timestamp, threadName, threadId,
+              formattedMessage,
+              stackTrace);
+    }
+  }
+
+  @Override
+  public synchronized void addAlertListener(final DistributedMember member,
+      final AlertLevel alertLevel) {
+    if (alertLevel == AlertLevel.NONE) {
+      return;
+    }
+    AlertListener listener = new AlertListener(alertLevel, member);
+
+    // Add (or replace) a listener to the list of sorted listeners such that listeners with a
+    // greater level (e.g. FATAL) will be at the end of the list.
+    listeners.remove(listener);
+    for (int i = 0; i < listeners.size(); i++) {
+      if (listener.getLevel().compareTo(listeners.get(i).getLevel()) <= 0) {
+        listeners.add(i, listener);
+        return;
+      }
+    }
+    listeners.add(listener);
+
+    logger.debug("Added/Replaced alert listener for member {} at level {}.", member, alertLevel);
+  }
+
+  @Override
+  public synchronized boolean removeAlertListener(final DistributedMember member) {
+    boolean memberWasFound = listeners.remove(new AlertListener(null, member));
+    if (memberWasFound) {
+      logger.debug("Removed alert listener for member {}.", member);
+    }
+    return memberWasFound;
+  }
+
+  @Override
+  public synchronized boolean hasAlertListener(final DistributedMember member,
+      final AlertLevel alertLevel) {
+    for (AlertListener listener : listeners) {
+      if (listener.getMember().equals(member) && listener.getLevel().equals(alertLevel)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  @Override
+  public boolean hasAlertListeners() {
+    return !listeners.isEmpty();
+  }
+
+  @Override
+  public String toString() {
+    return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
+  }
+
+  @VisibleForTesting
+  synchronized List<AlertListener> getAlertListeners() {
+    return Collections.unmodifiableList(listeners);
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingService.java
similarity index 77%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingService.java
index da785a6..b0c286e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingService.java
@@ -12,12 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.alerting.internal;
 
-/**
- * Listens for logging configuration changes from a {@code LogConfigSupplier}.
- */
-public interface LogConfigListener {
+import org.apache.geode.alerting.internal.api.AlertingService;
+
+public interface InternalAlertingService extends AlertingService {
 
-  void configChanged();
+  void useAlertMessaging(AlertMessaging alertMessaging);
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingServiceFactory.java
similarity index 80%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingServiceFactory.java
index da785a6..300bd39 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/InternalAlertingServiceFactory.java
@@ -12,12 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.alerting.internal;
 
-/**
- * Listens for logging configuration changes from a {@code LogConfigSupplier}.
- */
-public interface LogConfigListener {
+public class InternalAlertingServiceFactory {
 
-  void configChanged();
+  public InternalAlertingService create() {
+    return new ClusterAlertingService();
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertMessaging.java
similarity index 66%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertMessaging.java
index c87e5d3..70cdf0c 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertMessaging.java
@@ -12,21 +12,18 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.alerting.internal;
 
-/**
- * {@link ProviderAgent} that does nothing.
- */
-public class NullProviderAgent implements ProviderAgent {
+import java.time.Instant;
 
-  @Override
-  public void configure(final LogConfig logConfig, final LogLevelUpdateOccurs logLevelUpdateOccurs,
-      final LogLevelUpdateScope logLevelUpdateScope) {
-    // nothing
-  }
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.distributed.DistributedMember;
+
+public class NullAlertMessaging implements AlertMessaging {
 
   @Override
-  public void cleanup() {
+  public void sendAlert(DistributedMember member, AlertLevel alertLevel, Instant timestamp,
+      String threadName, long threadId, String formattedMessage, String stackTrace) {
     // nothing
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingProvider.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertingService.java
similarity index 56%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingProvider.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertingService.java
index bb8c800..e7d818a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingProvider.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/NullAlertingService.java
@@ -12,11 +12,41 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
+import java.time.Instant;
+
+import org.apache.geode.alerting.internal.api.AlertingService;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.annotations.Immutable;
 import org.apache.geode.distributed.DistributedMember;
 
-class NullAlertingProvider implements AlertingProvider {
+/**
+ * Null implementation of {@link AlertingService} that does nothing.
+ */
+public class NullAlertingService implements InternalAlertingService {
+
+  @Immutable
+  private static final NullAlertingService INSTANCE = new NullAlertingService();
+
+  public static NullAlertingService get() {
+    return INSTANCE;
+  }
+
+  private NullAlertingService() {
+    // nothing
+  }
+
+  @Override
+  public void useAlertMessaging(AlertMessaging alertMessaging) {
+    // nothing
+  }
+
+  @Override
+  public void sendAlerts(AlertLevel alertLevel, Instant timestamp, String threadName, long threadId,
+      String formattedMessage, String stackTrace) {
+    // nothing
+  }
 
   @Override
   public void addAlertListener(DistributedMember member, AlertLevel alertLevel) {
@@ -34,17 +64,12 @@ class NullAlertingProvider implements AlertingProvider {
   }
 
   @Override
-  public void createSession(AlertMessaging alertMessaging) {
-    // nothing
-  }
-
-  @Override
-  public void startSession() {
-    // nothing
+  public boolean hasAlertListeners() {
+    return false;
   }
 
   @Override
-  public void stopSession() {
-    // nothing
+  public String toString() {
+    return getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProvider.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/api/AlertingService.java
similarity index 69%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProvider.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/api/AlertingService.java
index 9ba8061..a620b8d 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProvider.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/api/AlertingService.java
@@ -12,20 +12,27 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.api;
 
+import java.time.Instant;
+
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.DistributedMember;
 
 /**
- * Handles {@code Alert} listeners for local and remote members. The implementation is responsible
- * for maintaining registration of {@code Alert} listeners. Listeners are typically managing members
- * that will receive a notification anytime an {@code Alert} is raised.
+ * Adds and removes alert listeners for local and remote members that need to receive
+ * notification of system alerts.
  */
-public interface AlertingProvider extends AlertingSessionListener {
+public interface AlertingService {
+
+  void sendAlerts(AlertLevel alertLevel, Instant timestamp, String threadName, long threadId,
+      String formattedMessage, String stackTrace);
 
   void addAlertListener(DistributedMember member, AlertLevel alertLevel);
 
   boolean removeAlertListener(DistributedMember member);
 
   boolean hasAlertListener(DistributedMember member, AlertLevel alertLevel);
+
+  boolean hasAlertListeners();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertLevelConverter.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverter.java
similarity index 79%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertLevelConverter.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverter.java
index 06276fc..c2a9528 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/AlertLevelConverter.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverter.java
@@ -12,16 +12,16 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.alerting.internal.log4j;
 
-import static org.apache.geode.internal.alerting.AlertLevel.ERROR;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
-import static org.apache.geode.internal.alerting.AlertLevel.WARNING;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.ERROR;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.WARNING;
 
 import org.apache.logging.log4j.Level;
 
-import org.apache.geode.internal.alerting.AlertLevel;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 
 /**
  * Converts between {@link AlertLevel}s and Log4J2 {@code Level}s.
@@ -30,12 +30,12 @@ import org.apache.geode.internal.alerting.AlertLevel;
  * Implementation note: switch and if-else structures perform better than using a HashMap for this
  * which matters the most if used for every log statement.
  */
-class AlertLevelConverter {
+public class AlertLevelConverter {
 
   /**
    * True if the Log4J2 {@code Level} converts to an {@link AlertLevel}.
    */
-  static boolean hasAlertLevel(final Level level) {
+  public static boolean hasAlertLevel(final Level level) {
     if (level == Level.FATAL) {
       return true;
     } else if (level == Level.ERROR) {
@@ -52,7 +52,7 @@ class AlertLevelConverter {
    *
    * @throws IllegalArgumentException if there is no matching Log4J2 Level
    */
-  static Level toLevel(final AlertLevel alert) {
+  public static Level toLevel(final AlertLevel alert) {
     switch (alert) {
       case SEVERE:
         return Level.FATAL;
@@ -72,7 +72,7 @@ class AlertLevelConverter {
    *
    * @throws IllegalArgumentException if there is no matching Alert
    */
-  static AlertLevel fromLevel(final Level level) {
+  public static AlertLevel fromLevel(final Level level) {
     if (level == Level.FATAL) {
       return SEVERE;
     } else if (level == Level.ERROR) {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertLevel.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertLevel.java
similarity index 88%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertLevel.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertLevel.java
index 0ec7984..84b74f2 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertLevel.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertLevel.java
@@ -12,9 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.spi;
 
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 
 /**
  * Defines the {@code LogWriterLevel}s that are available for use as a threshold for generating and
@@ -46,6 +46,10 @@ public enum AlertLevel {
     return intLevel;
   }
 
+  public boolean meetsOrExceeds(AlertLevel alertLevel) {
+    return intLevel() < alertLevel.intLevel();
+  }
+
   @Override
   public String toString() {
     return getClass().getSimpleName() + "." + name() + "(" + intLevel + ")";
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingAction.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingAction.java
similarity index 80%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingAction.java
rename to geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingAction.java
index c94ceb5..b88355a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingAction.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingAction.java
@@ -12,7 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.spi;
+
+import org.apache.geode.annotations.VisibleForTesting;
 
 /**
  * Executes an action that is protected against generating additional {@code Alert}s. Even if the
@@ -24,15 +26,26 @@ public class AlertingAction {
   private static final ThreadLocal<Boolean> ALERTING = ThreadLocal.withInitial(() -> Boolean.FALSE);
 
   public static void execute(final Runnable action) {
+    if (ALERTING.get()) {
+      return;
+    }
     ALERTING.set(true);
     try {
       action.run();
     } finally {
-      ALERTING.set(false);
+      ALERTING.remove();
     }
   }
 
   public static boolean isThreadAlerting() {
     return ALERTING.get();
   }
+
+  @VisibleForTesting
+  static void setThreadAlerting(final boolean value) {
+    ALERTING.set(value);
+    if (!value) {
+      ALERTING.remove();
+    }
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionListener.java
similarity index 69%
copy from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionListener.java
index 3e9a831..042fb14 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionListener.java
@@ -12,16 +12,27 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.spi;
+
+import org.apache.geode.alerting.internal.api.AlertingService;
 
 /**
- * Defines the lifecycle callbacks of an {@code AlertingSession}.
+ * Defines the lifecycle callbacks of an alerting session.
  */
 public interface AlertingSessionListener {
 
-  void createSession(final AlertMessaging alertMessaging);
+  /**
+   * Notifies creation of new alerting session.
+   */
+  void createSession(AlertingService alertingService);
 
+  /**
+   * Notifies start of alerting session.
+   */
   void startSession();
 
+  /**
+   * Notifies stop of alerting session.
+   */
   void stopSession();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionRegistry.java
similarity index 59%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java
copy to geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionRegistry.java
index aadc00f..4c8affa 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java
+++ b/geode-core/src/main/java/org/apache/geode/alerting/internal/spi/AlertingSessionRegistry.java
@@ -12,26 +12,21 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.alerting.internal.spi;
 
 /**
- * Controls whether or not log level updates should be triggered. Default is
- * {@link #ONLY_WHEN_USING_DEFAULT_CONFIG}.
+ * Manages registration of {@link AlertingSessionListener}s and provides notifications to them.
  */
-public enum LogLevelUpdateOccurs {
-  NEVER,
-  ONLY_WHEN_USING_DEFAULT_CONFIG,
-  ALWAYS;
+public interface AlertingSessionRegistry {
 
-  public boolean never() {
-    return this == NEVER;
-  }
+  /**
+   * Adds the {@code AlertingSessionListener} and returns true if it was not already
+   * registered.
+   */
+  void addAlertingSessionListener(AlertingSessionListener listener);
 
-  public boolean always() {
-    return this == ALWAYS;
-  }
-
-  public boolean onlyWhenUsingDefaultConfig() {
-    return this == ONLY_WHEN_USING_DEFAULT_CONFIG;
-  }
+  /**
+   * Removes the {@code AlertingSessionListener} and returns true if it was registered.
+   */
+  void removeAlertingSessionListener(AlertingSessionListener listener);
 }
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
index e7c043c..5ec2179 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
@@ -209,9 +209,9 @@ import org.apache.geode.internal.ConfigSource;
 import org.apache.geode.internal.admin.remote.DistributionLocatorId;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.internal.logging.log4j.LogLevel;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.security.SecurableCommunicationChannel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 
 /**
  * Provides an implementation of <code>DistributionConfig</code> that knows how to read the
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
index 5cea9f7..c931bb7 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/ClusterDistributionManager.java
@@ -55,6 +55,7 @@ import org.apache.geode.SystemConnectException;
 import org.apache.geode.SystemFailure;
 import org.apache.geode.ToDataException;
 import org.apache.geode.admin.GemFireHealthConfig;
+import org.apache.geode.alerting.internal.api.AlertingService;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 import org.apache.geode.cache.CacheClosedException;
 import org.apache.geode.distributed.DistributedMember;
@@ -76,7 +77,6 @@ import org.apache.geode.internal.OSProcess;
 import org.apache.geode.internal.admin.remote.AdminConsoleDisconnectMessage;
 import org.apache.geode.internal.admin.remote.RemoteGfManagerAgent;
 import org.apache.geode.internal.admin.remote.RemoteTransportConfig;
-import org.apache.geode.internal.alerting.AlertingService;
 import org.apache.geode.internal.cache.InitialImageOperation;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.logging.LogService;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
index 9ddcbde..6699551 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
@@ -203,12 +203,12 @@ import org.apache.geode.distributed.ConfigurationProperties;
 import org.apache.geode.distributed.DistributedSystem;
 import org.apache.geode.internal.Config;
 import org.apache.geode.internal.ConfigSource;
-import org.apache.geode.internal.logging.LogConfig;
 import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.internal.logging.LogWriterLevel;
 import org.apache.geode.internal.security.SecurableCommunicationChannel;
 import org.apache.geode.internal.statistics.StatisticsConfig;
 import org.apache.geode.internal.tcp.Connection;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 
 /**
  * Provides accessor (and in some cases mutator) methods for the various GemFire distribution
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
index 3c631d6..fcb46e3 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionManager.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ExecutorService;
 
 import org.apache.geode.CancelCriterion;
 import org.apache.geode.admin.GemFireHealthConfig;
+import org.apache.geode.alerting.internal.api.AlertingService;
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheClosedException;
 import org.apache.geode.distributed.DistributedMember;
@@ -31,7 +32,6 @@ import org.apache.geode.distributed.Role;
 import org.apache.geode.distributed.internal.locks.ElderState;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.MembershipManager;
-import org.apache.geode.internal.alerting.AlertingService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.monitoring.ThreadsMonitoring;
 import org.apache.geode.internal.serialization.Version;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
index 66c3e2a..821a508 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java
@@ -59,6 +59,12 @@ import org.apache.geode.Statistics;
 import org.apache.geode.StatisticsType;
 import org.apache.geode.SystemConnectException;
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.AlertingSession;
+import org.apache.geode.alerting.internal.ClusterAlertMessaging;
+import org.apache.geode.alerting.internal.InternalAlertingService;
+import org.apache.geode.alerting.internal.InternalAlertingServiceFactory;
+import org.apache.geode.alerting.internal.NullAlertMessaging;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.annotations.Immutable;
 import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.annotations.internal.MakeNotStatic;
@@ -80,10 +86,6 @@ import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.InternalInstantiator;
 import org.apache.geode.internal.SystemTimer;
 import org.apache.geode.internal.admin.remote.DistributionLocatorId;
-import org.apache.geode.internal.alerting.AlertLevel;
-import org.apache.geode.internal.alerting.AlertMessaging;
-import org.apache.geode.internal.alerting.AlertingService;
-import org.apache.geode.internal.alerting.AlertingSession;
 import org.apache.geode.internal.cache.CacheServerImpl;
 import org.apache.geode.internal.cache.EventID;
 import org.apache.geode.internal.cache.GemFireCacheImpl;
@@ -96,15 +98,9 @@ import org.apache.geode.internal.cache.tier.sockets.EncryptorImpl;
 import org.apache.geode.internal.cache.xmlcache.CacheServerCreation;
 import org.apache.geode.internal.config.ClusterConfigurationNotAvailableException;
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LogConfig;
-import org.apache.geode.internal.logging.LogConfigListener;
-import org.apache.geode.internal.logging.LogConfigSupplier;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LogWriterFactory;
-import org.apache.geode.internal.logging.LoggingSession;
 import org.apache.geode.internal.logging.LoggingThread;
-import org.apache.geode.internal.logging.NullLoggingSession;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.internal.offheap.MemoryAllocator;
 import org.apache.geode.internal.offheap.OffHeapStorage;
@@ -119,6 +115,12 @@ import org.apache.geode.internal.statistics.StatisticsRegistry;
 import org.apache.geode.internal.statistics.platform.LinuxProcFsStatistics;
 import org.apache.geode.internal.tcp.ConnectionTable;
 import org.apache.geode.internal.util.JavaWorkarounds;
+import org.apache.geode.logging.internal.LoggingSession;
+import org.apache.geode.logging.internal.NullLoggingSession;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigListener;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
+import org.apache.geode.logging.internal.spi.LogFile;
 import org.apache.geode.management.ManagementException;
 import org.apache.geode.pdx.internal.TypeRegistry;
 import org.apache.geode.security.GemFireSecurityException;
@@ -181,6 +183,9 @@ public class InternalDistributedSystem extends DistributedSystem
   /** services provided by other modules */
   private Map<Class, DistributedSystemService> services = new HashMap<>();
 
+  private final AtomicReference<ClusterAlertMessaging> clusterAlertMessaging =
+      new AtomicReference<>();
+
   /**
    * If the experimental multiple-system feature is enabled, always create a new system.
    *
@@ -399,7 +404,7 @@ public class InternalDistributedSystem extends DistributedSystem
   private boolean deltaEnabledOnServer = true;
 
   private final AlertingSession alertingSession;
-  private final AlertingService alertingService;
+  private final InternalAlertingService alertingService;
 
   private final LoggingSession loggingSession;
   private final Set<LogConfigListener> logConfigListeners = new HashSet<>();
@@ -531,7 +536,7 @@ public class InternalDistributedSystem extends DistributedSystem
   private InternalDistributedSystem(ConnectionConfig config,
       StatisticsManagerFactory statisticsManagerFactory) {
     alertingSession = AlertingSession.create();
-    alertingService = new AlertingService();
+    alertingService = new InternalAlertingServiceFactory().create();
     loggingSession = LoggingSession.create();
     originalConfig = config.distributionConfig();
     isReconnectingDS = config.isReconnecting();
@@ -788,7 +793,9 @@ public class InternalDistributedSystem extends DistributedSystem
 
       startSampler();
 
-      alertingSession.createSession(new AlertMessaging(this));
+      clusterAlertMessaging.set(new ClusterAlertMessaging(this));
+      alertingService.useAlertMessaging(clusterAlertMessaging.get());
+      alertingSession.createSession(alertingService);
       alertingSession.startSession();
 
       // Log any instantiators that were registered before the log writer
@@ -1608,6 +1615,8 @@ public class InternalDistributedSystem extends DistributedSystem
           if (!attemptingToReconnect) {
             loggingSession.shutdown();
           }
+          alertingService.useAlertMessaging(new NullAlertMessaging());
+          clusterAlertMessaging.get().close();
           alertingSession.shutdown();
           // Close the config object
           config.close();
@@ -1744,7 +1753,7 @@ public class InternalDistributedSystem extends DistributedSystem
     return config;
   }
 
-  public AlertingService getAlertingService() {
+  public InternalAlertingService getAlertingService() {
     return alertingService;
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
index d546018..750e0d3 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
@@ -77,17 +77,17 @@ import org.apache.geode.internal.cache.tier.sockets.TcpServerFactory;
 import org.apache.geode.internal.cache.wan.WANServiceProvider;
 import org.apache.geode.internal.config.JAXBService;
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LogConfig;
-import org.apache.geode.internal.logging.LogConfigListener;
-import org.apache.geode.internal.logging.LogConfigSupplier;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LogWriterFactory;
-import org.apache.geode.internal.logging.LoggingSession;
 import org.apache.geode.internal.logging.LoggingThread;
-import org.apache.geode.internal.logging.NullLoggingSession;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.net.SocketCreatorFactory;
 import org.apache.geode.internal.statistics.StatisticsConfig;
+import org.apache.geode.logging.internal.LoggingSession;
+import org.apache.geode.logging.internal.NullLoggingSession;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigListener;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
 import org.apache.geode.management.api.ClusterManagementService;
 import org.apache.geode.management.internal.AgentUtil;
 import org.apache.geode.management.internal.JmxManagerLocator;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
index e0d1aa4..6e98b4b 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/LonerDistributionManager.java
@@ -39,6 +39,8 @@ import java.util.concurrent.TimeoutException;
 import org.apache.geode.CancelCriterion;
 import org.apache.geode.InternalGemFireError;
 import org.apache.geode.admin.GemFireHealthConfig;
+import org.apache.geode.alerting.internal.NullAlertingService;
+import org.apache.geode.alerting.internal.api.AlertingService;
 import org.apache.geode.annotations.Immutable;
 import org.apache.geode.cache.CacheClosedException;
 import org.apache.geode.distributed.DistributedMember;
@@ -49,8 +51,6 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe
 import org.apache.geode.distributed.internal.membership.MemberAttributes;
 import org.apache.geode.distributed.internal.membership.MembershipManager;
 import org.apache.geode.i18n.LogWriterI18n;
-import org.apache.geode.internal.alerting.AlertingService;
-import org.apache.geode.internal.alerting.NullAlertingService;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.logging.InternalLogWriter;
 import org.apache.geode.internal.logging.LoggingExecutors;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/ProductUseLog.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/ProductUseLog.java
index a09cea9..6232155 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/ProductUseLog.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/ProductUseLog.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.distributed.internal;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
 
 import java.io.File;
 import java.io.FileNotFoundException;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
index 383ab6f..89e5448 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/direct/DirectChannel.java
@@ -33,6 +33,7 @@ import org.apache.geode.CancelCriterion;
 import org.apache.geode.CancelException;
 import org.apache.geode.InternalGemFireException;
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.cache.TimeoutException;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystemDisconnectedException;
@@ -46,7 +47,6 @@ import org.apache.geode.distributed.internal.ReplyProcessor21;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.MembershipManager;
 import org.apache.geode.distributed.internal.membership.gms.api.MessageListener;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.cache.DirectReplyMessage;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LogMarker;
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManager.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManager.java
index d4185fe..1faf5b0 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManager.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/adapter/GMSMembershipManager.java
@@ -86,7 +86,6 @@ import org.apache.geode.internal.Assert;
 import org.apache.geode.internal.SystemTimer;
 import org.apache.geode.internal.cache.partitioned.PartitionMessageWithDirectReply;
 import org.apache.geode.internal.logging.LoggingThread;
-import org.apache.geode.internal.logging.log4j.AlertAppender;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.serialization.DataSerializableFixedID;
 import org.apache.geode.internal.serialization.Version;
@@ -2585,8 +2584,6 @@ public class GMSMembershipManager implements MembershipManager {
       services.setShutdownCause(shutdownCause);
       services.getCancelCriterion().cancel(reason);
 
-      AlertAppender.stopSessionIfRunning();
-
       if (!inhibitForceDisconnectLogging) {
         logger.fatal(
             String.format("Membership service failure: %s", reason),
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
index 5471abd..61bc20d 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/messenger/JGroupsMessenger.java
@@ -73,6 +73,7 @@ import org.apache.geode.GemFireIOException;
 import org.apache.geode.InternalGemFireError;
 import org.apache.geode.InternalGemFireException;
 import org.apache.geode.SystemConnectException;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.annotations.internal.MutableForTesting;
 import org.apache.geode.distributed.DistributedSystemDisconnectedException;
 import org.apache.geode.distributed.internal.DistributionConfig;
@@ -92,7 +93,6 @@ import org.apache.geode.distributed.internal.membership.gms.messages.JoinRequest
 import org.apache.geode.distributed.internal.membership.gms.messages.JoinResponseMessage;
 import org.apache.geode.internal.ClassPathLoader;
 import org.apache.geode.internal.OSProcess;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.cache.DistributedCacheOperation;
 import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.serialization.BufferDataOutputStream;
diff --git a/geode-core/src/main/java/org/apache/geode/i18n/StringId.java b/geode-core/src/main/java/org/apache/geode/i18n/StringId.java
index 8fbe91e..aef1277 100755
--- a/geode-core/src/main/java/org/apache/geode/i18n/StringId.java
+++ b/geode-core/src/main/java/org/apache/geode/i18n/StringId.java
@@ -19,6 +19,7 @@ import java.util.Locale;
 
 import org.apache.geode.annotations.Immutable;
 import org.apache.geode.internal.i18n.AbstractStringIdResourceBundle;
+import org.apache.geode.internal.logging.LogWriterImpl;
 
 /**
  * This class forms the basis of the i18n strategy. Its primary function is to be used as a key to
@@ -36,7 +37,7 @@ public class StringId {
    * A unique identifier that is written when this StringId is logged to allow for reverse
    * translation.
    *
-   * @see org.apache.geode.internal.logging.LogWriterImpl
+   * @see LogWriterImpl
    */
   public final int id;
   /** the English translation of text */
diff --git a/geode-core/src/main/java/org/apache/geode/internal/ClassPathLoader.java b/geode-core/src/main/java/org/apache/geode/internal/ClassPathLoader.java
index 0bab739..ecce58b 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/ClassPathLoader.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/ClassPathLoader.java
@@ -29,11 +29,12 @@ import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 
+import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 import org.apache.geode.distributed.internal.DistributionConfig;
-import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.util.CollectionUtils;
 
 /**
@@ -42,14 +43,15 @@ import org.apache.geode.internal.util.CollectionUtils;
  * loaders, thread context <tt>ClassLoader</tt> s unless they have been excluded}, the
  * <tt>ClassLoader</tt> which loaded the GemFire classes, and finally the system
  * <tt>ClassLoader</tt>.
+ *
  * <p>
  * The thread context class loaders can be excluded by setting the system property
  * <tt>gemfire.excludeThreadContextClassLoader</tt>:
  * <ul>
  * <li><tt>-Dgemfire.excludeThreadContextClassLoader=true</tt>
- * <li><tt>System.setProperty("gemfire.excludeThreadContextClassLoader", "true");
- * </tt>
+ * <li><tt>System.setProperty("gemfire.excludeThreadContextClassLoader", "true");</tt>
  * </ul>
+ *
  * <p>
  * Class loading and resource loading order:
  * <ul>
@@ -57,16 +59,18 @@ import org.apache.geode.internal.util.CollectionUtils;
  * <li>2. <tt>Thread.currentThread().getContextClassLoader()</tt> unless excludeTCCL == true
  * <li>3. <tt>ClassPathLoader.class.getClassLoader()</tt>
  * <li>4. <tt>ClassLoader.getSystemClassLoader()</tt> If the attempt to acquire any of the above
- * class loaders results in either a {@link java.lang.SecurityException SecurityException} or a
- * null, then that class loader is quietly skipped. Duplicate class loaders will be skipped.
+ * class loaders results in either a {@code SecurityException} or a null, then that class loader is
+ * quietly skipped. Duplicate class loaders will be skipped.
+ * </ul>
+ *
  * <p>
- * This class it not an extension of ClassLoader due to #43080. See also
- * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html
+ * See http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html for more information about
+ * {@code ClassLoader}s.
  *
  * @since GemFire 6.5.1.4
  */
 public class ClassPathLoader {
-  private static final Logger logger = LogService.getLogger();
+  private static final Logger logger = LogManager.getLogger();
 
   static final String EXCLUDE_TCCL_PROPERTY =
       DistributionConfig.GEMFIRE_PREFIX + "excludeThreadContextClassLoader";
@@ -74,27 +78,28 @@ public class ClassPathLoader {
   @MakeNotStatic
   private static volatile ClassPathLoader latest;
 
-  public final HashMap<String, DeployJarChildFirstClassLoader> latestJarNamesToClassLoader =
+  private final HashMap<String, DeployJarChildFirstClassLoader> latestJarNamesToClassLoader =
       new HashMap<>();
 
   private volatile DeployJarChildFirstClassLoader leafLoader;
 
   private final JarDeployer jarDeployer;
 
-  private boolean excludeTCCL;
+  private final boolean excludeTCCL;
 
   public ClassPathLoader(boolean excludeTCCL) {
     this.excludeTCCL = excludeTCCL;
-    this.jarDeployer = new JarDeployer();
+    jarDeployer = new JarDeployer();
     rebuildClassLoaderForDeployedJars();
   }
 
   public ClassPathLoader(boolean excludeTCCL, File workingDir) {
     this.excludeTCCL = excludeTCCL;
-    this.jarDeployer = new JarDeployer(workingDir);
+    jarDeployer = new JarDeployer(workingDir);
     rebuildClassLoaderForDeployedJars();
   }
 
+  @VisibleForTesting
   static ClassPathLoader setLatestToDefault() {
     latest = new ClassPathLoader(Boolean.getBoolean(EXCLUDE_TCCL_PROPERTY));
     return latest;
@@ -106,17 +111,18 @@ public class ClassPathLoader {
   }
 
   public JarDeployer getJarDeployer() {
-    return this.jarDeployer;
+    return jarDeployer;
   }
 
   /**
    * createWithDefaults is exposed for testing.
    */
+  @VisibleForTesting
   static ClassPathLoader createWithDefaults(final boolean excludeTCCL) {
     return new ClassPathLoader(excludeTCCL);
   }
 
-  synchronized void rebuildClassLoaderForDeployedJars() {
+  private synchronized void rebuildClassLoaderForDeployedJars() {
     leafLoader = null;
     Collection<DeployedJar> deployedJars = jarDeployer.getDeployedJars().values();
     for (DeployedJar deployedJar : deployedJars) {
@@ -124,7 +130,7 @@ public class ClassPathLoader {
     }
   }
 
-  ClassLoader getLeafLoader() {
+  private ClassLoader getLeafLoader() {
     if (leafLoader == null) {
       return ClassPathLoader.class.getClassLoader();
     }
@@ -132,7 +138,7 @@ public class ClassPathLoader {
   }
 
   synchronized void chainClassloader(DeployedJar jar) {
-    this.leafLoader = new DeployJarChildFirstClassLoader(latestJarNamesToClassLoader,
+    leafLoader = new DeployJarChildFirstClassLoader(latestJarNamesToClassLoader,
         new URL[] {jar.getFileURL()}, jar.getJarName(), getLeafLoader());
   }
 
@@ -141,20 +147,20 @@ public class ClassPathLoader {
   }
 
   public URL getResource(final String name) {
-    final boolean isDebugEnabled = logger.isTraceEnabled();
-    if (isDebugEnabled) {
+    final boolean isTraceEnabled = logger.isTraceEnabled();
+    if (isTraceEnabled) {
       logger.trace("getResource({})", name);
     }
 
     for (ClassLoader classLoader : getClassLoaders()) {
-      if (isDebugEnabled) {
+      if (isTraceEnabled) {
         logger.trace("getResource trying: {}", classLoader);
       }
       try {
         URL url = classLoader.getResource(name);
 
         if (url != null) {
-          if (isDebugEnabled) {
+          if (isTraceEnabled) {
             logger.trace("getResource found by: {}", classLoader);
           }
           return url;
@@ -168,21 +174,21 @@ public class ClassPathLoader {
   }
 
   public Class<?> forName(final String name) throws ClassNotFoundException {
-    final boolean isDebugEnabled = logger.isTraceEnabled();
-    if (isDebugEnabled) {
+    final boolean isTraceEnabled = logger.isTraceEnabled();
+    if (isTraceEnabled) {
       logger.trace("forName({})", name);
     }
 
-    Class<?> clazz = forName(name, isDebugEnabled);
+    Class<?> clazz = forName(name, isTraceEnabled);
     if (clazz != null)
       return clazz;
 
     throw new ClassNotFoundException(name);
   }
 
-  private Class<?> forName(String name, boolean isDebugEnabled) {
-    for (ClassLoader classLoader : this.getClassLoaders()) {
-      if (isDebugEnabled) {
+  private Class<?> forName(String name, boolean isTraceEnabled) {
+    for (ClassLoader classLoader : getClassLoaders()) {
+      if (isTraceEnabled) {
         logger.trace("forName trying: {}", classLoader);
       }
       try {
@@ -194,7 +200,7 @@ public class ClassPathLoader {
         }
         Class<?> clazz = Class.forName(name, true, classLoader);
         if (clazz != null) {
-          if (isDebugEnabled) {
+          if (isTraceEnabled) {
             logger.trace("forName found by: {}", classLoader);
           }
           return clazz;
@@ -212,7 +218,7 @@ public class ClassPathLoader {
   Class<?> getProxyClass(final Class<?>... classObjs) {
     IllegalArgumentException ex = null;
 
-    for (ClassLoader classLoader : this.getClassLoaders()) {
+    for (ClassLoader classLoader : getClassLoaders()) {
       try {
         return Proxy.getProxyClass(classLoader, classObjs);
       } catch (SecurityException sex) {
@@ -233,9 +239,9 @@ public class ClassPathLoader {
   public String toString() {
     final StringBuilder sb = new StringBuilder(getClass().getName());
     sb.append("@").append(System.identityHashCode(this)).append("{");
-    sb.append(", excludeTCCL=").append(this.excludeTCCL);
+    sb.append(", excludeTCCL=").append(excludeTCCL);
     sb.append(", classLoaders=[");
-    sb.append(this.getClassLoaders().stream().map(ClassLoader::toString).collect(joining(", ")));
+    sb.append(getClassLoaders().stream().map(ClassLoader::toString).collect(joining(", ")));
     sb.append("]}");
     return sb.toString();
   }
@@ -300,19 +306,19 @@ public class ClassPathLoader {
 
   /**
    * Finds all the resources with the given name. This method will first search the class loader of
-   * the context class for the resource before searching all other {@link ClassLoader}s.
+   * the context class for the resource before searching all other {@code ClassLoader}s.
    *
    * @param contextClass The class whose class loader will first be searched
    * @param name The resource name
-   * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for the resource. If no
-   *         resources could be found, the enumeration will be empty. Resources that the class
-   *         loader doesn't have access to will not be in the enumeration.
+   * @return An enumeration of <tt>URL</tt> objects for the resource. If no resources could be
+   *         found, the enumeration will be empty. Resources that the class loader doesn't have
+   *         access to will not be in the enumeration.
    * @throws IOException If I/O errors occur
    * @see ClassLoader#getResources(String)
    */
   private Enumeration<URL> getResources(final Class<?> contextClass, final String name)
       throws IOException {
-    final LinkedHashSet<URL> urls = new LinkedHashSet<URL>();
+    final LinkedHashSet<URL> urls = new LinkedHashSet<>();
 
     if (contextClass != null) {
       CollectionUtils.addAll(urls, contextClass.getClassLoader().getResources(name));
@@ -347,21 +353,21 @@ public class ClassPathLoader {
   }
 
   /**
-   * Wrap this {@link ClassPathLoader} with a {@link ClassLoader} facade.
+   * Wrap this {@code ClassPathLoader} with a {@code ClassLoader} facade.
    *
-   * @return {@link ClassLoader} facade.
+   * @return a ClassLoader facade.
    * @since GemFire 8.1
    */
   public ClassLoader asClassLoader() {
     return new ClassLoader() {
       @Override
       public Class<?> loadClass(String name) throws ClassNotFoundException {
-        return ClassPathLoader.this.forName(name);
+        return forName(name);
       }
 
       @Override
       protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        return ClassPathLoader.this.forName(name);
+        return forName(name);
       }
 
       @Override
@@ -393,9 +399,9 @@ public class ClassPathLoader {
   }
 
   /**
-   * Helper method equivalent to <code>ClassPathLoader.getLatest().asClassLoader();</code>.
+   * Helper method equivalent to {@code ClassPathLoader.getLatest().asClassLoader();}.
    *
-   * @return {@link ClassLoader} for current {@link ClassPathLoader}.
+   * @return a ClassLoader for current ClassPathLoader.
    * @since GemFire 8.1
    */
   public static ClassLoader getLatestAsClassLoader() {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AdminConsoleMessage.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AdminConsoleMessage.java
index eb876fc..10ad1cd 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AdminConsoleMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AdminConsoleMessage.java
@@ -18,10 +18,10 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.PooledDistributionMessage;
 import org.apache.geode.internal.admin.Alert;
-import org.apache.geode.internal.alerting.AlertLevel;
 import org.apache.geode.internal.serialization.DeserializationContext;
 import org.apache.geode.internal.serialization.SerializationContext;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertLevelChangeMessage.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertLevelChangeMessage.java
index 21d8ee2..245acd1 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertLevelChangeMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertLevelChangeMessage.java
@@ -20,9 +20,9 @@ import java.io.IOException;
 
 import org.apache.logging.log4j.Logger;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.SerialDistributionMessage;
-import org.apache.geode.internal.alerting.AlertLevel;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.serialization.DeserializationContext;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java
index 7e861ff..2207a19 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/AlertListenerMessage.java
@@ -17,6 +17,7 @@ package org.apache.geode.internal.admin.remote;
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
+import java.time.Instant;
 import java.util.Date;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -56,13 +57,14 @@ public class AlertListenerMessage extends PooledDistributionMessage implements A
   private String message;
   private String exceptionText;
 
-  public static AlertListenerMessage create(DistributedMember recipient, int alertLevel, Date date,
+  public static AlertListenerMessage create(DistributedMember recipient, int alertLevel,
+      Instant timestamp,
       String connectionName, String threadName, long threadId, String message,
       String exceptionText) {
     AlertListenerMessage alertListenerMessage = new AlertListenerMessage();
     alertListenerMessage.setRecipient((InternalDistributedMember) recipient);
     alertListenerMessage.alertLevel = alertLevel;
-    alertListenerMessage.date = date;
+    alertListenerMessage.date = new Date(timestamp.toEpochMilli());
     alertListenerMessage.connectionName = connectionName;
     if (alertListenerMessage.connectionName == null) {
       alertListenerMessage.connectionName = "";
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/RemoteAlert.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/RemoteAlert.java
index 452cf9b..4be06f8 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/RemoteAlert.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/RemoteAlert.java
@@ -26,7 +26,7 @@ import org.apache.geode.internal.admin.Alert;
 import org.apache.geode.internal.admin.GemFireVM;
 import org.apache.geode.internal.logging.DateFormatter;
 import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 
 /**
  * Implementation of the Alert interface.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/TailLogResponse.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/TailLogResponse.java
index e189c03..44578d2 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/TailLogResponse.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/TailLogResponse.java
@@ -27,10 +27,10 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.serialization.DeserializationContext;
 import org.apache.geode.internal.serialization.SerializationContext;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 public class TailLogResponse extends AdminResponse {
   private static final Logger logger = LogService.getLogger();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProviderRegistry.java b/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProviderRegistry.java
deleted file mode 100644
index f258350..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingProviderRegistry.java
+++ /dev/null
@@ -1,84 +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.alerting;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.geode.annotations.Immutable;
-import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.annotations.internal.MakeNotStatic;
-
-/**
- * Provides publication of {@code AlertingProvider} that may be initiated by a third party logging
- * library such as Log4J2.
- *
- * <p>
- * This mechanism is used instead of a manifest-based {@code ServiceLoader} so that
- * {@code AlertAppender} is registered only if Log4J2 creates it.
- */
-public class AlertingProviderRegistry {
-
-  @Immutable
-  private static final AlertingProvider NULL_ALERTING_PROVIDER = new NullAlertingProvider();
-
-  @MakeNotStatic
-  private static final AlertingProviderRegistry INSTANCE = new AlertingProviderRegistry();
-
-  public static AlertingProviderRegistry get() {
-    return INSTANCE;
-  }
-
-  @VisibleForTesting
-  public static AlertingProvider getNullAlertingProvider() {
-    return NULL_ALERTING_PROVIDER;
-  }
-
-  private final AlertingSessionListeners alertingSessionListeners;
-  private final AtomicReference<AlertingProvider> alertingProviderRef = new AtomicReference<>();
-
-  AlertingProviderRegistry() {
-    this(AlertingSessionListeners.get(), NULL_ALERTING_PROVIDER);
-  }
-
-  private AlertingProviderRegistry(final AlertingSessionListeners alertingSessionListeners,
-      final AlertingProvider alertingProvider) {
-    if (alertingSessionListeners == null) {
-      throw new NullPointerException("alertingSessionListeners must not be null");
-    }
-    if (alertingProvider == null) {
-      throw new NullPointerException("alertingProvider must not be null");
-    }
-    this.alertingSessionListeners = alertingSessionListeners;
-    alertingProviderRef.set(alertingProvider);
-  }
-
-  public AlertingProvider getAlertingProvider() {
-    return alertingProviderRef.get();
-  }
-
-  public void registerAlertingProvider(final AlertingProvider provider) {
-    alertingSessionListeners.addAlertingSessionListener(provider);
-    alertingProviderRef.compareAndSet(NULL_ALERTING_PROVIDER, provider);
-  }
-
-  public void unregisterAlertingProvider(final AlertingProvider provider) {
-    alertingProviderRef.compareAndSet(provider, NULL_ALERTING_PROVIDER);
-    alertingSessionListeners.removeAlertingSessionListener(provider);
-  }
-
-  public void clear() {
-    unregisterAlertingProvider(alertingProviderRef.get());
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingService.java b/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingService.java
deleted file mode 100644
index 5b75c14..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingService.java
+++ /dev/null
@@ -1,57 +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.alerting;
-
-
-import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.distributed.DistributedMember;
-
-/**
- * Adds and removes {@code AlertListeners} for local and remote members that need to receive
- * notification of system {@code Alerts}.
- *
- * <p>
- * The {@code AlertingService} looks up the registered {@code AlertingProvider} from
- * {@code AlertingProviderRegistry} and delegates all calls to that provider.
- */
-public class AlertingService {
-
-  private final AlertingProviderRegistry providerRegistry;
-
-  public AlertingService() {
-    this(AlertingProviderRegistry.get());
-  }
-
-  AlertingService(final AlertingProviderRegistry providerRegistry) {
-    this.providerRegistry = providerRegistry;
-  }
-
-  public void addAlertListener(final DistributedMember member, final AlertLevel alertLevel) {
-    providerRegistry.getAlertingProvider().addAlertListener(member, alertLevel);
-  }
-
-  public boolean removeAlertListener(final DistributedMember member) {
-    return providerRegistry.getAlertingProvider().removeAlertListener(member);
-  }
-
-  public boolean hasAlertListener(final DistributedMember member, final AlertLevel alertLevel) {
-    return providerRegistry.getAlertingProvider().hasAlertListener(member, alertLevel);
-  }
-
-  @VisibleForTesting
-  AlertingProviderRegistry getAlertingProviderRegistry() {
-    return providerRegistry;
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingService.java b/geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingService.java
deleted file mode 100644
index 1855f85..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/NullAlertingService.java
+++ /dev/null
@@ -1,50 +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.alerting;
-
-import org.apache.geode.annotations.Immutable;
-import org.apache.geode.distributed.DistributedMember;
-
-/**
- * Null implementation of {@link AlertingService} that does nothing.
- */
-public class NullAlertingService extends AlertingService {
-
-  @Immutable
-  private static final NullAlertingService INSTANCE = new NullAlertingService();
-
-  public static NullAlertingService get() {
-    return INSTANCE;
-  }
-
-  public NullAlertingService() {
-    // nothing
-  }
-
-  @Override
-  public void addAlertListener(final DistributedMember member, final AlertLevel alertLevel) {
-    // nothing
-  }
-
-  @Override
-  public boolean removeAlertListener(final DistributedMember member) {
-    return false;
-  }
-
-  @Override
-  public boolean hasAlertListener(final DistributedMember member, final AlertLevel alertLevel) {
-    return false;
-  }
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java b/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesCollection.java
similarity index 75%
rename from geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
rename to geode-core/src/main/java/org/apache/geode/internal/cache/EntriesCollection.java
index 3e9a831..3d55dd8 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/alerting/AlertingSessionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesCollection.java
@@ -12,16 +12,12 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.internal.cache;
+
+import org.apache.geode.cache.Region;
 
 /**
- * Defines the lifecycle callbacks of an {@code AlertingSession}.
+ * Collection of data entries in a data structure such as a {@link Region}.
  */
-public interface AlertingSessionListener {
-
-  void createSession(final AlertMessaging alertMessaging);
-
-  void startSession();
-
-  void stopSession();
+public interface EntriesCollection {
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesSet.java b/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesSet.java
index c0c6704..18e3a3e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesSet.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/EntriesSet.java
@@ -28,7 +28,7 @@ import org.apache.geode.internal.cache.LocalRegion.IteratorType;
 import org.apache.geode.internal.cache.entries.AbstractRegionEntry;
 
 /** Set view of entries */
-public class EntriesSet extends AbstractSet {
+public class EntriesSet extends AbstractSet implements EntriesCollection {
 
   final LocalRegion topRegion;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
index 2ad697d..dd41a08 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/xmlcache/CacheCreation.java
@@ -16,8 +16,8 @@ package org.apache.geode.internal.cache.xmlcache;
 
 import static java.lang.String.format;
 import static org.apache.geode.internal.logging.LogWriterFactory.toSecurityLogWriter;
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
 import static org.apache.geode.internal.statistics.StatisticsClockFactory.disabledClock;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/jta/TransactionUtils.java b/geode-core/src/main/java/org/apache/geode/internal/jta/TransactionUtils.java
index 59c2504..32b6c48 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/jta/TransactionUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/jta/TransactionUtils.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.internal.jta;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.SEVERE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.SEVERE;
 
 import org.apache.geode.LogWriter;
 import org.apache.geode.annotations.internal.MakeNotStatic;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/Banner.java b/geode-core/src/main/java/org/apache/geode/internal/logging/Banner.java
index 83804b5..514bb67 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/Banner.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/Banner.java
@@ -46,6 +46,7 @@ import org.apache.geode.internal.OSProcess;
 import org.apache.geode.internal.VersionDescription;
 import org.apache.geode.internal.serialization.Version;
 import org.apache.geode.internal.util.ArgumentRedactor;
+import org.apache.geode.logging.internal.ConfigurationInfo;
 
 /**
  * Utility class to print banner information at manager startup.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/DateFormatter.java b/geode-core/src/main/java/org/apache/geode/internal/logging/DateFormatter.java
index 330646e..a8277ea 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/DateFormatter.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/DateFormatter.java
@@ -1,16 +1,18 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/DefaultProviderChecker.java b/geode-core/src/main/java/org/apache/geode/internal/logging/DefaultProviderChecker.java
deleted file mode 100644
index fae6390..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/DefaultProviderChecker.java
+++ /dev/null
@@ -1,82 +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 java.util.function.Function;
-import java.util.function.Supplier;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.status.StatusLogger;
-
-import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.internal.ClassPathLoader;
-import org.apache.geode.internal.logging.ProviderAgentLoader.AvailabilityChecker;
-
-class DefaultProviderChecker implements AvailabilityChecker {
-
-  /**
-   * The default {@code ProviderAgent} is {@code Log4jAgent}.
-   */
-  static final String DEFAULT_PROVIDER_AGENT_NAME =
-      "org.apache.geode.internal.logging.log4j.Log4jAgent";
-
-  static final String DEFAULT_PROVIDER_CLASS_NAME =
-      "org.apache.logging.log4j.core.impl.Log4jContextFactory";
-
-  private final Supplier<Class> contextFactoryClassSupplier;
-  private final Function<String, Boolean> isClassLoadableFunction;
-  private final Logger logger;
-
-  DefaultProviderChecker() {
-    this(() -> LogManager.getFactory().getClass(), DefaultProviderChecker::isClassLoadable,
-        StatusLogger.getLogger());
-  }
-
-  @VisibleForTesting
-  DefaultProviderChecker(Supplier<Class> contextFactoryClassSupplier,
-      Function<String, Boolean> isClassLoadableFunction,
-      Logger logger) {
-    this.contextFactoryClassSupplier = contextFactoryClassSupplier;
-    this.isClassLoadableFunction = isClassLoadableFunction;
-    this.logger = logger;
-  }
-
-  @Override
-  public boolean isAvailable() {
-    if (!isClassLoadableFunction.apply(DEFAULT_PROVIDER_CLASS_NAME)) {
-      logger.info("Unable to find Log4j Core.");
-      return false;
-    }
-
-    boolean usingLog4jProvider =
-        DEFAULT_PROVIDER_CLASS_NAME.equals(contextFactoryClassSupplier.get().getName());
-    String message = "Log4j Core is available "
-        + (usingLog4jProvider ? "and using" : "but not using") + " Log4jProvider.";
-    logger.info(message);
-    return usingLog4jProvider;
-  }
-
-  @VisibleForTesting
-  static boolean isClassLoadable(String className) {
-    try {
-      ClassPathLoader.getLatest().forName(className);
-      return true;
-    } catch (ClassNotFoundException e) {
-      return false;
-    }
-  }
-
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireFormatter.java b/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireFormatter.java
index e2eac93..eba21aa 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireFormatter.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireFormatter.java
@@ -22,6 +22,7 @@ import java.util.Date;
 import java.util.logging.Formatter;
 import java.util.logging.LogRecord;
 
+
 /**
  * Implementation of the standard JDK formatter that formats a message in GemFire's log format.
  */
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireHandler.java b/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireHandler.java
index 3766c74..eb5b069 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/GemFireHandler.java
@@ -20,7 +20,7 @@ import java.util.logging.LogRecord;
 
 import org.apache.geode.GemFireException;
 import org.apache.geode.LogWriter;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.log4j.LogWriterLogger;
 
 /**
  * Implementation of the standard JDK handler that publishes a log record to a LogWriterImpl. Note
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileParser.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileParser.java
index aa2db56..729f3ac 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileParser.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileParser.java
@@ -15,7 +15,7 @@
 package org.apache.geode.internal.logging;
 
 import static org.apache.commons.lang3.SystemUtils.LINE_SEPARATOR;
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
 
 import java.io.BufferedReader;
 import java.io.FileReader;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogService.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LogService.java
index fe428d8..a543634 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LogService.java
@@ -18,37 +18,19 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.util.StackLocator;
 
-import org.apache.geode.cache.Region;
-import org.apache.geode.internal.cache.EntriesSet;
-import org.apache.geode.internal.logging.log4j.FastLogger;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
-import org.apache.geode.internal.logging.log4j.message.GemFireParameterizedMessage;
-import org.apache.geode.internal.logging.log4j.message.GemFireParameterizedMessageFactory;
+import org.apache.geode.annotations.Immutable;
+import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.logging.internal.LoggingProviderLoader;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 
 /**
  * Provides Log4J2 Loggers with customized optimizations for Geode:
- *
- * <p>
- * Returned Logger is wrapped inside an instance of {@link FastLogger} which skips expensive
- * filtering, debug and trace handling with a volatile boolean. This optimization is turned on only
- * when using the default Geode {@code log4j2.xml} by checking for the existence of this property:
- *
- * <pre>
- * &lt;Property name="geode-default"&gt;true&lt;/Property&gt;
- * </pre>
- *
- * <p>
- * Returned Logger uses {@link GemFireParameterizedMessageFactory} to create
- * {@link GemFireParameterizedMessage} which excludes {@link Region}s from being handled as a
- * {@code Map} and {@link EntriesSet} from being handled as a {@code Collection}. Without this
- * change, using a {@code Region} or {@code EntriesSet} in a log statement can result in an
- * expensive operation or even a hang in the case of a {@code PartitionedRegion}.
- *
- * <p>
- * {@code LogService} only uses Log4J2 API so that any logging backend may be used.
  */
 public class LogService extends LogManager {
 
+  @Immutable
+  private static final LoggingProvider loggingProvider = new LoggingProviderLoader().load();
+
   private LogService() {
     // do not instantiate
   }
@@ -60,26 +42,15 @@ public class LogService extends LogManager {
    */
   public static Logger getLogger() {
     String name = StackLocator.getInstance().getCallerClass(2).getName();
-    return new FastLogger(
-        LogManager.getLogger(name, GemFireParameterizedMessageFactory.INSTANCE));
+    return loggingProvider.getLogger(name);
   }
 
-  public static Logger getLogger(final String name) {
-    return new FastLogger(LogManager.getLogger(name, GemFireParameterizedMessageFactory.INSTANCE));
+  public static Logger getLogger(String name) {
+    return loggingProvider.getLogger(name);
   }
 
-  /**
-   * Returns a LogWriterLogger that is decorated with the LogWriter and LogWriterI18n methods.
-   *
-   * <p>
-   * This is the bridge to LogWriter and LogWriterI18n that we need to eventually stop using in
-   * phase 1. We will switch over from a shared LogWriterLogger instance to having every GemFire
-   * class own its own private static GemFireLogger
-   *
-   * @return The LogWriterLogger for the calling class.
-   */
-  public static LogWriterLogger createLogWriterLogger(final String name,
-      final String connectionName, final boolean isSecure) {
-    return LogWriterLogger.create(name, connectionName, isSecure);
+  @VisibleForTesting
+  static LoggingProvider getLoggingProvider() {
+    return loggingProvider;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterFactory.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterFactory.java
index 3badc4c..b8a7381 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterFactory.java
@@ -14,10 +14,11 @@
  */
 package org.apache.geode.internal.logging;
 
-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.logging.internal.spi.LoggingProvider.MAIN_LOGGER_NAME;
+import static org.apache.geode.logging.internal.spi.LoggingProvider.SECURITY_LOGGER_NAME;
 
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.spi.LogConfig;
 
 /**
  * Factory for creating {@link LogWriterLogger}s.
@@ -34,7 +35,7 @@ public class LogWriterFactory {
   public static InternalLogWriter createLogWriterLogger(final LogConfig logConfig,
       final boolean secure) {
     String name = secure ? SECURITY_LOGGER_NAME : MAIN_LOGGER_NAME;
-    return LogService.createLogWriterLogger(name, logConfig.getName(), secure);
+    return createLogWriterLogger(name, logConfig.getName(), secure);
   }
 
   /**
@@ -43,4 +44,19 @@ public class LogWriterFactory {
   public static InternalLogWriter toSecurityLogWriter(final InternalLogWriter logWriter) {
     return new SecurityLogWriter(logWriter.getLogWriterLevel(), logWriter);
   }
+
+  /**
+   * Returns a LogWriterLogger that is decorated with the LogWriter and LogWriterI18n methods.
+   *
+   * <p>
+   * This is the bridge to LogWriter and LogWriterI18n that we need to eventually stop using in
+   * phase 1. We will switch over from a shared LogWriterLogger instance to having every GemFire
+   * class own its own private static GemFireLogger
+   *
+   * @return The LogWriterLogger for the calling class.
+   */
+  public static LogWriterLogger createLogWriterLogger(final String name,
+      final String connectionName, final boolean isSecure) {
+    return LogWriterLogger.create(name, connectionName, isSecure);
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingExecutors.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingExecutors.java
index 5f206ae..456e118 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingExecutors.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingExecutors.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThread.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThread.java
index 3c89a5b..6fe27d1 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThread.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThread.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadFactory.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadFactory.java
index a9967a3..b376fed 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadFactory.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadGroup.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadGroup.java
index 8661c07..516ccdf 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadGroup.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingThreadGroup.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.internal.logging;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
 
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandler.java b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandler.java
index 3a16840..f1d7147 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandler.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriter.java b/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriter.java
index 95559a6..326b2d1 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriter.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriter.java
@@ -27,10 +27,12 @@ import org.apache.geode.internal.OSProcess;
 import org.apache.geode.internal.io.MainWithChildrenRollingFileHandler;
 import org.apache.geode.internal.io.RollingFileHandler;
 import org.apache.geode.internal.util.LogFileUtils;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogFileDetails;
 
 /**
- * Implementation of {@link LogWriter} for distributed system members. It's just like
- * {@link LocalLogWriter} except it has support for rolling and alerts.
+ * Implementation of {@link LogWriter} for distributed system members. It's just like {@link
+ * org.apache.geode.internal.logging.LocalLogWriter} except it has support for rolling and alerts.
  *
  * @since Geode 1.0
  */
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriterFactory.java b/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriterFactory.java
index 5f7bcd2..976e7e5 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriterFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/ManagerLogWriterFactory.java
@@ -31,6 +31,7 @@ import org.apache.geode.internal.OSProcess;
 import org.apache.geode.internal.process.ProcessLauncherContext;
 import org.apache.geode.internal.statistics.StatisticsConfig;
 import org.apache.geode.internal.util.LogFileUtils;
+import org.apache.geode.logging.internal.spi.LogConfig;
 
 /**
  * Factory for creating a {@link ManagerLogWriter}.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgentLoader.java b/geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgentLoader.java
deleted file mode 100644
index 0671f3b..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgentLoader.java
+++ /dev/null
@@ -1,135 +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.lang.SystemPropertyHelper.GEODE_PREFIX;
-import static org.apache.geode.internal.logging.DefaultProviderChecker.DEFAULT_PROVIDER_AGENT_NAME;
-
-import java.util.ServiceLoader;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.status.StatusLogger;
-
-import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.internal.ClassPathLoader;
-
-/**
- * Loads a {@link ProviderAgent} using this order of preference:
- *
- * <pre>
- * 1. {@code META-INF/services/org.apache.geode.internal.logging.ProviderAgent} if found
- * 2. System Property {@code geode.PROVIDER_AGENT_NAME} if specified
- * 3. {@code org.apache.geode.internal.logging.log4j.Log4jAgent} if
- * {@code org.apache.logging.log4j.core.Logger} can be class loaded
- * 4. The no-op implementation {@code NullProviderAgent} as last resort
- * </pre>
- *
- * <p>
- * TODO: extract logging.log4j package to geode-logging module and use ServiceLoader only
- */
-public class ProviderAgentLoader {
-
-  private static final Logger LOGGER = StatusLogger.getLogger();
-
-  /**
-   * System property that may be used to override which {@code ProviderAgent} to use.
-   */
-  static final String PROVIDER_AGENT_NAME_PROPERTY = GEODE_PREFIX + "PROVIDER_AGENT_NAME";
-
-  private final AvailabilityChecker availabilityChecker;
-
-  public ProviderAgentLoader() {
-    this(new DefaultProviderChecker());
-  }
-
-  @VisibleForTesting
-  ProviderAgentLoader(final AvailabilityChecker availabilityChecker) {
-    this.availabilityChecker = availabilityChecker;
-  }
-
-  /**
-   * Returns true if the default provider {@code Log4j Core} is available.
-   */
-  public boolean isDefaultAvailable() {
-    return availabilityChecker.isAvailable();
-  }
-
-  public ProviderAgent findProviderAgent() {
-    ServiceLoader<ProviderAgent> serviceLoaderFromExt =
-        ServiceLoader.loadInstalled(ProviderAgent.class);
-    if (serviceLoaderFromExt.iterator().hasNext()) {
-      ProviderAgent providerAgent = serviceLoaderFromExt.iterator().next();
-      LOGGER.info("Using {} from Extension ClassLoader for service {}",
-          providerAgent.getClass().getName(), ProviderAgent.class.getName());
-      return providerAgent;
-    }
-
-    ServiceLoader<ProviderAgent> serviceLoaderFromTccl = ServiceLoader.load(ProviderAgent.class);
-    if (serviceLoaderFromTccl.iterator().hasNext()) {
-      ProviderAgent providerAgent = serviceLoaderFromTccl.iterator().next();
-      LOGGER.info("Using {} from Thread Context ClassLoader for service {}",
-          providerAgent.getClass().getName(), ProviderAgent.class.getName());
-      return providerAgent;
-    }
-
-    ServiceLoader<ProviderAgent> serviceLoaderFromSys =
-        ServiceLoader.load(ProviderAgent.class, null);
-    if (serviceLoaderFromSys.iterator().hasNext()) {
-      ProviderAgent providerAgent = serviceLoaderFromSys.iterator().next();
-      LOGGER.info("Using {} from System ClassLoader for service {}",
-          providerAgent.getClass().getName(), ProviderAgent.class.getName());
-      return providerAgent;
-    }
-
-    return createProviderAgent();
-  }
-
-  ProviderAgent createProviderAgent() {
-    if (System.getProperty(PROVIDER_AGENT_NAME_PROPERTY) == null && !isDefaultAvailable()) {
-      return new NullProviderAgent();
-    }
-
-    String agentClassName =
-        System.getProperty(PROVIDER_AGENT_NAME_PROPERTY, DEFAULT_PROVIDER_AGENT_NAME);
-    try {
-      Class<? extends ProviderAgent> agentClass =
-          ClassPathLoader.getLatest().forName(agentClassName).asSubclass(ProviderAgent.class);
-
-      ProviderAgent providerAgent = agentClass.newInstance();
-      if (DEFAULT_PROVIDER_AGENT_NAME.equals(providerAgent.getClass().getName())) {
-        LOGGER.info("Using {} by default for service {}", providerAgent.getClass().getName(),
-            ProviderAgent.class.getName());
-      } else {
-        LOGGER.info("Using {} from System Property {} for service {}",
-            providerAgent.getClass().getName(), PROVIDER_AGENT_NAME_PROPERTY,
-            ProviderAgent.class.getName());
-      }
-
-      return providerAgent;
-
-    } catch (ClassNotFoundException | ClassCastException | InstantiationException
-        | IllegalAccessException e) {
-      LOGGER.warn("Unable to create ProviderAgent of type {}", agentClassName, e);
-    }
-    LOGGER.info("Using {} for service {}", NullProviderAgent.class.getName(),
-        PROVIDER_AGENT_NAME_PROPERTY, ProviderAgent.class.getName());
-    return new NullProviderAgent();
-  }
-
-  interface AvailabilityChecker {
-    boolean isAvailable();
-  }
-
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityLogConfig.java b/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityLogConfig.java
index 661f766..9663b90 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityLogConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityLogConfig.java
@@ -16,6 +16,8 @@ package org.apache.geode.internal.logging;
 
 import java.io.File;
 
+import org.apache.geode.logging.internal.spi.LogConfig;
+
 /**
  * Wraps a {@link LogConfig} and overrides configuration for Security.
  */
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityManagerLogWriter.java b/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityManagerLogWriter.java
index ff69595..7d8cbb6 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityManagerLogWriter.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/SecurityManagerLogWriter.java
@@ -16,6 +16,8 @@ package org.apache.geode.internal.logging;
 
 import java.io.PrintStream;
 
+import org.apache.geode.logging.internal.spi.LogConfig;
+
 /**
  * A log writer for security related logs. This will prefix all messages with "security-" in the
  * level part of log-line for easy recognition and filtering if required. Intended usage is in all
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/SortLogFile.java b/geode-core/src/main/java/org/apache/geode/internal/logging/SortLogFile.java
index c2cb9f1..e3fe038 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/SortLogFile.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/logging/SortLogFile.java
@@ -38,7 +38,6 @@ import org.apache.geode.internal.ExitCode;
  *
  * @see MergeLogFiles
  * @see LogFileParser
- *
  * @since GemFire 3.0
  */
 public class SortLogFile {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/PausableAppender.java b/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/PausableAppender.java
deleted file mode 100644
index 6321821..0000000
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/PausableAppender.java
+++ /dev/null
@@ -1,26 +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;
-
-public interface PausableAppender {
-
-  void pause();
-
-  void resume();
-
-  boolean isPaused();
-}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
index 8c4b285..88da99a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/security/IntegratedSecurityService.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.internal.security;
 
-import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.logging.internal.spi.LoggingProvider.SECURITY_LOGGER_NAME;
 
 import java.io.IOException;
 import java.security.AccessController;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/SecurityManagerProvider.java b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/SecurityManagerProvider.java
index e0d9eac..f329291 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/security/shiro/SecurityManagerProvider.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/security/shiro/SecurityManagerProvider.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.internal.security.shiro;
 
-import static org.apache.geode.internal.logging.Configuration.SECURITY_LOGGER_NAME;
+import static org.apache.geode.logging.internal.spi.LoggingProvider.SECURITY_LOGGER_NAME;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.shiro.SecurityUtils;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/GemFireStatSampler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/GemFireStatSampler.java
index 47e2a8c..8a2fbaf 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/GemFireStatSampler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/GemFireStatSampler.java
@@ -34,11 +34,11 @@ import org.apache.geode.distributed.internal.membership.InternalDistributedMembe
 import org.apache.geode.internal.GemFireVersion;
 import org.apache.geode.internal.admin.ListenerIdMap;
 import org.apache.geode.internal.admin.remote.StatListenerMessage;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LogMarker;
 import org.apache.geode.internal.statistics.platform.OsStatisticsFactory;
 import org.apache.geode.internal.statistics.platform.ProcessStats;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * GemFireStatSampler adds listeners and rolling archives to HostStatSampler.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
index 82d5a86..7ac5683 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java
@@ -29,7 +29,6 @@ import org.apache.geode.SystemFailure;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.internal.NanoTimer;
 import org.apache.geode.internal.io.MainWithChildrenRollingFileHandler;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.logging.log4j.LogMarker;
@@ -37,6 +36,7 @@ import org.apache.geode.internal.net.SocketCreator;
 import org.apache.geode.internal.process.UncheckedPidUnavailableException;
 import org.apache.geode.internal.statistics.platform.OsStatisticsFactory;
 import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * HostStatSampler implements a thread which will monitor, sample, and archive statistics. It only
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
index 8142eb5..d79e82c 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandler.java
@@ -27,10 +27,10 @@ import org.apache.geode.GemFireIOException;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.internal.io.RollingFileHandler;
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.log4j.LogMarker;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.log4j.LogWriterLogger;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * Extracted from {@link HostStatSampler} and {@link GemFireStatSampler}.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandlerConfig.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandlerConfig.java
index 25abe8e..2c581f2 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandlerConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveHandlerConfig.java
@@ -17,7 +17,7 @@ package org.apache.geode.internal.statistics;
 import java.io.File;
 import java.util.Optional;
 
-import org.apache.geode.internal.logging.LogFile;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * Defines the contract enabling the {@link StatArchiveHandler} to retrieve configuration details
diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatisticsConfig.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatisticsConfig.java
index f1996ec..0c2b731 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatisticsConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatisticsConfig.java
@@ -26,7 +26,7 @@ public interface StatisticsConfig {
   /**
    * Returns the value of the {@link ConfigurationProperties#STATISTIC_ARCHIVE_FILE} property.
    *
-   * @return <code>null</code> if no file was specified
+   * @return {@code null} if no file was specified
    */
   File getStatisticArchiveFile();
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
index f112dbc..a49893c 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/Connection.java
@@ -46,6 +46,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.geode.CancelException;
 import org.apache.geode.SerializationException;
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 import org.apache.geode.annotations.internal.MutableForTesting;
 import org.apache.geode.cache.CacheClosedException;
@@ -73,7 +74,6 @@ import org.apache.geode.internal.DSFIDFactory;
 import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.SystemTimer;
 import org.apache.geode.internal.SystemTimer.SystemTimerTask;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.net.BufferPool;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/ConnectionTable.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/ConnectionTable.java
index df796a7..b622079 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/ConnectionTable.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/ConnectionTable.java
@@ -35,6 +35,7 @@ import java.util.concurrent.atomic.AtomicReference;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystemDisconnectedException;
@@ -46,7 +47,6 @@ import org.apache.geode.distributed.internal.membership.adapter.GMSMembershipMan
 import org.apache.geode.distributed.internal.membership.gms.api.Membership;
 import org.apache.geode.internal.Assert;
 import org.apache.geode.internal.SystemTimer;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingExecutors;
 import org.apache.geode.internal.net.BufferPool;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
index 699c706..6d7597f 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java
@@ -32,6 +32,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.geode.CancelCriterion;
 import org.apache.geode.CancelException;
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.annotations.internal.MakeNotStatic;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystemDisconnectedException;
@@ -43,7 +44,6 @@ import org.apache.geode.distributed.internal.LonerDistributionManager;
 import org.apache.geode.distributed.internal.direct.DirectChannel;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.MembershipManager;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.logging.log4j.LogMarker;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/util/CollectingServiceLoader.java b/geode-core/src/main/java/org/apache/geode/internal/util/CollectingServiceLoader.java
index 5690e02..acc9e76 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/util/CollectingServiceLoader.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/util/CollectingServiceLoader.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.util;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/util/ListCollectingServiceLoader.java b/geode-core/src/main/java/org/apache/geode/internal/util/ListCollectingServiceLoader.java
index b548677..e06cc0d 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/util/ListCollectingServiceLoader.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/util/ListCollectingServiceLoader.java
@@ -1,18 +1,16 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.util;
 
@@ -23,17 +21,17 @@ import java.util.List;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
 
+import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.internal.logging.LogService;
 
 /**
  * Implements {@link CollectingServiceLoader} by returning a {@link List} of all currently loadable
  * implementations of the given service interface.
  */
 public class ListCollectingServiceLoader<S> implements CollectingServiceLoader<S> {
-  private static final Logger logger = LogService.getLogger();
+  private static final Logger logger = LogManager.getLogger();
 
   private final ServiceLoaderWrapper<S> serviceLoaderWrapper;
 
@@ -65,6 +63,7 @@ public class ListCollectingServiceLoader<S> implements CollectingServiceLoader<S
   }
 
   interface ServiceLoaderWrapper<S> {
+
     void load(Class<S> service);
 
     Iterator<S> iterator() throws ServiceConfigurationError;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/CustomEntryConcurrentHashMap.java b/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/CustomEntryConcurrentHashMap.java
index 1cf64cd..993e97b 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/CustomEntryConcurrentHashMap.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/util/concurrent/CustomEntryConcurrentHashMap.java
@@ -60,7 +60,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.geode.CancelException;
 import org.apache.geode.internal.cache.RegionEntry;
 import org.apache.geode.internal.cache.entries.OffHeapRegionEntry;
-import org.apache.geode.internal.cache.tier.sockets.command.KeySet;
 import org.apache.geode.internal.cache.wan.GatewaySenderEventImpl;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.offheap.OffHeapRegionEntryHelper;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/Configuration.java b/geode-core/src/main/java/org/apache/geode/logging/internal/Configuration.java
similarity index 75%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/Configuration.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/Configuration.java
index 486e8cd..2f6d2df 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/Configuration.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/Configuration.java
@@ -12,17 +12,23 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
-import static org.apache.geode.internal.logging.LogLevelUpdateOccurs.ONLY_WHEN_USING_DEFAULT_CONFIG;
-import static org.apache.geode.internal.logging.LogLevelUpdateScope.GEODE_LOGGERS;
+import static org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs.ONLY_WHEN_USING_DEFAULT_CONFIG;
+import static org.apache.geode.logging.internal.spi.LogLevelUpdateScope.GEODE_LOGGERS;
 
 import org.apache.geode.annotations.VisibleForTesting;
-import org.apache.geode.cache.Cache;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigListener;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateScope;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 
 /**
- * Provides logging configuration by managing a {@link ProviderAgent} for the logging backend.
+ * Provides logging configuration by managing a {@link LoggingProvider} for the logging backend.
  */
 public class Configuration implements LogConfigListener {
 
@@ -43,21 +49,6 @@ public class Configuration implements LogConfigListener {
   public static final String CLI_CONFIG = "/log4j2-cli.xml";
 
   /**
-   * The root name of all Geode loggers.
-   */
-  public static final String GEODE_LOGGER_PREFIX = "org.apache.geode";
-
-  /**
-   * The name of the main Geode logger returned by {@link Cache#getLogger()}.
-   */
-  public static final String MAIN_LOGGER_NAME = GEODE_LOGGER_PREFIX;
-
-  /**
-   * The name of the security Geode logger returned by {@link Cache#getSecurityLogger()}.
-   */
-  public static final String SECURITY_LOGGER_NAME = GEODE_LOGGER_PREFIX + ".security";
-
-  /**
    * System property that may be used to override which {@code LogLevelUpdateOccurs} to use.
    */
   public static final String LOG_LEVEL_UPDATE_OCCURS_PROPERTY =
@@ -72,7 +63,7 @@ public class Configuration implements LogConfigListener {
   private final LogLevelUpdateOccurs logLevelUpdateOccurs;
   private final LogLevelUpdateScope logLevelUpdateScope;
 
-  private final ProviderAgent providerAgent;
+  private final LoggingProvider loggingProvider;
 
   /**
    * Protected by synchronization on Configuration instance.
@@ -80,33 +71,33 @@ public class Configuration implements LogConfigListener {
   private LogConfigSupplier logConfigSupplier;
 
   public static Configuration create() {
-    return create(getLogLevelUpdateOccurs(), getLogLevelUpdateScope(), new ProviderAgentLoader()
-        .findProviderAgent());
+    return create(getLogLevelUpdateOccurs(), getLogLevelUpdateScope(), new LoggingProviderLoader()
+        .load());
   }
 
   @VisibleForTesting
-  public static Configuration create(final ProviderAgent providerAgent) {
-    return create(getLogLevelUpdateOccurs(), getLogLevelUpdateScope(), providerAgent);
+  public static Configuration create(final LoggingProvider loggingProvider) {
+    return create(getLogLevelUpdateOccurs(), getLogLevelUpdateScope(), loggingProvider);
   }
 
   @VisibleForTesting
   public static Configuration create(final LogLevelUpdateOccurs logLevelUpdateOccurs,
       final LogLevelUpdateScope logLevelUpdateScope) {
     return create(logLevelUpdateOccurs, logLevelUpdateScope,
-        new ProviderAgentLoader().findProviderAgent());
+        new LoggingProviderLoader().load());
   }
 
   @VisibleForTesting
   public static Configuration create(final LogLevelUpdateOccurs logLevelUpdateOccurs,
-      final LogLevelUpdateScope logLevelUpdateScope, final ProviderAgent providerAgent) {
-    return new Configuration(logLevelUpdateOccurs, logLevelUpdateScope, providerAgent);
+      final LogLevelUpdateScope logLevelUpdateScope, final LoggingProvider loggingProvider) {
+    return new Configuration(logLevelUpdateOccurs, logLevelUpdateScope, loggingProvider);
   }
 
   private Configuration(final LogLevelUpdateOccurs logLevelUpdateOccurs,
-      final LogLevelUpdateScope logLevelUpdateScope, final ProviderAgent providerAgent) {
+      final LogLevelUpdateScope logLevelUpdateScope, final LoggingProvider loggingProvider) {
     this.logLevelUpdateOccurs = logLevelUpdateOccurs;
     this.logLevelUpdateScope = logLevelUpdateScope;
-    this.providerAgent = providerAgent;
+    this.loggingProvider = loggingProvider;
   }
 
   static LogLevelUpdateOccurs getLogLevelUpdateOccurs() {
@@ -129,7 +120,7 @@ public class Configuration implements LogConfigListener {
 
   /**
    * Initializes logging configuration with the {@code LogConfigSupplier}. This configuration will
-   * register as a {@code LogConfigListener} and configure the {@code ProviderAgent}.
+   * register as a {@code LogConfigListener} and configure the {@code LoggingProvider}.
    */
   public synchronized void initialize(final LogConfigSupplier logConfigSupplier) {
     if (logConfigSupplier == null) {
@@ -149,12 +140,12 @@ public class Configuration implements LogConfigListener {
 
     LogConfig logConfig = logConfigSupplier.getLogConfig();
 
-    providerAgent.configure(logConfig, logLevelUpdateOccurs, logLevelUpdateScope);
+    loggingProvider.configure(logConfig, logLevelUpdateOccurs, logLevelUpdateScope);
   }
 
   /**
    * Removes this configuration as a {@code LogConfigListener} if it's currently registered and
-   * cleans up the {@code ProviderAgent}.
+   * cleans up the {@code LoggingProvider}.
    */
   public synchronized void shutdown() {
     if (logConfigSupplier != null) {
@@ -162,24 +153,24 @@ public class Configuration implements LogConfigListener {
       logConfigSupplier = null;
     }
 
-    providerAgent.cleanup();
+    loggingProvider.cleanup();
   }
 
   String getConfigurationInfo() {
-    return providerAgent.getConfigurationInfo();
+    return loggingProvider.getConfigurationInfo();
   }
 
   void enableLoggingToStandardOutput() {
     LogConfig logConfig = logConfigSupplier.getLogConfig();
     if (logConfig.getLogFile().exists()) {
-      providerAgent.enableLoggingToStandardOutput();
+      loggingProvider.enableLoggingToStandardOutput();
     }
   }
 
   void disableLoggingToStandardOutputIfLoggingToFile() {
     LogConfig logConfig = logConfigSupplier.getLogConfig();
     if (logConfig.getLogFile().exists()) {
-      providerAgent.disableLoggingToStandardOutput();
+      loggingProvider.disableLoggingToStandardOutput();
     }
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/ConfigurationInfo.java b/geode-core/src/main/java/org/apache/geode/logging/internal/ConfigurationInfo.java
similarity index 71%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/ConfigurationInfo.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/ConfigurationInfo.java
index edcc34e..182d36a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/ConfigurationInfo.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/ConfigurationInfo.java
@@ -12,15 +12,17 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
+
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 
 /**
- * Fetches the configuration info from {@link ProviderAgent} for invocation from static context.
- * Note: this may instantiate a new instance of {@link ProviderAgent}.
+ * Fetches the configuration info from {@link LoggingProvider} for invocation from static context.
+ * Note: this may instantiate a new instance of {@link LoggingProvider}.
  */
 public class ConfigurationInfo {
 
   public static String getConfigurationInfo() {
-    return new ProviderAgentLoader().findProviderAgent().getConfigurationInfo();
+    return new LoggingProviderLoader().load().getConfigurationInfo();
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/SessionContext.java b/geode-core/src/main/java/org/apache/geode/logging/internal/InternalSessionContext.java
similarity index 86%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/SessionContext.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/InternalSessionContext.java
index 0a3d8c2..fd13472 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/SessionContext.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/InternalSessionContext.java
@@ -12,20 +12,19 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-public interface SessionContext {
+import org.apache.geode.logging.internal.spi.SessionContext;
 
+public interface InternalSessionContext extends SessionContext {
   State getState();
 
-  LogConfigSupplier getLogConfigSupplier();
-
   enum State {
     CREATED,
     STARTED,
     STOPPED;
 
-    State changeTo(final State newState) {
+    public State changeTo(final State newState) {
       switch (newState) {
         case CREATED:
           if (this != STOPPED) {
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogMessageRegex.java b/geode-core/src/main/java/org/apache/geode/logging/internal/LogMessageRegex.java
similarity index 85%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogMessageRegex.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/LogMessageRegex.java
index adacb58..7daba25 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogMessageRegex.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/LogMessageRegex.java
@@ -12,16 +12,16 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.DATE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.LOG_LEVEL;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MEMBER_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MESSAGE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_ID;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME_ZONE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.DATE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.LOG_LEVEL;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MEMBER_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MESSAGE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_ID;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME_ZONE;
 
 import java.util.regex.Pattern;
 
diff --git a/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingProviderLoader.java b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingProviderLoader.java
new file mode 100644
index 0000000..ebf6228
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingProviderLoader.java
@@ -0,0 +1,104 @@
+/*
+ * 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.logging.internal;
+
+import static org.apache.geode.internal.lang.SystemPropertyHelper.GEODE_PREFIX;
+
+import java.util.Collection;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.internal.ClassPathLoader;
+import org.apache.geode.internal.util.CollectingServiceLoader;
+import org.apache.geode.internal.util.ListCollectingServiceLoader;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
+
+/**
+ * Loads a {@link LoggingProvider} using this order of preference:
+ *
+ * <pre>
+ * 1. System Property {@code geode.LOGGING_PROVIDER_NAME} if specified
+ * 2. {@code META-INF/services/org.apache.geode.logging.internal.spi.LoggingProvider} implementation if found
+ * 3. {@code SimpleLoggingProvider} as last resort
+ * </pre>
+ */
+public class LoggingProviderLoader {
+
+  private static final Logger logger = LogManager.getLogger();
+
+  /**
+   * System property that may be used to override which {@code LoggingProvider} to use.
+   */
+  @VisibleForTesting
+  public static final String LOGGING_PROVIDER_NAME_PROPERTY =
+      GEODE_PREFIX + "LOGGING_PROVIDER_NAME";
+
+  public LoggingProvider load() {
+    // 1: use LOGGING_PROVIDER_NAME_PROPERTY if set
+    LoggingProvider providerFromSystemProperty = checkSystemProperty();
+    if (providerFromSystemProperty != null) {
+      logger.info("Using {} from System Property {} for service {}",
+          providerFromSystemProperty.getClass().getName(), LOGGING_PROVIDER_NAME_PROPERTY,
+          LoggingProvider.class.getName());
+      return providerFromSystemProperty;
+    }
+
+    // 2: use ListCollectingServiceLoader and select highest priority
+    SortedMap<Integer, LoggingProvider> loggingProviders = new TreeMap<>();
+    loadServiceProviders()
+        .forEach(provider -> loggingProviders.put(provider.getPriority(), provider));
+
+    if (!loggingProviders.isEmpty()) {
+      LoggingProvider providerFromServiceLoader = loggingProviders.get(loggingProviders.lastKey());
+      logger.info("Using {} from ServiceLoader for service {}",
+          providerFromServiceLoader.getClass().getName(), LoggingProvider.class.getName());
+      return providerFromServiceLoader;
+    }
+
+    // 3: use SimpleLoggingProvider
+    logger.info("Using {} for service {}", SimpleLoggingProvider.class.getName(),
+        LoggingProvider.class.getName());
+    return new SimpleLoggingProvider();
+  }
+
+  private Iterable<LoggingProvider> loadServiceProviders() {
+    CollectingServiceLoader<LoggingProvider> serviceLoader = new ListCollectingServiceLoader<>();
+    Collection<LoggingProvider> loggingProviders =
+        serviceLoader.loadServices(LoggingProvider.class);
+    return loggingProviders;
+  }
+
+  private LoggingProvider checkSystemProperty() {
+    String agentClassName = System.getProperty(LOGGING_PROVIDER_NAME_PROPERTY);
+    if (agentClassName == null) {
+      return null;
+    }
+
+    try {
+      Class<? extends LoggingProvider> agentClass =
+          ClassPathLoader.getLatest().forName(agentClassName).asSubclass(LoggingProvider.class);
+      return agentClass.newInstance();
+    } catch (ClassNotFoundException | ClassCastException | InstantiationException
+        | IllegalAccessException e) {
+      logger.warn("Unable to create LoggingProvider of type {}", agentClassName, e);
+    }
+
+    return null;
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSession.java b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSession.java
similarity index 69%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSession.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSession.java
index 58aaed1..c057e41 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSession.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSession.java
@@ -12,28 +12,32 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-import static org.apache.geode.internal.logging.Configuration.STARTUP_CONFIGURATION;
-import static org.apache.geode.internal.logging.SessionContext.State.CREATED;
-import static org.apache.geode.internal.logging.SessionContext.State.STARTED;
-import static org.apache.geode.internal.logging.SessionContext.State.STOPPED;
+import static org.apache.geode.logging.internal.Configuration.STARTUP_CONFIGURATION;
+import static org.apache.geode.logging.internal.InternalSessionContext.State.CREATED;
+import static org.apache.geode.logging.internal.InternalSessionContext.State.STARTED;
+import static org.apache.geode.logging.internal.InternalSessionContext.State.STOPPED;
 
 import java.util.Optional;
 
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.annotations.VisibleForTesting;
+import org.apache.geode.internal.logging.Banner;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * Configures the logging {@code Configuration} and provides lifecycle to Geode logging.
  */
-public class LoggingSession implements SessionContext {
+public class LoggingSession implements InternalSessionContext {
 
   private static final Logger logger = LogService.getLogger();
 
   private final Configuration configuration;
-  private final LoggingSessionListeners loggingSessionListeners;
+  private final LoggingSessionNotifier loggingSessionNotifier;
 
   private volatile boolean logBanner;
   private volatile boolean logConfiguration;
@@ -41,19 +45,19 @@ public class LoggingSession implements SessionContext {
   private State state = STOPPED;
 
   public static LoggingSession create() {
-    return create(Configuration.create(), LoggingSessionListeners.get());
+    return create(Configuration.create(), LoggingSessionRegistryProvider.get());
   }
 
   @VisibleForTesting
   static LoggingSession create(final Configuration configuration,
-      final LoggingSessionListeners loggingSessionListeners) {
-    return new LoggingSession(configuration, loggingSessionListeners);
+      final LoggingSessionNotifier loggingSessionNotifier) {
+    return new LoggingSession(configuration, loggingSessionNotifier);
   }
 
   LoggingSession(final Configuration configuration,
-      final LoggingSessionListeners loggingSessionListeners) {
+      final LoggingSessionNotifier loggingSessionNotifier) {
     this.configuration = configuration;
-    this.loggingSessionListeners = loggingSessionListeners;
+    this.loggingSessionNotifier = loggingSessionNotifier;
   }
 
   public synchronized void createSession(final LogConfigSupplier logConfigSupplier) {
@@ -64,7 +68,7 @@ public class LoggingSession implements SessionContext {
       final boolean logBanner, final boolean logConfiguration) {
     configuration.initialize(logConfigSupplier);
     state = state.changeTo(CREATED);
-    loggingSessionListeners.createSession(this);
+    loggingSessionNotifier.createSession(this);
 
     this.logBanner = logBanner;
     this.logConfiguration = logConfiguration;
@@ -75,7 +79,7 @@ public class LoggingSession implements SessionContext {
    */
   public synchronized void startSession() {
     state = state.changeTo(STARTED);
-    loggingSessionListeners.startSession();
+    loggingSessionNotifier.startSession();
     configuration.disableLoggingToStandardOutputIfLoggingToFile();
 
     if (logBanner) {
@@ -90,7 +94,7 @@ public class LoggingSession implements SessionContext {
   public synchronized void stopSession() {
     configuration.enableLoggingToStandardOutput();
     state = state.changeTo(STOPPED);
-    loggingSessionListeners.stopSession();
+    loggingSessionNotifier.stopSession();
   }
 
   public synchronized void shutdown() {
@@ -98,7 +102,7 @@ public class LoggingSession implements SessionContext {
   }
 
   public Optional<LogFile> getLogFile() {
-    return loggingSessionListeners.getLogFile();
+    return loggingSessionNotifier.getLogFile();
   }
 
   @Override
@@ -112,7 +116,7 @@ public class LoggingSession implements SessionContext {
   }
 
   @VisibleForTesting
-  LoggingSessionListeners getLoggingSessionListeners() {
-    return loggingSessionListeners;
+  LoggingSessionNotifier getLoggingSessionNotifier() {
+    return loggingSessionNotifier;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionNotifier.java b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionNotifier.java
new file mode 100644
index 0000000..1101f12
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionNotifier.java
@@ -0,0 +1,49 @@
+/*
+ * 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.logging.internal;
+
+import java.util.Optional;
+
+import org.apache.geode.logging.internal.spi.LogFile;
+import org.apache.geode.logging.internal.spi.LoggingSessionListener;
+import org.apache.geode.logging.internal.spi.SessionContext;
+
+public interface LoggingSessionNotifier {
+
+  /**
+   * Removes all currently registered {@code LoggingSessionListener}s.
+   */
+  void clear();
+
+  /**
+   * Provides {@code createSession} notification to all registered listeners.
+   */
+  void createSession(final SessionContext sessionContext);
+
+  /**
+   * Provides {@code startSession} notification to all registered listeners.
+   */
+  void startSession();
+
+  /**
+   * Provides {@code stopSession} notification to all registered listeners.
+   */
+  void stopSession();
+
+  /**
+   * Returns the system {@link LogFile} from any {@link LoggingSessionListener} that offers it.
+   */
+  Optional<LogFile> getLogFile();
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListeners.java b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionRegistryProvider.java
similarity index 76%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListeners.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionRegistryProvider.java
index d188c81..0bca64e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListeners.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/LoggingSessionRegistryProvider.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import java.util.LinkedHashSet;
 import java.util.Optional;
@@ -20,37 +20,40 @@ import java.util.Set;
 
 import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.annotations.internal.MakeNotStatic;
+import org.apache.geode.logging.internal.spi.LogFile;
+import org.apache.geode.logging.internal.spi.LoggingSessionListener;
+import org.apache.geode.logging.internal.spi.LoggingSessionRegistry;
+import org.apache.geode.logging.internal.spi.SessionContext;
 
-/**
- * Manages registration of {@link LoggingSessionListener}s and provides notifications to them.
- */
-public class LoggingSessionListeners {
+public class LoggingSessionRegistryProvider
+    implements LoggingSessionRegistry, LoggingSessionNotifier {
 
   @MakeNotStatic
-  private static final LoggingSessionListeners INSTANCE = new LoggingSessionListeners();
+  private static final LoggingSessionRegistryProvider INSTANCE =
+      new LoggingSessionRegistryProvider();
 
-  public static LoggingSessionListeners get() {
+  public static LoggingSessionRegistryProvider get() {
     return INSTANCE;
   }
 
   private final Set<LoggingSessionListener> listeners;
 
   @VisibleForTesting
-  LoggingSessionListeners() {
+  LoggingSessionRegistryProvider() {
     listeners = new LinkedHashSet<>();
   }
 
   /**
    * Adds the {@code LoggingSessionListener}.
    */
-  public void addLoggingLifecycleListener(final LoggingSessionListener listener) {
+  public void addLoggingSessionListener(final LoggingSessionListener listener) {
     listeners.add(listener);
   }
 
   /**
    * Removes the {@code LoggingSessionListener}.
    */
-  public void removeLoggingLifecycleListener(final LoggingSessionListener listener) {
+  public void removeLoggingSessionListener(final LoggingSessionListener listener) {
     listeners.remove(listener);
   }
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/NullLogFile.java b/geode-core/src/main/java/org/apache/geode/logging/internal/NullLogFile.java
similarity index 90%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/NullLogFile.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/NullLogFile.java
index db63f69..31edeaf 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/NullLogFile.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/NullLogFile.java
@@ -12,11 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
 import java.io.File;
 
 import org.apache.geode.annotations.Immutable;
+import org.apache.geode.logging.internal.spi.LogFile;
+import org.apache.geode.logging.internal.spi.LogFileDetails;
 
 /**
  * {@link LogFile} with default details of null values.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/NullLoggingSession.java b/geode-core/src/main/java/org/apache/geode/logging/internal/NullLoggingSession.java
similarity index 77%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/NullLoggingSession.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/NullLoggingSession.java
index 4611670..1bea357 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/NullLoggingSession.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/NullLoggingSession.java
@@ -12,7 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
+
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
 
 /**
  * {@link LoggingSession} that does nothing.
@@ -28,20 +30,22 @@ public class NullLoggingSession extends LoggingSession {
   }
 
   @Override
-  public void createSession(final LogConfigSupplier logConfigSupplier) {
+  public synchronized void createSession(LogConfigSupplier logConfigSupplier) {
     // nothing
   }
 
   @Override
-  public void startSession() {
+  public synchronized void startSession() {
     // nothing
   }
 
   @Override
-  public void stopSession() {
+  public synchronized void stopSession() {
     // nothing
   }
 
   @Override
-  public void shutdown() {}
+  public synchronized void shutdown() {
+    // nothing
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java b/geode-core/src/main/java/org/apache/geode/logging/internal/SimpleLoggingProvider.java
similarity index 58%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
copy to geode-core/src/main/java/org/apache/geode/logging/internal/SimpleLoggingProvider.java
index c87e5d3..02cca4e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/SimpleLoggingProvider.java
@@ -12,12 +12,21 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateScope;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 
 /**
- * {@link ProviderAgent} that does nothing.
+ * A {@link LoggingProvider} that does nothing other than delegate to {@code LogManager} for
+ * {@code getLogger()}.
  */
-public class NullProviderAgent implements ProviderAgent {
+public class SimpleLoggingProvider implements LoggingProvider {
 
   @Override
   public void configure(final LogConfig logConfig, final LogLevelUpdateOccurs logLevelUpdateOccurs,
@@ -29,4 +38,14 @@ public class NullProviderAgent implements ProviderAgent {
   public void cleanup() {
     // nothing
   }
+
+  @Override
+  public Logger getLogger(String name) {
+    return LogManager.getLogger(name);
+  }
+
+  @Override
+  public int getPriority() {
+    return Integer.MIN_VALUE;
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/GemFireLogger.java b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/GemFireLogger.java
similarity index 99%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/GemFireLogger.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/log4j/GemFireLogger.java
index 25d128c..e394244 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/GemFireLogger.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/GemFireLogger.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.logging.internal.log4j;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Marker;
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogLevel.java b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogLevel.java
similarity index 98%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogLevel.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogLevel.java
index 1a8d7fd..d6d8eff 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogLevel.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogLevel.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.logging.internal.log4j;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -23,7 +23,7 @@ import java.util.stream.Collectors;
 import org.apache.logging.log4j.Level;
 
 import org.apache.geode.annotations.Immutable;
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 
 /**
  * Provides lookup of any string representation of a logging level to Log4J2 {@code Level} or
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverter.java b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLevelConverter.java
similarity index 79%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverter.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLevelConverter.java
index 0e0b154..0115f38 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverter.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLevelConverter.java
@@ -12,20 +12,21 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.logging.internal.log4j;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
-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.FINEST;
-import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
-import static org.apache.geode.internal.logging.LogWriterLevel.NONE;
-import static org.apache.geode.internal.logging.LogWriterLevel.SEVERE;
-import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ERROR;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINEST;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.NONE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.SEVERE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
 
 import org.apache.logging.log4j.Level;
 
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 
 /**
  * Converts between {@link LogWriterLevel}s and Log4J2 {@code Level}s.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLogger.java b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLogger.java
similarity index 97%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLogger.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLogger.java
index 1fa67da..f8c5c16 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/LogWriterLogger.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/log4j/LogWriterLogger.java
@@ -12,25 +12,15 @@
  * 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.LogWriterLevel.ALL;
-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.INFO;
-import static org.apache.geode.internal.logging.LogWriterLevel.NONE;
-import static org.apache.geode.internal.logging.LogWriterLevel.SEVERE;
-import static org.apache.geode.internal.logging.LogWriterLevel.WARNING;
+package org.apache.geode.logging.internal.log4j;
 
 import java.util.logging.Handler;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.spi.AbstractLogger;
+import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;
 
 import org.apache.geode.LogWriter;
@@ -39,17 +29,16 @@ import org.apache.geode.i18n.LogWriterI18n;
 import org.apache.geode.i18n.StringId;
 import org.apache.geode.internal.logging.GemFireHandler;
 import org.apache.geode.internal.logging.InternalLogWriter;
-import org.apache.geode.internal.logging.LogWriterLevel;
-import org.apache.geode.internal.logging.log4j.message.GemFireParameterizedMessageFactory;
+import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 
 /**
  * Implements GemFireLogger with custom levels while also bridging LogWriter and LogWriterI18n to
  * Log4J.
  */
 @SuppressWarnings("unused")
-public class LogWriterLogger extends FastLogger implements InternalLogWriter, GemFireLogger {
-
-  private static final long serialVersionUID = 446081244292135L;
+public class LogWriterLogger extends ExtendedLoggerWrapper
+    implements InternalLogWriter, GemFireLogger {
 
   public static final String SECURITY_PREFIX = DistributionConfig.SECURITY_PREFIX_NAME;
 
@@ -60,7 +49,7 @@ public class LogWriterLogger extends FastLogger implements InternalLogWriter, Ge
 
   private LogWriterLogger(final Logger logger, final String connectionName,
       final boolean isSecure) {
-    super((AbstractLogger) logger, logger.getName(), logger.getMessageFactory());
+    super((ExtendedLogger) logger, logger.getName(), logger.getMessageFactory());
     logWrapper = this;
     this.connectionName = connectionName;
     loggerName = getName();
@@ -88,7 +77,7 @@ public class LogWriterLogger extends FastLogger implements InternalLogWriter, Ge
    */
   public static LogWriterLogger create(final String name, final String connectionName,
       final boolean isSecure) {
-    Logger wrapped = LogManager.getLogger(name, GemFireParameterizedMessageFactory.INSTANCE);
+    Logger wrapped = LogService.getLogger(name);
     return new LogWriterLogger(wrapped, connectionName, isSecure);
   }
 
@@ -96,6 +85,10 @@ public class LogWriterLogger extends FastLogger implements InternalLogWriter, Ge
     return new LogWriterLogger(logger, null, false);
   }
 
+  public Logger getExtendedLogger() {
+    return logger;
+  }
+
   /**
    * Logs a message with the specific Marker at the {@code Level.TRACE} level.
    *
@@ -1698,21 +1691,21 @@ public class LogWriterLogger extends FastLogger implements InternalLogWriter, Ge
     final Level log4jLevel = logWrapper.getLevel();
 
     if (log4jLevel == Level.OFF) {
-      return NONE.intLevel();
+      return LogWriterLevel.NONE.intLevel();
     } else if (log4jLevel == Level.FATAL) {
-      return SEVERE.intLevel();
+      return LogWriterLevel.SEVERE.intLevel();
     } else if (log4jLevel == Level.ERROR) {
-      return ERROR.intLevel();
+      return LogWriterLevel.ERROR.intLevel();
     } else if (log4jLevel == Level.WARN) {
-      return WARNING.intLevel();
+      return LogWriterLevel.WARNING.intLevel();
     } else if (log4jLevel == Level.INFO) {
-      return INFO.intLevel();
+      return LogWriterLevel.INFO.intLevel();
     } else if (log4jLevel == Level.DEBUG) {
-      return FINE.intLevel();
+      return LogWriterLevel.FINE.intLevel();
     } else if (log4jLevel == Level.TRACE) {
-      return FINER.intLevel();
+      return LogWriterLevel.FINER.intLevel();
     } else if (log4jLevel == Level.ALL) {
-      return ALL.intLevel();
+      return LogWriterLevel.ALL.intLevel();
     }
 
     throw new IllegalStateException(
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfig.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfig.java
similarity index 96%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfig.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfig.java
index 7586b71..2026860 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfig.java
@@ -12,12 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import java.io.File;
 
 import org.apache.geode.distributed.ConfigurationProperties;
 import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.internal.logging.LogWriterImpl;
 
 /**
  * Configuration for logging.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigListener.java
similarity index 95%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
copy to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigListener.java
index da785a6..9d66be6 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigListener.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 /**
  * Listens for logging configuration changes from a {@code LogConfigSupplier}.
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigSupplier.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigSupplier.java
similarity index 96%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigSupplier.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigSupplier.java
index e3ee6e4..e396401 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigSupplier.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogConfigSupplier.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import org.apache.geode.internal.statistics.StatisticsConfig;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFile.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFile.java
similarity index 96%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogFile.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFile.java
index 11461cf..06b7387 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFile.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFile.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import java.io.File;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileDetails.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFileDetails.java
similarity index 95%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogFileDetails.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFileDetails.java
index 319a393..2676971 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogFileDetails.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogFileDetails.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import java.io.File;
 
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateOccurs.java
similarity index 96%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateOccurs.java
index aadc00f..7a1ec81 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateOccurs.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateOccurs.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 /**
  * Controls whether or not log level updates should be triggered. Default is
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateScope.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateScope.java
similarity index 95%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateScope.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateScope.java
index 265f368..86a5fd6 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogLevelUpdateScope.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogLevelUpdateScope.java
@@ -12,7 +12,7 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 /**
  * Controls the scope of which packages of loggers are updated when the log level changes. Default
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterLevel.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogWriterLevel.java
similarity index 95%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterLevel.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogWriterLevel.java
index fdae8e8..4ea4659 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogWriterLevel.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LogWriterLevel.java
@@ -12,9 +12,10 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import org.apache.geode.LogWriter;
+import org.apache.geode.internal.logging.InternalLogWriter;
 
 /**
  * Levels used for identifying the severity of a {@link LogWriter} event. From least specific to
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgent.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingProvider.java
similarity index 68%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgent.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingProvider.java
index da28dbe..9b46959 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/ProviderAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingProvider.java
@@ -12,14 +12,30 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.cache.Cache;
 import org.apache.geode.distributed.ConfigurationProperties;
 
 /**
  * Provides custom configuration of the logging backend for Geode Logging.
  */
-public interface ProviderAgent {
+public interface LoggingProvider {
+
+  /**
+   * The root name of all Geode loggers.
+   */
+  String GEODE_LOGGER_PREFIX = "org.apache.geode";
+  /**
+   * The name of the security Geode logger returned by {@link Cache#getSecurityLogger()}.
+   */
+  String SECURITY_LOGGER_NAME = GEODE_LOGGER_PREFIX + ".security";
+  /**
+   * The name of the main Geode logger returned by {@link Cache#getLogger()}.
+   */
+  String MAIN_LOGGER_NAME = GEODE_LOGGER_PREFIX;
 
   /**
    * Updates the logging backend with any custom configuration. Invoked by Geode during
@@ -36,7 +52,7 @@ public interface ProviderAgent {
   void cleanup();
 
   /**
-   * Returns configuration info to be logged as part of the Geode Logging {@link Banner}. Default
+   * Returns configuration info to be logged as part of the Geode Logging {@code Banner}. Default
    * implementation returns the class name. Geode out-of-box returns the path to the log4j2.xml
    * configuration file.
    */
@@ -66,4 +82,20 @@ public interface ProviderAgent {
   default void enableLoggingToStandardOutput() {
     // override to enable logging to stdout
   }
+
+  /**
+   * Returns a Logger with the specified name.
+   *
+   * @param name The logger name. If null the name of the calling class will be used.
+   * @return The Logger.
+   * @throws UnsupportedOperationException if {@code name} is {@code null} and the calling class
+   *         cannot be determined.
+   */
+  Logger getLogger(String name);
+
+  /**
+   * If multiple {@code LoggingProvider}s are loadable then the instance with the highest priority
+   * or the first iterable element will be used.
+   */
+  int getPriority();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListener.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionListener.java
similarity index 94%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListener.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionListener.java
index 01defa0..3243956 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LoggingSessionListener.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionListener.java
@@ -12,10 +12,12 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 import java.util.Optional;
 
+import org.apache.geode.logging.internal.LoggingSession;
+
 /**
  * Listens for state changes to a {@code LoggingSession}.
  *
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionRegistry.java
similarity index 63%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
rename to geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionRegistry.java
index c87e5d3..944c17e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/NullProviderAgent.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/LoggingSessionRegistry.java
@@ -12,21 +12,20 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
 /**
- * {@link ProviderAgent} that does nothing.
+ * Manages registration of {@link LoggingSessionListener}s and provides notifications to them.
  */
-public class NullProviderAgent implements ProviderAgent {
+public interface LoggingSessionRegistry {
 
-  @Override
-  public void configure(final LogConfig logConfig, final LogLevelUpdateOccurs logLevelUpdateOccurs,
-      final LogLevelUpdateScope logLevelUpdateScope) {
-    // nothing
-  }
+  /**
+   * Adds the {@code LoggingSessionListener}.
+   */
+  void addLoggingSessionListener(final LoggingSessionListener listener);
 
-  @Override
-  public void cleanup() {
-    // nothing
-  }
+  /**
+   * Removes the {@code LoggingSessionListener}.
+   */
+  void removeLoggingSessionListener(final LoggingSessionListener listener);
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/SessionContext.java
similarity index 80%
copy from geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
copy to geode-core/src/main/java/org/apache/geode/logging/internal/spi/SessionContext.java
index da785a6..c12386a 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/LogConfigListener.java
+++ b/geode-core/src/main/java/org/apache/geode/logging/internal/spi/SessionContext.java
@@ -12,12 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal.spi;
 
-/**
- * Listens for logging configuration changes from a {@code LogConfigSupplier}.
- */
-public interface LogConfigListener {
+public interface SessionContext {
 
-  void configChanged();
+  LogConfigSupplier getLogConfigSupplier();
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagerStartupMessage.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagerStartupMessage.java
index bdb5ce0..cdbecf3 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagerStartupMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagerStartupMessage.java
@@ -18,10 +18,10 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.PooledDistributionMessage;
 import org.apache.geode.internal.admin.Alert;
-import org.apache.geode.internal.alerting.AlertLevel;
 import org.apache.geode.internal.serialization.DeserializationContext;
 import org.apache.geode.internal.serialization.SerializationContext;
 
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/MemberMessenger.java b/geode-core/src/main/java/org/apache/geode/management/internal/MemberMessenger.java
index 30a73fd..64af0ea 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/MemberMessenger.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/MemberMessenger.java
@@ -23,7 +23,7 @@ import org.apache.geode.distributed.internal.DistributionMessage;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.admin.remote.AlertLevelChangeMessage;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 
 /**
  * Handles messaging from manager to members for various operations. It sends two types of messages:
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
index 416cf6b..d0dff1d 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
@@ -2,7 +2,7 @@
  * 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
+ * "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
@@ -67,7 +67,6 @@ import org.apache.geode.internal.cache.PartitionedRegion;
 import org.apache.geode.internal.cache.PartitionedRegionStats;
 import org.apache.geode.internal.cache.control.ResourceManagerStats;
 import org.apache.geode.internal.cache.execute.FunctionServiceStats;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingThread;
 import org.apache.geode.internal.logging.log4j.LogMarker;
@@ -84,6 +83,7 @@ import org.apache.geode.internal.statistics.platform.LinuxSystemStats;
 import org.apache.geode.internal.statistics.platform.ProcessStats;
 import org.apache.geode.internal.stats50.VMStats50;
 import org.apache.geode.internal.tcp.ConnectionTable;
+import org.apache.geode.logging.internal.spi.LogFile;
 import org.apache.geode.management.GemFireProperties;
 import org.apache.geode.management.JVMMetrics;
 import org.apache.geode.management.OSMetrics;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRuntimeConfigCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRuntimeConfigCommand.java
index 0b4880a..7106e0b 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRuntimeConfigCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterRuntimeConfigCommand.java
@@ -33,7 +33,7 @@ import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
 import org.apache.geode.internal.cache.xmlcache.CacheXml;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.management.cli.GfshCommand;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
index b1bd2a8..1b8732a 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ChangeLogLevelCommand.java
@@ -31,7 +31,7 @@ import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.cli.CliMetaData;
 import org.apache.geode.management.cli.ConverterHint;
 import org.apache.geode.management.cli.GfshCommand;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsUtils.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsUtils.java
index f9795f0..8c88b79 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsUtils.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/DiskStoreCommandsUtils.java
@@ -14,8 +14,6 @@
  */
 package org.apache.geode.management.internal.cli.commands;
 
-import static org.apache.logging.log4j.core.config.ConfigurationFactory.CONFIGURATION_FILE_PROPERTY;
-
 import java.io.File;
 import java.net.URL;
 import java.util.List;
@@ -28,21 +26,23 @@ import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.logging.Configuration;
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.logging.internal.Configuration;
 import org.apache.geode.management.DistributedSystemMXBean;
 import org.apache.geode.management.internal.cli.CliUtil;
 
 class DiskStoreCommandsUtils {
   private static final Logger logger = LogService.getLogger();
 
+  private static final String LOG4J_CONFIGURATION_FILE_PROPERTY = "log4j.configurationFile";
+
   static void configureLogging(final List<String> commandList) {
-    String configFilePropertyValue = System.getProperty(CONFIGURATION_FILE_PROPERTY);
+    String configFilePropertyValue = System.getProperty(LOG4J_CONFIGURATION_FILE_PROPERTY);
     if (StringUtils.isBlank(configFilePropertyValue)) {
       URL configUrl = LogService.class.getResource(Configuration.CLI_CONFIG);
       configFilePropertyValue = configUrl.toString();
     }
-    commandList.add("-D" + CONFIGURATION_FILE_PROPERTY + "=" + configFilePropertyValue);
+    commandList.add("-D" + LOG4J_CONFIGURATION_FILE_PROPERTY + "=" + configFilePropertyValue);
   }
 
   static String validatedDirectories(String[] diskDirs) {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
index d2218c3..6c8fde5 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ExportLogsInterceptor.java
@@ -25,7 +25,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
 import org.apache.geode.management.internal.cli.GfshParseResult;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunction.java
index 62a1830..3772278 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ChangeLogLevelFunction.java
@@ -27,8 +27,8 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.execute.InternalFunction;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.log4j.LogLevel;
 import org.apache.geode.internal.logging.log4j.LogMarker;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 
 /**
  * Class for change log level function
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
index ceecbed..22213b7 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunction.java
@@ -41,7 +41,7 @@ import org.apache.geode.internal.cache.InternalCacheForClientAccess;
 import org.apache.geode.internal.cache.InternalRegionArguments;
 import org.apache.geode.internal.cache.execute.InternalFunction;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.internal.cli.commands.ExportLogsCommand;
 import org.apache.geode.management.internal.cli.util.ExportLogsCacheWriter;
 import org.apache.geode.management.internal.cli.util.LogExporter;
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
index 46c1104..cbf8c60 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/LogLevelExtractor.java
@@ -24,7 +24,7 @@ import java.util.regex.Pattern;
 import org.apache.logging.log4j.Level;
 
 import org.apache.geode.annotations.Immutable;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 
 /**
  * this will extract convert the deprecated InternalLogWriter's level into log4j level as well.
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ReadWriteFile.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ReadWriteFile.java
index 25b3ef7..1f4fc82 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ReadWriteFile.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/ReadWriteFile.java
@@ -28,7 +28,7 @@ import java.util.List;
 
 import org.apache.geode.cache.execute.FunctionException;
 import org.apache.geode.internal.logging.LogWriterImpl;
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.internal.cli.GfshParser;
 
 /**
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/logging/log4j/log4j2-legacy.xml b/geode-core/src/main/resources/org/apache/geode/internal/logging/log4j/log4j2-legacy.xml
deleted file mode 100644
index 914acc5..0000000
--- a/geode-core/src/main/resources/org/apache/geode/internal/logging/log4j/log4j2-legacy.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j">
-  <Properties>
-    <Property name="geode-pattern">[%level{FATAL=severe,ERROR=error,WARN=warning,INFO=info,DEBUG=fine,TRACE=finest} %date{yyyy/MM/dd HH:mm:ss.SSS z} &lt;%thread&gt; tid=%hexTid] %message%n%throwable%n</Property>
-  </Properties>
-  <Appenders>
-    <Console name="STDOUT" target="SYSTEM_OUT">
-      <PatternLayout pattern="${geode-pattern}"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Logger name="com.gemstone" level="WARN" additivity="true"/>
-    <Logger name="org.apache.geode" level="WARN" additivity="true"/>
-    <Logger name="org.jgroups" level="FATAL" additivity="true"/>
-    <Root level="WARN">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-</Configuration>
diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
index 24cbaec..35737f9 100644
--- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
+++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt
@@ -425,6 +425,7 @@ org/apache/geode/internal/util/concurrent/ReentrantSemaphore,false,holdCount:jav
 org/apache/geode/internal/util/concurrent/StoppableCondition,true,-7091681525970431937,condition:java/util/concurrent/locks/Condition,stopper:org/apache/geode/CancelCriterion
 org/apache/geode/internal/util/concurrent/StoppableReentrantReadWriteLock,true,-1185707921434766946
 org/apache/geode/lang/AttachAPINotFoundException,true,-5953162090462085551
+org/apache/geode/logging/internal/InternalSessionContext$State,false
 org/apache/geode/management/AlreadyRunningException,true,8947734854770335071
 org/apache/geode/management/DependenciesNotFoundException,true,9082304929238159814
 org/apache/geode/management/JVMMetrics,false,committedMemory:long,gcCount:long,gcTimeMillis:long,initMemory:long,maxMemory:long,totalThreads:int,usedMemory:long
diff --git a/geode-core/src/test/java/org/apache/geode/admin/internal/DistributedSystemConfigImplTest.java b/geode-core/src/test/java/org/apache/geode/admin/internal/DistributedSystemConfigImplTest.java
index 0acbede..2e1d206 100644
--- a/geode-core/src/test/java/org/apache/geode/admin/internal/DistributedSystemConfigImplTest.java
+++ b/geode-core/src/test/java/org/apache/geode/admin/internal/DistributedSystemConfigImplTest.java
@@ -20,8 +20,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.LogConfig;
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertLevelTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/AlertLevelTest.java
similarity index 85%
rename from geode-core/src/test/java/org/apache/geode/internal/alerting/AlertLevelTest.java
rename to geode-core/src/test/java/org/apache/geode/alerting/internal/AlertLevelTest.java
index c981550..a7bd724 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertLevelTest.java
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/AlertLevelTest.java
@@ -12,13 +12,13 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
-import static org.apache.geode.internal.alerting.AlertLevel.ERROR;
-import static org.apache.geode.internal.alerting.AlertLevel.NONE;
-import static org.apache.geode.internal.alerting.AlertLevel.SEVERE;
-import static org.apache.geode.internal.alerting.AlertLevel.WARNING;
-import static org.apache.geode.internal.alerting.AlertLevel.find;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.ERROR;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.NONE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.SEVERE;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.WARNING;
+import static org.apache.geode.alerting.internal.spi.AlertLevel.find;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -28,7 +28,8 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 import org.apache.geode.test.junit.categories.AlertingTest;
 
 /**
@@ -44,7 +45,7 @@ public class AlertLevelTest {
 
   @Test
   public void serializes() {
-    AlertLevel logLevel = (AlertLevel) SerializationUtils.clone(NONE);
+    AlertLevel logLevel = SerializationUtils.clone(NONE);
 
     assertThat(logLevel).isEqualTo(NONE).isSameAs(NONE);
   }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertListenerMessageFactoryTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/AlertListenerMessageFactoryTest.java
similarity index 79%
rename from geode-core/src/test/java/org/apache/geode/internal/alerting/AlertListenerMessageFactoryTest.java
rename to geode-core/src/test/java/org/apache/geode/alerting/internal/AlertListenerMessageFactoryTest.java
index 4c875b4..efd77e6 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertListenerMessageFactoryTest.java
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/AlertListenerMessageFactoryTest.java
@@ -12,19 +12,24 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
 import static org.apache.geode.internal.serialization.DataSerializableFixedID.ALERT_LISTENER_MESSAGE;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.catchThrowable;
 import static org.mockito.Mockito.mock;
 
-import java.util.Date;
+import java.time.Instant;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.internal.admin.remote.AlertListenerMessage;
@@ -39,6 +44,9 @@ public class AlertListenerMessageFactoryTest {
   private DistributedMember member;
   private AlertListenerMessageFactory alertListenerMessageFactory;
 
+  @Rule
+  public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
   @Before
   public void setUp() {
     member = mock(InternalDistributedMember.class);
@@ -48,7 +56,8 @@ public class AlertListenerMessageFactoryTest {
   @Test
   public void createAlertListenerMessage() {
     AlertListenerMessage message = alertListenerMessageFactory.createAlertListenerMessage(member,
-        AlertLevel.WARNING, new Date(), "connectionName", "threadName", "formattedMessage", null);
+        AlertLevel.WARNING, Instant.now(), "connectionName", "threadName",
+        Thread.currentThread().getId(), "formattedMessage", null);
 
     assertThat(message).isNotNull();
     assertThat(message.getDSFID()).isEqualTo(ALERT_LISTENER_MESSAGE);
@@ -61,7 +70,8 @@ public class AlertListenerMessageFactoryTest {
 
     Throwable thrown = catchThrowable(
         () -> alertListenerMessageFactory.createAlertListenerMessage(member, AlertLevel.WARNING,
-            new Date(), "connectionName", "threadName", "formattedMessage", null));
+            Instant.now(), "connectionName", "threadName", Thread.currentThread().getId(),
+            "formattedMessage", null));
 
     assertThat(thrown).isNotNull().isInstanceOf(IllegalArgumentException.class);
   }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertMessagingTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertMessagingTest.java
similarity index 56%
rename from geode-core/src/test/java/org/apache/geode/internal/alerting/AlertMessagingTest.java
rename to geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertMessagingTest.java
index 907fa9f..df413e7 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertMessagingTest.java
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertMessagingTest.java
@@ -12,25 +12,30 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import java.util.Date;
+import java.time.Instant;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
 
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.DistributionConfig;
@@ -41,68 +46,75 @@ import org.apache.geode.internal.admin.remote.AlertListenerMessage;
 import org.apache.geode.test.junit.categories.AlertingTest;
 
 /**
- * Unit tests for {@link AlertMessaging}.
+ * Unit tests for {@link ClusterAlertMessaging}.
  */
 @Category(AlertingTest.class)
-public class AlertMessagingTest {
+public class ClusterAlertMessagingTest {
 
   private InternalDistributedSystem system;
   private InternalDistributedMember localMember;
+  private InternalDistributedMember remoteMember;
   private DistributionConfig config;
-  private DistributionManager dm;
   private AlertListenerMessageFactory alertListenerMessageFactory;
   private AlertListenerMessage alertListenerMessage;
 
-  private AlertMessaging alertMessaging;
+  @Rule
+  public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
 
   @Before
   public void setUp() {
     system = mock(InternalDistributedSystem.class);
     localMember = mock(InternalDistributedMember.class);
+    remoteMember = mock(InternalDistributedMember.class);
     config = mock(DistributionConfig.class);
-    dm = mock(ClusterDistributionManager.class);
     alertListenerMessageFactory = mock(AlertListenerMessageFactory.class);
     alertListenerMessage = mock(AlertListenerMessage.class);
-
-    alertMessaging = spy(new AlertMessaging(system, dm, alertListenerMessageFactory));
-
-    when(system.getConfig()).thenReturn(config);
-    when(system.getDistributedMember()).thenReturn(localMember);
-    when(config.getName()).thenReturn("name");
-
-    when(alertListenerMessageFactory.createAlertListenerMessage(
-        any(DistributedMember.class), any(AlertLevel.class), any(Date.class),
-        anyString(), anyString(), anyString(), anyString())).thenReturn(alertListenerMessage);
-
-    doNothing().when(alertMessaging).processAlertListenerMessage(any(AlertListenerMessage.class));
   }
 
   @Test
   public void sendAlertProcessesMessageIfMemberIsLocal() {
-    alertMessaging.sendAlert(localMember, AlertLevel.WARNING, new Date(), "threadName",
-        "formattedMessage", "stackTrace");
+    ClusterAlertMessaging clusterAlertMessaging = spyClusterAlertMessaging(
+        mock(ClusterDistributionManager.class));
 
-    verify(alertMessaging).processAlertListenerMessage(eq(alertListenerMessage));
+    clusterAlertMessaging.sendAlert(localMember, AlertLevel.WARNING, Instant.now(), "threadName",
+        Thread.currentThread().getId(), "formattedMessage", "stackTrace");
+
+    verify(clusterAlertMessaging).processAlertListenerMessage(eq(alertListenerMessage));
   }
 
   @Test
   public void sendAlertSendsMessageIfMemberIsRemote() {
-    DistributedMember remoteMember = mock(DistributedMember.class);
+    DistributionManager dm = mock(ClusterDistributionManager.class);
+    ClusterAlertMessaging clusterAlertMessaging = spyClusterAlertMessaging(dm);
 
-    alertMessaging.sendAlert(remoteMember, AlertLevel.WARNING, new Date(), "threadName",
-        "formattedMessage", "stackTrace");
+    clusterAlertMessaging.sendAlert(remoteMember, AlertLevel.WARNING, Instant.now(), "threadName",
+        Thread.currentThread().getId(), "formattedMessage", "stackTrace");
 
     verify(dm).putOutgoing(eq(alertListenerMessage));
   }
 
   @Test
   public void processAlertListenerMessage_requires_ClusterDistributionManager() {
-    dm = mock(DistributionManager.class);
+    ClusterAlertMessaging clusterAlertMessaging = spy(new ClusterAlertMessaging(system,
+        mock(DistributionManager.class), alertListenerMessageFactory));
 
-    alertMessaging = new AlertMessaging(system, dm, alertListenerMessageFactory);
+    Throwable thrown = catchThrowable(
+        () -> clusterAlertMessaging.processAlertListenerMessage(alertListenerMessage));
 
-    Throwable thrown =
-        catchThrowable(() -> alertMessaging.processAlertListenerMessage(alertListenerMessage));
     assertThat(thrown).isInstanceOf(IllegalArgumentException.class);
   }
+
+  private ClusterAlertMessaging spyClusterAlertMessaging(DistributionManager distributionManager) {
+    when(alertListenerMessageFactory.createAlertListenerMessage(any(DistributedMember.class),
+        any(AlertLevel.class), any(Instant.class), anyString(), anyString(), anyLong(), anyString(),
+        anyString()))
+            .thenReturn(alertListenerMessage);
+    when(config.getName())
+        .thenReturn("name");
+    when(system.getConfig())
+        .thenReturn(config);
+    when(system.getDistributedMember())
+        .thenReturn(localMember);
+    return spy(new ClusterAlertMessaging(system, distributionManager, alertListenerMessageFactory));
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertingServiceTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertingServiceTest.java
new file mode 100644
index 0000000..89a38cb
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/ClusterAlertingServiceTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.alerting.internal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+
+import org.apache.geode.alerting.internal.spi.AlertLevel;
+import org.apache.geode.distributed.DistributedMember;
+import org.apache.geode.test.junit.categories.AlertingTest;
+
+/**
+ * Unit tests for {@link ClusterAlertingService}.
+ */
+@Category(AlertingTest.class)
+public class ClusterAlertingServiceTest {
+
+  private DistributedMember member;
+  private ClusterAlertingService alertingService;
+
+  @Rule
+  public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
+  @Before
+  public void setUp() {
+    member = mock(DistributedMember.class);
+    alertingService = new ClusterAlertingService();
+  }
+
+  @Test
+  public void alertListenersIsEmptyByDefault() {
+    assertThat(alertingService.getAlertListeners()).isEmpty();
+  }
+
+  @Test
+  public void hasAlertListenerReturnsFalseByDefault() {
+    alertingService.hasAlertListener(member, AlertLevel.WARNING);
+  }
+
+  @Test
+  public void addAlertListenerAddsListener() {
+    alertingService.addAlertListener(member, AlertLevel.WARNING);
+    assertThat(alertingService.getAlertListeners())
+        .contains(new AlertListener(AlertLevel.WARNING, member));
+  }
+
+  @Test
+  public void hasAlertListenerReturnsTrueIfListenerExists() {
+    alertingService.addAlertListener(member, AlertLevel.WARNING);
+    assertThat(alertingService.hasAlertListener(member, AlertLevel.WARNING)).isTrue();
+  }
+
+  @Test
+  public void removeAlertListenerDoesNothingByDefault() {
+    alertingService.removeAlertListener(member);
+    assertThat(alertingService.getAlertListeners()).isEmpty();
+  }
+
+  @Test
+  public void removeAlertListenerDoesNothingIfMemberDoesNotMatch() {
+    alertingService.addAlertListener(member, AlertLevel.WARNING);
+
+    alertingService.removeAlertListener(mock(DistributedMember.class));
+
+    assertThat(alertingService.hasAlertListener(member, AlertLevel.WARNING)).isTrue();
+  }
+
+  @Test
+  public void removeAlertListenerRemovesListener() {
+    alertingService.addAlertListener(member, AlertLevel.WARNING);
+
+    alertingService.removeAlertListener(member);
+
+    assertThat(alertingService.hasAlertListener(member, AlertLevel.WARNING)).isFalse();
+  }
+
+  @Test
+  public void addAlertListenerWithAlertLevelNoneDoesNothing() {
+    alertingService.addAlertListener(member, AlertLevel.NONE);
+    assertThat(alertingService.getAlertListeners()).isEmpty();
+  }
+
+  @Test
+  public void hasAlertListenerReturnsFalseIfAlertLevelIsNone() {
+    alertingService.addAlertListener(member, AlertLevel.WARNING);
+    assertThat(alertingService.hasAlertListener(member, AlertLevel.NONE)).isFalse();
+  }
+
+  @Test
+  public void addAlertListenerOrdersByAscendingAlertLevel() {
+    DistributedMember member1 = mock(DistributedMember.class);
+    DistributedMember member2 = mock(DistributedMember.class);
+    DistributedMember member3 = mock(DistributedMember.class);
+
+    alertingService.addAlertListener(member3, AlertLevel.WARNING);
+    alertingService.addAlertListener(member1, AlertLevel.SEVERE);
+    alertingService.addAlertListener(member2, AlertLevel.ERROR);
+
+    AlertListener listener1 = new AlertListener(AlertLevel.WARNING, member3);
+    AlertListener listener2 = new AlertListener(AlertLevel.ERROR, member2);
+    AlertListener listener3 = new AlertListener(AlertLevel.SEVERE, member1);
+
+    assertThat(alertingService.getAlertListeners()).containsExactly(listener1, listener2,
+        listener3);
+  }
+
+  @Test
+  public void removeAlertListenerMaintainsExistingOrder() {
+    DistributedMember member1 = mock(DistributedMember.class);
+    DistributedMember member2 = mock(DistributedMember.class);
+    DistributedMember member3 = mock(DistributedMember.class);
+
+    alertingService.addAlertListener(member3, AlertLevel.WARNING);
+    alertingService.addAlertListener(member1, AlertLevel.SEVERE);
+    alertingService.addAlertListener(member2, AlertLevel.ERROR);
+
+    AlertListener listener1 = new AlertListener(AlertLevel.WARNING, member3);
+    AlertListener listener3 = new AlertListener(AlertLevel.SEVERE, member1);
+
+    assertThat(alertingService.removeAlertListener(member2)).isTrue();
+
+    assertThat(alertingService.getAlertListeners()).containsExactly(listener1, listener3);
+  }
+
+  @Test
+  public void addAlertListenerOrdersByDescendingAddIfAlertLevelMatches() {
+    DistributedMember member1 = mock(DistributedMember.class);
+    DistributedMember member2 = mock(DistributedMember.class);
+    DistributedMember member3 = mock(DistributedMember.class);
+
+    alertingService.addAlertListener(member3, AlertLevel.WARNING);
+    alertingService.addAlertListener(member1, AlertLevel.WARNING);
+    alertingService.addAlertListener(member2, AlertLevel.WARNING);
+
+    AlertListener listener1 = new AlertListener(AlertLevel.WARNING, member2);
+    AlertListener listener2 = new AlertListener(AlertLevel.WARNING, member1);
+    AlertListener listener3 = new AlertListener(AlertLevel.WARNING, member3);
+
+    assertThat(alertingService.getAlertListeners()).containsExactly(listener1, listener2,
+        listener3);
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/alerting/internal/api/AlertingDependenciesTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/api/AlertingDependenciesTest.java
new file mode 100644
index 0000000..6e67eea
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/api/AlertingDependenciesTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.alerting.internal.api;
+
+import static com.tngtech.archunit.base.DescribedPredicate.not;
+import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
+import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
+
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.junit.ArchUnitRunner;
+import com.tngtech.archunit.lang.ArchRule;
+import org.junit.runner.RunWith;
+
+@RunWith(ArchUnitRunner.class)
+@AnalyzeClasses(packages = "org.apache.geode.alerting..")
+public class AlertingDependenciesTest {
+  @ArchTest
+  public static final ArchRule alertingDoesNotDependOnLog4JCore = classes()
+      .that()
+      .resideInAPackage("org.apache.geode.alerting..")
+      .should()
+      .onlyDependOnClassesThat(not(resideInAPackage("org.apache.logging.log4j.core..")));
+
+  @ArchTest
+  public static final ArchRule alertingDoesNotDependOnGeodeLog4J = classes()
+      .that()
+      .resideInAPackage("org.apache.geode.alerting..")
+      .should()
+      .onlyDependOnClassesThat(not(resideInAPackage("org.apache.geode.alerting.log4j..")));
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertLevelConverterTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverterTest.java
similarity index 92%
rename from geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertLevelConverterTest.java
rename to geode-core/src/test/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverterTest.java
index 223f7f2..149e92f 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertLevelConverterTest.java
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/log4j/AlertLevelConverterTest.java
@@ -12,11 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.alerting.internal.log4j;
 
-import static org.apache.geode.internal.logging.log4j.AlertLevelConverter.fromLevel;
-import static org.apache.geode.internal.logging.log4j.AlertLevelConverter.hasAlertLevel;
-import static org.apache.geode.internal.logging.log4j.AlertLevelConverter.toLevel;
+import static org.apache.geode.alerting.internal.log4j.AlertLevelConverter.fromLevel;
+import static org.apache.geode.alerting.internal.log4j.AlertLevelConverter.hasAlertLevel;
+import static org.apache.geode.alerting.internal.log4j.AlertLevelConverter.toLevel;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -24,7 +24,7 @@ import org.apache.logging.log4j.Level;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.alerting.AlertLevel;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.test.junit.categories.AlertingTest;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingActionTest.java b/geode-core/src/test/java/org/apache/geode/alerting/internal/spi/AlertingActionTest.java
similarity index 68%
rename from geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingActionTest.java
rename to geode-core/src/test/java/org/apache/geode/alerting/internal/spi/AlertingActionTest.java
index 1d4a7ff..d377fcc 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingActionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/alerting/internal/spi/AlertingActionTest.java
@@ -12,13 +12,17 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.alerting;
+package org.apache.geode.alerting.internal.spi;
 
-import static org.apache.geode.internal.alerting.AlertingAction.execute;
-import static org.apache.geode.internal.alerting.AlertingAction.isThreadAlerting;
+import static org.apache.geode.alerting.internal.spi.AlertingAction.execute;
+import static org.apache.geode.alerting.internal.spi.AlertingAction.isThreadAlerting;
+import static org.apache.geode.alerting.internal.spi.AlertingAction.setThreadAlerting;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.is;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
@@ -26,15 +30,18 @@ import org.junit.rules.ErrorCollector;
 
 import org.apache.geode.test.junit.categories.AlertingTest;
 
-/**
- * Unit tests for {@link AlertingAction}.
- */
+/** Unit tests for {@link org.apache.geode.alerting.internal.spi.AlertingAction}. */
 @Category(AlertingTest.class)
 public class AlertingActionTest {
 
   @Rule
   public ErrorCollector errorCollector = new ErrorCollector();
 
+  @After
+  public void tearDown() {
+    setThreadAlerting(false);
+  }
+
   @Test
   public void isThreadAlertingIsFalseByDefault() {
     assertThat(isThreadAlerting()).isFalse();
@@ -51,4 +58,14 @@ public class AlertingActionTest {
 
     assertThat(isThreadAlerting()).isFalse();
   }
+
+  @Test
+  public void executeDoesNothingIfIsThreadAlertingIsTrue() {
+    AtomicBoolean executed = new AtomicBoolean();
+    setThreadAlerting(true);
+
+    execute(() -> executed.set(true));
+
+    assertThat(executed).isFalse();
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/cache/client/internal/OpExecutorImplJUnitTest.java b/geode-core/src/test/java/org/apache/geode/cache/client/internal/OpExecutorImplJUnitTest.java
index 4e6dcef..752ba93 100644
--- a/geode-core/src/test/java/org/apache/geode/cache/client/internal/OpExecutorImplJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/cache/client/internal/OpExecutorImplJUnitTest.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.cache.client.internal;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.FINE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINE;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/ServerLocatorJUnitTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/ServerLocatorJUnitTest.java
index 7aa9b0b..4fb70a7 100755
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/ServerLocatorJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/ServerLocatorJUnitTest.java
@@ -14,7 +14,7 @@
  */
 package org.apache.geode.distributed.internal;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.NONE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.NONE;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
index 624c74f..3ac1bed 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/membership/MembershipDependenciesJUnitTest.java
@@ -32,6 +32,7 @@ import org.apache.geode.CancelCriterion;
 import org.apache.geode.GemFireException;
 import org.apache.geode.InternalGemFireError;
 import org.apache.geode.SystemFailure;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
@@ -44,7 +45,6 @@ import org.apache.geode.internal.ConnectionWatcher;
 import org.apache.geode.internal.InternalDataSerializer;
 import org.apache.geode.internal.OSProcess;
 import org.apache.geode.internal.admin.remote.DistributionLocatorId;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.concurrent.ConcurrentHashSet;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.internal.logging.LoggingExecutors;
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingProviderRegistryTest.java b/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingProviderRegistryTest.java
deleted file mode 100644
index a4efb1a..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingProviderRegistryTest.java
+++ /dev/null
@@ -1,94 +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.alerting;
-
-import static org.apache.geode.internal.alerting.AlertingProviderRegistry.getNullAlertingProvider;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.test.junit.categories.AlertingTest;
-
-/**
- * Unit tests for {@link AlertingProviderRegistry}.
- */
-@Category(AlertingTest.class)
-public class AlertingProviderRegistryTest {
-
-  private AlertingProvider provider;
-
-  private AlertingProviderRegistry alertingProviderRegistry;
-
-  @Before
-  public void setUp() {
-    provider = mock(AlertingProvider.class);
-
-    alertingProviderRegistry = new AlertingProviderRegistry();
-  }
-
-  @Test
-  public void getAlertingProviderIsNullProviderBeforeRegister() {
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(getNullAlertingProvider());
-  }
-
-  @Test
-  public void getAlertingProviderIsSameAsRegisteredProvider() {
-    alertingProviderRegistry.registerAlertingProvider(provider);
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(provider);
-  }
-
-  @Test
-  public void unregisterDoesNothingIfNotRegistered() {
-    alertingProviderRegistry.unregisterAlertingProvider(provider);
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(getNullAlertingProvider());
-  }
-
-  @Test
-  public void unregisterWrongProviderDoesNothing() {
-    alertingProviderRegistry.registerAlertingProvider(provider);
-
-    alertingProviderRegistry.unregisterAlertingProvider(mock(AlertingProvider.class));
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(provider);
-  }
-
-  @Test
-  public void unregisterDoesNothingIfNullProvider() {
-    alertingProviderRegistry.unregisterAlertingProvider(getNullAlertingProvider());
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(getNullAlertingProvider());
-  }
-
-  @Test
-  public void unregisterRemovesRegisteredProvider() {
-    alertingProviderRegistry.registerAlertingProvider(provider);
-
-    alertingProviderRegistry.unregisterAlertingProvider(provider);
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(getNullAlertingProvider());
-  }
-
-  @Test
-  public void registerAddsAlertingProvider() {
-    alertingProviderRegistry.registerAlertingProvider(provider);
-
-    assertThat(alertingProviderRegistry.getAlertingProvider()).isSameAs(provider);
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingServiceTest.java b/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingServiceTest.java
deleted file mode 100644
index 089579d..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/AlertingServiceTest.java
+++ /dev/null
@@ -1,75 +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.alerting;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.test.junit.categories.AlertingTest;
-
-/**
- * Unit tests for {@link AlertingService}.
- */
-@Category(AlertingTest.class)
-public class AlertingServiceTest {
-
-  private AlertingProviderRegistry registry;
-  private AlertingProvider provider;
-  private DistributedMember member;
-
-  private AlertingService alertingService;
-
-  @Before
-  public void setUp() {
-    registry = mock(AlertingProviderRegistry.class);
-    provider = mock(AlertingProvider.class);
-    member = mock(DistributedMember.class);
-
-    when(registry.getAlertingProvider()).thenReturn(provider);
-    when(provider.hasAlertListener(eq(member), eq(AlertLevel.WARNING))).thenReturn(true);
-    when(provider.removeAlertListener(eq(member))).thenReturn(true);
-
-    alertingService = new AlertingService(registry);
-  }
-
-  @Test
-  public void hasAlertListenerDelegates() {
-    assertThat(alertingService.hasAlertListener(member, AlertLevel.WARNING)).isTrue();
-
-    verify(provider).hasAlertListener(eq(member), eq(AlertLevel.WARNING));
-  }
-
-  @Test
-  public void addAlertListenerDelegates() {
-    alertingService.addAlertListener(member, AlertLevel.WARNING);
-
-    verify(provider).addAlertListener(eq(member), eq(AlertLevel.WARNING));
-  }
-
-  @Test
-  public void removeAlertListenerDelegates() {
-    assertThat(alertingService.removeAlertListener(member)).isTrue();
-
-    verify(provider).removeAlertListener(eq(member));
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/alerting/NullAlertingProviderTest.java b/geode-core/src/test/java/org/apache/geode/internal/alerting/NullAlertingProviderTest.java
deleted file mode 100644
index 8d31f0d..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/alerting/NullAlertingProviderTest.java
+++ /dev/null
@@ -1,48 +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.alerting;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.test.junit.categories.AlertingTest;
-
-/**
- * Unit test for {@link NullAlertingProvider}.
- */
-@Category(AlertingTest.class)
-public class NullAlertingProviderTest {
-
-  private DistributedMember member;
-  private NullAlertingProvider nullAlertingProvider;
-
-  @Before
-  public void setUp() {
-    member = mock(DistributedMember.class);
-    nullAlertingProvider = new NullAlertingProvider();
-  }
-
-  @Test
-  public void doesNothingButReturnFalse() {
-    nullAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-    assertThat(nullAlertingProvider.hasAlertListener(member, AlertLevel.WARNING)).isFalse();
-    assertThat(nullAlertingProvider.removeAlertListener(member)).isFalse();
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/BannerTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/BannerTest.java
similarity index 61%
rename from geode-core/src/test/java/org/apache/geode/internal/BannerTest.java
rename to geode-core/src/test/java/org/apache/geode/internal/logging/BannerTest.java
index fa80563..c298c19 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/BannerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/BannerTest.java
@@ -1,18 +1,20 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
+ * 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.
+ * 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;
+package org.apache.geode.internal.logging;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -20,11 +22,11 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.Banner;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Unit tests for {@link Banner} and {@link Banner.BannerHeader}.
+ * Unit tests for {@link org.apache.geode.internal.logging.Banner} and {@link
+ * org.apache.geode.internal.logging.Banner.BannerHeader}.
  */
 @Category(LoggingTest.class)
 public class BannerTest {
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/DefaultProviderCheckerTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/DefaultProviderCheckerTest.java
deleted file mode 100644
index ac16278..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/DefaultProviderCheckerTest.java
+++ /dev/null
@@ -1,152 +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.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.catchThrowable;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.impl.Log4jContextFactory;
-import org.apache.logging.log4j.spi.LoggerContextFactory;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import org.apache.geode.internal.ClassPathLoader;
-
-public class DefaultProviderCheckerTest {
-
-  @Test
-  public void isAvailableReturnsTrueIfAbleToLoadDefaultProviderClass() {
-    DefaultProviderChecker checker = new DefaultProviderChecker(() -> Log4jContextFactory.class,
-        (a) -> true, mock(Logger.class));
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isTrue();
-  }
-
-  @Test
-  public void isAvailableReturnsFalseIfUnableToLoadDefaultProviderClass() {
-    DefaultProviderChecker checker = new DefaultProviderChecker(() -> Log4jContextFactory.class,
-        (a) -> false, mock(Logger.class));
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isFalse();
-  }
-
-  @Test
-  public void isAvailableReturnsFalseIfNotUsingLog4jProvider() {
-    DefaultProviderChecker checker = new DefaultProviderChecker(
-        () -> mock(LoggerContextFactory.class).getClass(), (a) -> true, mock(Logger.class));
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isFalse();
-  }
-
-  @Test
-  public void logsUsingMessageIfUsingLog4jProvider() {
-    Logger logger = mock(Logger.class);
-    DefaultProviderChecker checker =
-        new DefaultProviderChecker(() -> Log4jContextFactory.class, (a) -> true, logger);
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isTrue();
-
-    ArgumentCaptor<String> loggedMessage = ArgumentCaptor.forClass(String.class);
-    verify(logger).info(loggedMessage.capture());
-
-    assertThat(loggedMessage.getValue())
-        .isEqualTo("Log4j Core is available and using Log4jProvider.");
-  }
-
-  @Test
-  public void logsNotUsingMessageIfNotUsingLog4jProvider() {
-    Logger logger = mock(Logger.class);
-    DefaultProviderChecker checker = new DefaultProviderChecker(
-        () -> mock(LoggerContextFactory.class).getClass(), (a) -> true, logger);
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isFalse();
-
-    ArgumentCaptor<String> loggedMessage = ArgumentCaptor.forClass(String.class);
-    verify(logger).info(loggedMessage.capture());
-
-    assertThat(loggedMessage.getValue())
-        .isEqualTo("Log4j Core is available but not using Log4jProvider.");
-  }
-
-  @Test
-  public void logsUnableToFindMessageIfClassNotFoundExceptionIsCaught() {
-    Logger logger = mock(Logger.class);
-    DefaultProviderChecker checker =
-        new DefaultProviderChecker(() -> Log4jContextFactory.class, (a) -> false, logger);
-
-    boolean value = checker.isAvailable();
-
-    assertThat(value).isFalse();
-
-    ArgumentCaptor<String> loggedMessage = ArgumentCaptor.forClass(String.class);
-    verify(logger).info(loggedMessage.capture());
-
-    assertThat(loggedMessage.getValue()).isEqualTo("Unable to find Log4j Core.");
-  }
-
-  @Test
-  public void rethrowsIfIsClassLoadableFunctionThrowsRuntimeException() {
-    RuntimeException exception = new RuntimeException("expected");
-    DefaultProviderChecker checker =
-        new DefaultProviderChecker(() -> Log4jContextFactory.class, (a) -> {
-          throw exception;
-        }, mock(Logger.class));
-
-    Throwable thrown = catchThrowable(() -> checker.isAvailable());
-
-    assertThat(thrown).isSameAs(exception);
-  }
-
-  @Test
-  public void isClassLoadableReturnsTrueIfClassNameExists() {
-    boolean value = DefaultProviderChecker.isClassLoadable(ClassPathLoader.class.getName());
-
-    assertThat(value).isTrue();
-  }
-
-  @Test
-  public void isClassLoadableReturnsFalseIfClassNameDoesNotExist() {
-    boolean value = DefaultProviderChecker.isClassLoadable("Not a class");
-
-    assertThat(value).isFalse();
-  }
-
-  @Test
-  public void isClassLoadableThrowsNullPointerExceptionIfClassNameIsNull() {
-    Throwable thrown = catchThrowable(() -> DefaultProviderChecker.isClassLoadable(null));
-
-    assertThat(thrown).isInstanceOf(NullPointerException.class);
-  }
-
-  @Test
-  public void isClassLoadableReturnsFalseIfClassNameIsEmpty() {
-    boolean value = DefaultProviderChecker.isClassLoadable("");
-
-    assertThat(value).isFalse();
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogServiceTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LogServiceTest.java
index e8ca28c..c8fa7a2 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogServiceTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LogServiceTest.java
@@ -17,16 +17,13 @@ package org.apache.geode.internal.logging;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.message.MessageFactory;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.rules.TestName;
 
-import org.apache.geode.LogWriter;
-import org.apache.geode.internal.logging.log4j.FastLogger;
-import org.apache.geode.internal.logging.log4j.LogWriterLogger;
-import org.apache.geode.internal.logging.log4j.message.GemFireParameterizedMessageFactory;
+import org.apache.geode.logging.internal.SimpleLoggingProvider;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
@@ -41,91 +38,23 @@ public class LogServiceTest {
   public TestName testName = new TestName();
 
   @Test
-  public void getLoggerReturnsFastLogger() {
-    assertThat(LogService.getLogger()).isInstanceOf(FastLogger.class);
-  }
-
-  @Test
   public void getLoggerReturnsLoggerWithCallerClassName() {
-    assertThat(LogService.getLogger().getName()).isEqualTo(getClass().getName());
-  }
-
-  @Test
-  public void getLoggerReturnsLoggerWithGeodeMessageFactory() {
     Logger logger = LogService.getLogger();
 
-    MessageFactory messageFactory = logger.getMessageFactory();
-    assertThat(messageFactory).isInstanceOf(GemFireParameterizedMessageFactory.class);
+    assertThat(logger.getName()).isEqualTo(getClass().getName());
   }
 
   @Test
   public void getLoggerNameReturnsLoggerWithSpecifiedName() {
-    assertThat(LogService.getLogger(APPLICATION_LOGGER_NAME).getName())
-        .isEqualTo(APPLICATION_LOGGER_NAME);
-  }
-
-  @Test
-  public void getLoggerNameReturnsLoggerWithGeodeMessageFactory() {
     Logger logger = LogService.getLogger(APPLICATION_LOGGER_NAME);
 
-    MessageFactory messageFactory = logger.getMessageFactory();
-    assertThat(messageFactory).isInstanceOf(GemFireParameterizedMessageFactory.class);
-  }
-
-  @Test
-  public void createLogWriterLoggerReturnsFastLogger() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    assertThat(logWriterLogger).isInstanceOf(FastLogger.class);
-  }
-
-  @Test
-  public void createLogWriterLoggerReturnsLogWriter() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    assertThat(logWriterLogger).isInstanceOf(LogWriter.class);
-  }
-
-  @Test
-  public void createLogWriterLoggerReturnsLoggerWithSpecifiedName() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    assertThat(logWriterLogger.getName()).isEqualTo(getClass().getName());
-  }
-
-  @Test
-  public void createLogWriterLoggerReturnsLoggerWithSpecifiedConnectionName() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    assertThat(logWriterLogger.getConnectionName()).isEqualTo(testName.getMethodName());
-  }
-
-  @Test
-  public void createLogWriterLoggerReturnsLoggerWithGeodeMessageFactory() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    MessageFactory messageFactory = logWriterLogger.getMessageFactory();
-    assertThat(messageFactory).isInstanceOf(GemFireParameterizedMessageFactory.class);
-  }
-
-  @Test
-  public void createLogWriterLoggerWithSecureFalseReturnsSecureLogWriter() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), false);
-
-    assertThat(logWriterLogger.isSecure()).isFalse();
+    assertThat(logger.getName()).isEqualTo(APPLICATION_LOGGER_NAME);
   }
 
   @Test
-  public void createLogWriterLoggerWithSecureTrueReturnsSecureLogWriter() {
-    LogWriterLogger logWriterLogger =
-        LogService.createLogWriterLogger(getClass().getName(), testName.getMethodName(), true);
+  public void getLoggingProviderReturnsSimpleLoggingProviderByDefault() {
+    LoggingProvider loggingProvider = LogService.getLoggingProvider();
 
-    assertThat(logWriterLogger.isSecure()).isTrue();
+    assertThat(loggingProvider).isInstanceOf(SimpleLoggingProvider.class);
   }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterFactoryTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterFactoryTest.java
new file mode 100644
index 0000000..f23be18
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterFactoryTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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 org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.logging.internal.log4j.LogWriterLogger;
+
+public class LogWriterFactoryTest {
+
+  @Rule
+  public TestName testName = new TestName();
+
+  @Test
+  public void createLogWriterLoggerReturnsLogWriter() {
+    LogWriterLogger logWriterLogger =
+        LogWriterFactory.createLogWriterLogger(getClass().getName(), testName.getMethodName(),
+            false);
+
+    assertThat(logWriterLogger).isInstanceOf(LogWriter.class);
+  }
+
+  @Test
+  public void createLogWriterLoggerReturnsLoggerWithSpecifiedName() {
+    LogWriterLogger logWriterLogger =
+        LogWriterFactory.createLogWriterLogger(getClass().getName(), testName.getMethodName(),
+            false);
+
+    assertThat(logWriterLogger.getName()).isEqualTo(getClass().getName());
+  }
+
+  @Test
+  public void createLogWriterLoggerReturnsLoggerWithSpecifiedConnectionName() {
+    LogWriterLogger logWriterLogger =
+        LogWriterFactory.createLogWriterLogger(getClass().getName(), testName.getMethodName(),
+            false);
+
+    assertThat(logWriterLogger.getConnectionName()).isEqualTo(testName.getMethodName());
+  }
+
+  @Test
+  public void createLogWriterLoggerWithSecureFalseReturnsSecureLogWriter() {
+    LogWriterLogger logWriterLogger =
+        LogWriterFactory.createLogWriterLogger(getClass().getName(), testName.getMethodName(),
+            false);
+
+    assertThat(logWriterLogger.isSecure()).isFalse();
+  }
+
+  @Test
+  public void createLogWriterLoggerWithSecureTrueReturnsSecureLogWriter() {
+    LogWriterLogger logWriterLogger =
+        LogWriterFactory.createLogWriterLogger(getClass().getName(), testName.getMethodName(),
+            true);
+
+    assertThat(logWriterLogger.isSecure()).isTrue();
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterImplTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterImplTest.java
index 3b9a671..de4e281 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterImplTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterImplTest.java
@@ -1,16 +1,18 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
@@ -21,9 +23,7 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.junit.categories.LoggingTest;
 
-/**
- * Unit tests for {@link LogWriterImpl}.
- */
+/** Unit tests for {@link org.apache.geode.internal.logging.LogWriterImpl}. */
 @Category(LoggingTest.class)
 public class LogWriterImplTest {
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
index 85befab..7af9dd6 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LogWriterLevelTest.java
@@ -14,17 +14,17 @@
  */
 package org.apache.geode.internal.logging;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.ALL;
-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.NONE;
-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.LogWriterLevel.find;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ALL;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.CONFIG;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.ERROR;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINER;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.FINEST;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.NONE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.SEVERE;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.WARNING;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.find;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.Serializable;
@@ -33,6 +33,7 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
@@ -48,7 +49,7 @@ public class LogWriterLevelTest {
 
   @Test
   public void serializes() {
-    LogWriterLevel logLevel = (LogWriterLevel) SerializationUtils.clone(ALL);
+    LogWriterLevel logLevel = SerializationUtils.clone(ALL);
 
     assertThat(logLevel).isEqualTo(ALL).isSameAs(ALL);
   }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadFactoryTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadFactoryTest.java
index 4e94ef6..82ae215 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadFactoryTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadFactoryTest.java
@@ -31,9 +31,7 @@ import org.apache.geode.internal.logging.LoggingThreadFactory.CommandWrapper;
 import org.apache.geode.internal.logging.LoggingThreadFactory.ThreadInitializer;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
-/**
- * Unit tests for {@link LoggingThreadFactory}.
- */
+/** Unit tests for {@link org.apache.geode.internal.logging.LoggingThreadFactory}. */
 @Category(LoggingTest.class)
 public class LoggingThreadFactoryTest {
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadTest.java
index 9b2b3cd..107db46 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingThreadTest.java
@@ -25,9 +25,7 @@ import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.junit.categories.LoggingTest;
 
-/**
- * Unit tests for {@link LoggingThread}.
- */
+/** Unit tests for {@link org.apache.geode.internal.logging.LoggingThread}. */
 @Category(LoggingTest.class)
 public class LoggingThreadTest {
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandlerTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandlerTest.java
index bdfb13e..be08d62 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandlerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingUncaughtExceptionHandlerTest.java
@@ -31,9 +31,7 @@ import org.apache.geode.internal.logging.LoggingUncaughtExceptionHandler.Failure
 import org.apache.geode.internal.logging.LoggingUncaughtExceptionHandler.Implementation;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
-/**
- * Unit tests for {@link LoggingUncaughtExceptionHandler}.
- */
+/** Unit tests for {@link org.apache.geode.internal.logging.LoggingUncaughtExceptionHandler}. */
 @Category(LoggingTest.class)
 public class LoggingUncaughtExceptionHandlerTest {
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/ManagerLogWriterTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/ManagerLogWriterTest.java
index e923fbd..5a0612e 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/ManagerLogWriterTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/ManagerLogWriterTest.java
@@ -14,27 +14,26 @@
  */
 package org.apache.geode.internal.logging;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.CONFIG;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.CONFIG;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
 
+import java.io.OutputStream;
 import java.io.PrintStream;
 
-import org.apache.logging.log4j.core.util.NullOutputStream;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.test.junit.categories.LoggingTest;
 
-/**
- * Unit tests for {@link ManagerLogWriter}.
- */
+/** Unit tests for {@link org.apache.geode.internal.logging.ManagerLogWriter}. */
 @Category(LoggingTest.class)
 public class ManagerLogWriterTest {
 
   @Test
   public void logWriterLevelIsPassedIntoConstructor() {
     ManagerLogWriter logWriter = new ManagerLogWriter(CONFIG.intLevel(),
-        new PrintStream(NullOutputStream.getInstance()), true);
+        new PrintStream(mock(OutputStream.class)), true);
 
     assertThat(logWriter.getLogWriterLevel()).isEqualTo(CONFIG.intLevel());
   }
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/NullProviderAgentTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/NullProviderAgentTest.java
deleted file mode 100644
index 7b37778..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/NullProviderAgentTest.java
+++ /dev/null
@@ -1,40 +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.assertj.core.api.Assertions.assertThat;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link NullProviderAgent}.
- */
-public class NullProviderAgentTest {
-
-  private NullProviderAgent nullProviderAgent;
-
-  @Before
-  public void setUp() {
-    nullProviderAgent = new NullProviderAgent();
-  }
-
-  @Test
-  public void getConfigurationInfoReturnsClassName() {
-    String configurationInfo = nullProviderAgent.getConfigurationInfo();
-
-    assertThat(configurationInfo).isEqualTo(NullProviderAgent.class.getName());
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/ProviderAgentLoaderTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/ProviderAgentLoaderTest.java
deleted file mode 100644
index f1dfe76..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/ProviderAgentLoaderTest.java
+++ /dev/null
@@ -1,131 +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.ProviderAgentLoader.PROVIDER_AGENT_NAME_PROPERTY;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-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.ProviderAgentLoader.AvailabilityChecker;
-import org.apache.geode.internal.logging.log4j.Log4jAgent;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Unit tests for {@link ProviderAgentLoader}.
- */
-@Category(LoggingTest.class)
-public class ProviderAgentLoaderTest {
-
-  private ProviderAgentLoader providerAgentLoader;
-
-  @Rule
-  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
-
-  @Before
-  public void setUp() {
-    providerAgentLoader = new ProviderAgentLoader();
-  }
-
-  @Test
-  public void createProviderAgent_defaultsTo_Log4jAgent() {
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(Log4jAgent.class);
-  }
-
-  @Test
-  public void createProviderAgent_usesSystemPropertySetTo_Log4jAgent() {
-    System.setProperty(PROVIDER_AGENT_NAME_PROPERTY, Log4jAgent.class.getName());
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(Log4jAgent.class);
-  }
-
-  @Test
-  public void createProviderAgent_usesSystemPropertySetTo_NullProviderAgent() {
-    System.setProperty(PROVIDER_AGENT_NAME_PROPERTY, NullProviderAgent.class.getName());
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(NullProviderAgent.class);
-  }
-
-  @Test
-  public void createProviderAgent_usesSystemPropertySetTo_SimpleProviderAgent() {
-    System.setProperty(PROVIDER_AGENT_NAME_PROPERTY, SimpleProviderAgent.class.getName());
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(
-        SimpleProviderAgent.class);
-  }
-
-  @Test
-  public void createProviderAgent_usesNullProviderAgent_whenClassNotFoundException() {
-    System.setProperty(PROVIDER_AGENT_NAME_PROPERTY, SimpleProviderAgent.class.getSimpleName());
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(NullProviderAgent.class);
-  }
-
-  @Test
-  public void createProviderAgent_usesNullProviderAgent_whenClassCastException() {
-    System.setProperty(PROVIDER_AGENT_NAME_PROPERTY, NotProviderAgent.class.getName());
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(NullProviderAgent.class);
-  }
-
-  @Test
-  public void findProviderAgent_defaultsTo_createProviderAgent() {
-    assertThat(providerAgentLoader.findProviderAgent()).isInstanceOf(Log4jAgent.class);
-  }
-
-  @Test
-  public void isLog4jCoreAvailable_isTrue() {
-    assertThat(providerAgentLoader.isDefaultAvailable()).isTrue();
-  }
-
-  @Test
-  public void isLog4jCoreAvailable_usesProvidedAvailabilityChecker() {
-    providerAgentLoader = new ProviderAgentLoader(mock(AvailabilityChecker.class));
-
-    assertThat(providerAgentLoader.isDefaultAvailable()).isFalse();
-  }
-
-  @Test
-  public void createProviderAgent_usesNullProviderAgent_whenIsDefaultAvailableIsFalse() {
-    providerAgentLoader = new ProviderAgentLoader(mock(AvailabilityChecker.class));
-
-    assertThat(providerAgentLoader.createProviderAgent()).isInstanceOf(NullProviderAgent.class);
-  }
-
-  static class SimpleProviderAgent implements ProviderAgent {
-
-    @Override
-    public void configure(LogConfig logConfig,
-        LogLevelUpdateOccurs logLevelUpdateOccurs,
-        LogLevelUpdateScope logLevelUpdateScope) {
-      // nothing
-    }
-
-    @Override
-    public void cleanup() {
-      // nothing
-    }
-  }
-
-  @SuppressWarnings("all")
-  static class NotProviderAgent {
-
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/SortLogFileTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/SortLogFileTest.java
index 07da2f8..18adef4 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/SortLogFileTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/SortLogFileTest.java
@@ -1,16 +1,18 @@
 /*
- * 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
  *
- * 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.
  */
 package org.apache.geode.internal.logging;
 
@@ -33,7 +35,7 @@ import org.apache.geode.LogWriter;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
- * Unit tests for {@link SortLogFile}.
+ * Unit tests for {@link org.apache.geode.internal.logging.SortLogFile}.
  *
  * @since GemFire 3.0
  */
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertAppenderTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertAppenderTest.java
deleted file mode 100644
index 6779b20..0000000
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/AlertAppenderTest.java
+++ /dev/null
@@ -1,193 +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.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import org.apache.logging.log4j.Level;
-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.TestName;
-
-import org.apache.geode.distributed.DistributedMember;
-import org.apache.geode.internal.alerting.AlertLevel;
-import org.apache.geode.internal.alerting.AlertingProvider;
-import org.apache.geode.test.junit.categories.AlertingTest;
-import org.apache.geode.test.junit.categories.LoggingTest;
-
-/**
- * Unit tests for {@link AlertAppender}.
- */
-@Category({AlertingTest.class, LoggingTest.class})
-public class AlertAppenderTest {
-
-  private DistributedMember member;
-
-  private AlertAppender alertAppender;
-  private AlertingProvider asAlertingProvider;
-
-  @Rule
-  public TestName testName = new TestName();
-
-  @Before
-  public void setUp() {
-    member = mock(DistributedMember.class);
-
-    alertAppender = new AlertAppender(testName.getMethodName(), null, null);
-    asAlertingProvider = alertAppender;
-  }
-
-  @After
-  public void tearDown() {
-    AlertAppender.setInstance(null);
-  }
-
-  @Test
-  public void alertListenersIsEmptyByDefault() {
-    assertThat(alertAppender.getAlertListeners()).isEmpty();
-  }
-
-  @Test
-  public void hasAlertListenerReturnsFalseByDefault() {
-    asAlertingProvider.hasAlertListener(member, AlertLevel.WARNING);
-  }
-
-  @Test
-  public void addAlertListenerAddsListener() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-    assertThat(alertAppender.getAlertListeners())
-        .contains(new AlertListener(Level.WARN, member));
-  }
-
-  @Test
-  public void hasAlertListenerReturnsTrueIfListenerExists() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-    assertThat(asAlertingProvider.hasAlertListener(member, AlertLevel.WARNING)).isTrue();
-  }
-
-  @Test
-  public void removeAlertListenerDoesNothingByDefault() {
-    asAlertingProvider.removeAlertListener(member);
-    assertThat(alertAppender.getAlertListeners()).isEmpty();
-  }
-
-  @Test
-  public void removeAlertListenerDoesNothingIfMemberDoesNotMatch() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-
-    asAlertingProvider.removeAlertListener(mock(DistributedMember.class));
-
-    assertThat(asAlertingProvider.hasAlertListener(member, AlertLevel.WARNING)).isTrue();
-  }
-
-  @Test
-  public void removeAlertListenerRemovesListener() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-
-    asAlertingProvider.removeAlertListener(member);
-
-    assertThat(asAlertingProvider.hasAlertListener(member, AlertLevel.WARNING)).isFalse();
-  }
-
-  @Test
-  public void addAlertListenerWithAlertLevelNoneDoesNothing() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.NONE);
-    assertThat(alertAppender.getAlertListeners()).isEmpty();
-  }
-
-  @Test
-  public void hasAlertListenerReturnsFalseIfAlertLevelIsNone() {
-    asAlertingProvider.addAlertListener(member, AlertLevel.WARNING);
-    assertThat(asAlertingProvider.hasAlertListener(member, AlertLevel.NONE)).isFalse();
-  }
-
-  @Test
-  public void addAlertListenerOrdersByAscendingAlertLevel() {
-    DistributedMember member1 = mock(DistributedMember.class);
-    DistributedMember member2 = mock(DistributedMember.class);
-    DistributedMember member3 = mock(DistributedMember.class);
-
-    asAlertingProvider.addAlertListener(member3, AlertLevel.WARNING);
-    asAlertingProvider.addAlertListener(member1, AlertLevel.SEVERE);
-    asAlertingProvider.addAlertListener(member2, AlertLevel.ERROR);
-
-    AlertListener listener1 = new AlertListener(Level.WARN, member3);
-    AlertListener listener2 = new AlertListener(Level.ERROR, member2);
-    AlertListener listener3 = new AlertListener(Level.FATAL, member1);
-
-    assertThat(alertAppender.getAlertListeners()).containsExactly(listener1, listener2,
-        listener3);
-  }
-
-  @Test
-  public void removeAlertListenerMaintainsExistingOrder() {
-    DistributedMember member1 = mock(DistributedMember.class);
-    DistributedMember member2 = mock(DistributedMember.class);
-    DistributedMember member3 = mock(DistributedMember.class);
-
-    asAlertingProvider.addAlertListener(member3, AlertLevel.WARNING);
-    asAlertingProvider.addAlertListener(member1, AlertLevel.SEVERE);
-    asAlertingProvider.addAlertListener(member2, AlertLevel.ERROR);
-
-    AlertListener listener1 = new AlertListener(Level.WARN, member3);
-    AlertListener listener3 = new AlertListener(Level.FATAL, member1);
-
-    assertThat(alertAppender.removeAlertListener(member2)).isTrue();
-
-    assertThat(alertAppender.getAlertListeners()).containsExactly(listener1, listener3);
-  }
-
-  @Test
-  public void addAlertListenerOrdersByDescendingAddIfAlertLevelMatches() {
-    DistributedMember member1 = mock(DistributedMember.class);
-    DistributedMember member2 = mock(DistributedMember.class);
-    DistributedMember member3 = mock(DistributedMember.class);
-
-    asAlertingProvider.addAlertListener(member3, AlertLevel.WARNING);
-    asAlertingProvider.addAlertListener(member1, AlertLevel.WARNING);
-    asAlertingProvider.addAlertListener(member2, AlertLevel.WARNING);
-
-    AlertListener listener1 = new AlertListener(Level.WARN, member2);
-    AlertListener listener2 = new AlertListener(Level.WARN, member1);
-    AlertListener listener3 = new AlertListener(Level.WARN, member3);
-
-    assertThat(alertAppender.getAlertListeners()).containsExactly(listener1, listener2,
-        listener3);
-  }
-
-  @Test
-  public void stopSessionIfRunningDoesNotThrowIfReferenceIsNull() {
-    AlertAppender.setInstance(null);
-
-    assertThatCode(AlertAppender::stopSessionIfRunning).doesNotThrowAnyException();
-  }
-
-  @Test
-  public void stopSessionIfRunningStopCurrentInstance() {
-    alertAppender = spy(alertAppender);
-    AlertAppender.setInstance(alertAppender);
-
-    AlertAppender.stopSessionIfRunning();
-
-    verify(alertAppender).stopSession();
-  }
-}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogLevelTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogLevelTest.java
index 70819ab..aafeef0 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogLevelTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogLevelTest.java
@@ -21,7 +21,8 @@ import org.apache.logging.log4j.Level;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverterTest.java b/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverterTest.java
index 2c1109b..9bbbce8 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverterTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/logging/log4j/LogWriterLevelConverterTest.java
@@ -14,8 +14,8 @@
  */
 package org.apache.geode.internal.logging.log4j;
 
-import static org.apache.geode.internal.logging.log4j.LogWriterLevelConverter.fromLevel;
-import static org.apache.geode.internal.logging.log4j.LogWriterLevelConverter.toLevel;
+import static org.apache.geode.logging.internal.log4j.LogWriterLevelConverter.fromLevel;
+import static org.apache.geode.logging.internal.log4j.LogWriterLevelConverter.toLevel;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
@@ -23,7 +23,8 @@ import org.apache.logging.log4j.Level;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.LogWriterLevel;
+import org.apache.geode.logging.internal.log4j.LogWriterLevelConverter;
+import org.apache.geode.logging.internal.spi.LogWriterLevel;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
diff --git a/geode-core/src/test/java/org/apache/geode/internal/statistics/HostStatSamplerTest.java b/geode-core/src/test/java/org/apache/geode/internal/statistics/HostStatSamplerTest.java
index 1e1df6d..842cfa5 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/statistics/HostStatSamplerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/statistics/HostStatSamplerTest.java
@@ -25,9 +25,9 @@ import org.junit.Test;
 
 import org.apache.geode.CancelCriterion;
 import org.apache.geode.internal.NanoTimer;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.process.PidUnavailableException;
 import org.apache.geode.internal.process.UncheckedPidUnavailableException;
+import org.apache.geode.logging.internal.spi.LogFile;
 
 /**
  * Unit tests for {@link HostStatSampler}.
diff --git a/geode-core/src/test/java/org/apache/geode/internal/tcp/ConnectionJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/tcp/ConnectionJUnitTest.java
index 7862779..cd77b9c 100755
--- a/geode-core/src/test/java/org/apache/geode/internal/tcp/ConnectionJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/tcp/ConnectionJUnitTest.java
@@ -30,12 +30,12 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import org.apache.geode.CancelCriterion;
+import org.apache.geode.alerting.internal.spi.AlertingAction;
 import org.apache.geode.distributed.internal.DMStats;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
 import org.apache.geode.distributed.internal.membership.MembershipManager;
-import org.apache.geode.internal.alerting.AlertingAction;
 import org.apache.geode.internal.net.BufferPool;
 import org.apache.geode.internal.net.SocketCloser;
 import org.apache.geode.internal.net.SocketCreator;
diff --git a/geode-core/src/test/java/org/apache/geode/logging/api/LoggingDependenciesTest.java b/geode-core/src/test/java/org/apache/geode/logging/api/LoggingDependenciesTest.java
new file mode 100644
index 0000000..ce496ce
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/logging/api/LoggingDependenciesTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.logging.api;
+
+import static com.tngtech.archunit.base.DescribedPredicate.not;
+import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
+import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
+
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.junit.ArchUnitRunner;
+import com.tngtech.archunit.lang.ArchRule;
+import org.junit.runner.RunWith;
+
+@RunWith(ArchUnitRunner.class)
+@AnalyzeClasses(packages = {"org.apache.geode.logging..", "org.apache.geode.internal.logging.."})
+public class LoggingDependenciesTest {
+  @ArchTest
+  public static final ArchRule loggingDoesNotDependOnLog4JCore = classes()
+      .that()
+      .resideInAnyPackage("org.apache.geode.logging..", "org.apache.geode.internal.logging..")
+      .should()
+      .onlyDependOnClassesThat(not(resideInAPackage("org.apache.logging.log4j.core..")));
+
+  @ArchTest
+  public static final ArchRule loggingDoesNotDependOnGeodeLog4J = classes()
+      .that()
+      .resideInAnyPackage("org.apache.geode.logging..", "org.apache.geode.internal.logging..")
+      .should()
+      .onlyDependOnClassesThat(not(resideInAPackage("org.apache.geode.logging.log4j..")));
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/ConfigurationTest.java b/geode-core/src/test/java/org/apache/geode/logging/internal/ConfigurationTest.java
similarity index 92%
rename from geode-core/src/test/java/org/apache/geode/internal/logging/ConfigurationTest.java
rename to geode-core/src/test/java/org/apache/geode/logging/internal/ConfigurationTest.java
index 39c7984..ea664b5 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/ConfigurationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/ConfigurationTest.java
@@ -12,11 +12,11 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-import static org.apache.geode.internal.logging.Configuration.LOG_LEVEL_UPDATE_OCCURS_PROPERTY;
-import static org.apache.geode.internal.logging.Configuration.LOG_LEVEL_UPDATE_SCOPE_PROPERTY;
-import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.Configuration.LOG_LEVEL_UPDATE_OCCURS_PROPERTY;
+import static org.apache.geode.logging.internal.Configuration.LOG_LEVEL_UPDATE_SCOPE_PROPERTY;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.isA;
@@ -33,6 +33,11 @@ import org.junit.Test;
 import org.junit.contrib.java.lang.system.RestoreSystemProperties;
 import org.junit.experimental.categories.Category;
 
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateScope;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
@@ -41,7 +46,7 @@ import org.apache.geode.test.junit.categories.LoggingTest;
 @Category(LoggingTest.class)
 public class ConfigurationTest {
 
-  private ProviderAgent providerAgent;
+  private LoggingProvider loggingProvider;
   private LogConfig logConfig;
   private LogConfigSupplier logConfigSupplier;
   private Configuration configuration;
@@ -51,10 +56,10 @@ public class ConfigurationTest {
 
   @Before
   public void setUp() {
-    providerAgent = mock(ProviderAgent.class);
+    loggingProvider = mock(LoggingProvider.class);
     logConfig = mock(LogConfig.class);
     logConfigSupplier = mockLogConfigSupplier();
-    configuration = Configuration.create(providerAgent);
+    configuration = Configuration.create(loggingProvider);
   }
 
   @Test
@@ -114,7 +119,7 @@ public class ConfigurationTest {
   public void initializeConfiguresProviderAgent() {
     configuration.initialize(logConfigSupplier);
 
-    verify(providerAgent).configure(eq(logConfig), isA(LogLevelUpdateOccurs.class), isA(
+    verify(loggingProvider).configure(eq(logConfig), isA(LogLevelUpdateOccurs.class), isA(
         LogLevelUpdateScope.class));
   }
 
@@ -130,7 +135,7 @@ public class ConfigurationTest {
 
     configuration.configChanged();
 
-    verify(providerAgent, times(2)).configure(eq(logConfig), isA(LogLevelUpdateOccurs.class),
+    verify(loggingProvider, times(2)).configure(eq(logConfig), isA(LogLevelUpdateOccurs.class),
         isA(LogLevelUpdateScope.class));
   }
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexMatchesStartupConfigurationTest.java b/geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexMatchesStartupConfigurationTest.java
similarity index 83%
rename from geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexMatchesStartupConfigurationTest.java
rename to geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexMatchesStartupConfigurationTest.java
index 00dcb69..a380b0c 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexMatchesStartupConfigurationTest.java
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexMatchesStartupConfigurationTest.java
@@ -1,30 +1,32 @@
 /*
- * 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
  *
- * 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.
  */
-package org.apache.geode.internal.logging;
-
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.DATE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.LOG_LEVEL;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MEMBER_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MESSAGE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_ID;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME_ZONE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.values;
-import static org.apache.geode.internal.logging.LogMessageRegex.getPattern;
-import static org.apache.geode.internal.logging.LogMessageRegex.getRegex;
+package org.apache.geode.logging.internal;
+
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.DATE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.LOG_LEVEL;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MEMBER_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MESSAGE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_ID;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME_ZONE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.values;
+import static org.apache.geode.logging.internal.LogMessageRegex.getPattern;
+import static org.apache.geode.logging.internal.LogMessageRegex.getRegex;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.regex.Matcher;
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexTest.java b/geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexTest.java
similarity index 83%
rename from geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexTest.java
rename to geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexTest.java
index 5c77a52..7485791 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LogMessageRegexTest.java
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/LogMessageRegexTest.java
@@ -1,30 +1,32 @@
 /*
- * 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
  *
- * 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.
  */
-package org.apache.geode.internal.logging;
-
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.DATE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.LOG_LEVEL;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MEMBER_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.MESSAGE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_ID;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.THREAD_NAME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.TIME_ZONE;
-import static org.apache.geode.internal.logging.LogMessageRegex.Group.values;
-import static org.apache.geode.internal.logging.LogMessageRegex.getPattern;
-import static org.apache.geode.internal.logging.LogMessageRegex.getRegex;
+package org.apache.geode.logging.internal;
+
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.DATE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.LOG_LEVEL;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MEMBER_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.MESSAGE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_ID;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.THREAD_NAME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.TIME_ZONE;
+import static org.apache.geode.logging.internal.LogMessageRegex.Group.values;
+import static org.apache.geode.logging.internal.LogMessageRegex.getPattern;
+import static org.apache.geode.logging.internal.LogMessageRegex.getRegex;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.regex.Matcher;
diff --git a/geode-core/src/test/java/org/apache/geode/logging/internal/LoggingProviderLoaderTest.java b/geode-core/src/test/java/org/apache/geode/logging/internal/LoggingProviderLoaderTest.java
new file mode 100644
index 0000000..67304a9
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/LoggingProviderLoaderTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.logging.internal;
+
+import static org.apache.geode.logging.internal.LoggingProviderLoader.LOGGING_PROVIDER_NAME_PROPERTY;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.logging.log4j.Logger;
+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.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateOccurs;
+import org.apache.geode.logging.internal.spi.LogLevelUpdateScope;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
+import org.apache.geode.test.junit.categories.LoggingTest;
+
+/**
+ * Unit tests for {@link LoggingProviderLoader}.
+ */
+@Category(LoggingTest.class)
+public class LoggingProviderLoaderTest {
+
+  private LoggingProviderLoader loggingProviderLoader;
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+  @Before
+  public void setUp() {
+    loggingProviderLoader = new LoggingProviderLoader();
+  }
+
+  @Test
+  public void createProviderAgent_usesSystemPropertySetTo_NullProviderAgent() {
+    System.setProperty(LOGGING_PROVIDER_NAME_PROPERTY, SimpleLoggingProvider.class.getName());
+
+    LoggingProvider value = loggingProviderLoader.load();
+
+    assertThat(value).isInstanceOf(SimpleLoggingProvider.class);
+  }
+
+  @Test
+  public void createProviderAgent_usesSystemPropertySetTo_SimpleProviderAgent() {
+    System.setProperty(LOGGING_PROVIDER_NAME_PROPERTY, TestLoggingProvider.class.getName());
+
+    LoggingProvider value = loggingProviderLoader.load();
+
+    assertThat(value).isInstanceOf(TestLoggingProvider.class);
+  }
+
+  @Test
+  public void createProviderAgent_usesNullProviderAgent_whenClassNotFoundException() {
+    System.setProperty(LOGGING_PROVIDER_NAME_PROPERTY, TestLoggingProvider.class.getSimpleName());
+
+    LoggingProvider value = loggingProviderLoader.load();
+
+    assertThat(value).isInstanceOf(SimpleLoggingProvider.class);
+  }
+
+  @Test
+  public void createProviderAgent_usesNullProviderAgent_whenClassCastException() {
+    System.setProperty(LOGGING_PROVIDER_NAME_PROPERTY, NotProviderAgent.class.getName());
+
+    LoggingProvider value = loggingProviderLoader.load();
+
+    assertThat(value).isInstanceOf(SimpleLoggingProvider.class);
+  }
+
+  static class TestLoggingProvider implements LoggingProvider {
+
+    @Override
+    public void configure(LogConfig logConfig,
+        LogLevelUpdateOccurs logLevelUpdateOccurs,
+        LogLevelUpdateScope logLevelUpdateScope) {
+      // nothing
+    }
+
+    @Override
+    public void cleanup() {
+      // nothing
+    }
+
+    @Override
+    public Logger getLogger(String name) {
+      return null;
+    }
+
+    @Override
+    public int getPriority() {
+      return Integer.MAX_VALUE;
+    }
+  }
+
+  @SuppressWarnings("all")
+  static class NotProviderAgent {
+
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingSessionTest.java b/geode-core/src/test/java/org/apache/geode/logging/internal/LoggingSessionTest.java
similarity index 88%
rename from geode-core/src/test/java/org/apache/geode/internal/logging/LoggingSessionTest.java
rename to geode-core/src/test/java/org/apache/geode/logging/internal/LoggingSessionTest.java
index 4581a36..ef16779 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/logging/LoggingSessionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/LoggingSessionTest.java
@@ -12,9 +12,9 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.apache.geode.internal.logging;
+package org.apache.geode.logging.internal;
 
-import static org.apache.geode.internal.logging.LogWriterLevel.INFO;
+import static org.apache.geode.logging.internal.spi.LogWriterLevel.INFO;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.eq;
@@ -31,6 +31,8 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.mockito.InOrder;
 
+import org.apache.geode.logging.internal.spi.LogConfig;
+import org.apache.geode.logging.internal.spi.LogConfigSupplier;
 import org.apache.geode.test.junit.categories.LoggingTest;
 
 /**
@@ -39,7 +41,7 @@ import org.apache.geode.test.junit.categories.LoggingTest;
 @Category(LoggingTest.class)
 public class LoggingSessionTest {
 
-  private LoggingSessionListeners loggingSessionListeners;
+  private LoggingSessionNotifier loggingSessionNotifier;
   private LogConfigSupplier logConfigSupplier;
   private Configuration configuration;
 
@@ -47,7 +49,7 @@ public class LoggingSessionTest {
 
   @Before
   public void setUp() {
-    loggingSessionListeners = spy(new LoggingSessionListeners());
+    loggingSessionNotifier = spy(new LoggingSessionRegistryProvider());
     logConfigSupplier = spy(LogConfigSupplier.class);
     configuration = spy(Configuration.create());
     LogConfig config = mock(LogConfig.class);
@@ -57,15 +59,15 @@ public class LoggingSessionTest {
     when(config.getLogLevel()).thenReturn(INFO.intLevel());
     when(config.getSecurityLogLevel()).thenReturn(INFO.intLevel());
 
-    loggingSession = LoggingSession.create(configuration, loggingSessionListeners);
+    loggingSession = LoggingSession.create(configuration, loggingSessionNotifier);
   }
 
   @Test
   public void createUsesLoggingSessionListenersGetByDefault() {
     loggingSession = LoggingSession.create();
 
-    assertThat(loggingSession.getLoggingSessionListeners())
-        .isEqualTo(LoggingSessionListeners.get());
+    assertThat(loggingSession.getLoggingSessionNotifier())
+        .isEqualTo(LoggingSessionRegistryProvider.get());
   }
 
   @Test
@@ -95,10 +97,10 @@ public class LoggingSessionTest {
   public void createSessionPublishesConfigBeforeCreatingLoggingSession() {
     loggingSession.createSession(logConfigSupplier);
 
-    InOrder inOrder = inOrder(configuration, loggingSessionListeners);
+    InOrder inOrder = inOrder(configuration, loggingSessionNotifier);
     inOrder.verify(configuration).initialize(eq(logConfigSupplier));
     inOrder.verify(configuration).configChanged();
-    inOrder.verify(loggingSessionListeners).createSession(eq(loggingSession));
+    inOrder.verify(loggingSessionNotifier).createSession(eq(loggingSession));
     inOrder.verifyNoMoreInteractions();
   }
 
@@ -113,7 +115,7 @@ public class LoggingSessionTest {
   public void createSessionNotifiesLoggingSessionListeners() {
     loggingSession.createSession(logConfigSupplier);
 
-    verify(loggingSessionListeners).createSession(eq(loggingSession));
+    verify(loggingSessionNotifier).createSession(eq(loggingSession));
   }
 
   @Test
@@ -139,7 +141,7 @@ public class LoggingSessionTest {
 
     loggingSession.startSession();
 
-    verify(loggingSessionListeners).startSession();
+    verify(loggingSessionNotifier).startSession();
   }
 
   @Test
@@ -174,7 +176,7 @@ public class LoggingSessionTest {
 
     loggingSession.stopSession();
 
-    verify(loggingSessionListeners).stopSession();
+    verify(loggingSessionNotifier).stopSession();
   }
 
   @Test
diff --git a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/DebuggableAppender.java b/geode-core/src/test/java/org/apache/geode/logging/internal/SimpleLoggingProviderTest.java
similarity index 56%
rename from geode-core/src/main/java/org/apache/geode/internal/logging/log4j/DebuggableAppender.java
rename to geode-core/src/test/java/org/apache/geode/logging/internal/SimpleLoggingProviderTest.java
index 1aaac1b..ba877b6 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/logging/log4j/DebuggableAppender.java
+++ b/geode-core/src/test/java/org/apache/geode/logging/internal/SimpleLoggingProviderTest.java
@@ -14,15 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.geode.internal.logging.log4j;
+package org.apache.geode.logging.internal;
 
-import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.logging.log4j.core.LogEvent;
+import org.junit.Before;
+import org.junit.Test;
 
-public interface DebuggableAppender {
+/**
+ * Unit tests for {@link SimpleLoggingProvider}.
+ */
+public class SimpleLoggingProviderTest {
+
+  private SimpleLoggingProvider nullProviderAgent;
+
+  @Before
+  public void setUp() {
+    nullProviderAgent = new SimpleLoggingProvider();
+  }
 
-  void clearLogEvents();
+  @Test
+  public void getConfigurationInfoReturnsClassName() {
+    String configurationInfo = nullProviderAgent.getConfigurationInfo();
 
-  List<LogEvent> getLogEvents();
+    assertThat(configurationInfo).isEqualTo(SimpleLoggingProvider.class.getName());
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/management/bean/stats/MemberLevelStatsTest.java b/geode-core/src/test/java/org/apache/geode/management/bean/stats/MemberLevelStatsTest.java
index d450e87..e1f4c28 100644
--- a/geode-core/src/test/java/org/apache/geode/management/bean/stats/MemberLevelStatsTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/bean/stats/MemberLevelStatsTest.java
@@ -39,12 +39,12 @@ import org.apache.geode.internal.cache.CachePerfStats;
 import org.apache.geode.internal.cache.DiskStoreStats;
 import org.apache.geode.internal.cache.PartitionedRegionStats;
 import org.apache.geode.internal.cache.execute.FunctionServiceStats;
-import org.apache.geode.internal.logging.LogFile;
 import org.apache.geode.internal.statistics.GemFireStatSampler;
 import org.apache.geode.internal.statistics.StatSamplerStats;
 import org.apache.geode.internal.statistics.StatisticsConfig;
 import org.apache.geode.internal.statistics.StatisticsManager;
 import org.apache.geode.internal.statistics.StatisticsRegistry;
+import org.apache.geode.logging.internal.spi.LogFile;
 import org.apache.geode.management.internal.beans.MemberMBeanBridge;
 import org.apache.geode.test.junit.categories.JMXTest;
 import org.apache.geode.test.junit.categories.StatisticsTest;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
index b70c5f9..b776bed 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
@@ -28,11 +28,11 @@ import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.StatisticsFactory;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.Region;
 import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.internal.alerting.AlertLevel;
 import org.apache.geode.internal.cache.HasCachePerfStats;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalCacheForClientAccess;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/LocalManagerTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/LocalManagerTest.java
index 1813a92..d9516d3 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/LocalManagerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/LocalManagerTest.java
@@ -28,12 +28,12 @@ import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.StatisticsFactory;
+import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.Region;
 import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.internal.alerting.AlertLevel;
 import org.apache.geode.internal.cache.HasCachePerfStats;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalCacheForClientAccess;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
index 00d02d3..6d94939 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/ExportLogsFunctionTest.java
@@ -23,7 +23,7 @@ import org.apache.logging.log4j.Level;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import org.apache.geode.internal.logging.log4j.LogLevel;
+import org.apache.geode.logging.internal.log4j.LogLevel;
 import org.apache.geode.management.internal.cli.commands.ExportLogsCommand;
 import org.apache.geode.test.junit.categories.GfshTest;
 import org.apache.geode.test.junit.categories.LoggingTest;
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshInitFileJUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshInitFileJUnitTest.java
index a533aeb..db8ce8b 100755
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshInitFileJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/shell/GfshInitFileJUnitTest.java
@@ -89,7 +89,7 @@ public class GfshInitFileJUnitTest {
       julLogger.removeHandler(handler);
     }
 
-    File log4j2XML = temporaryFolder_Config.newFile("log4j2.xml");
+    File log4j2XML = temporaryFolder_Config.newFile("log4j2-ignore.xml");
     FileUtils.writeStringToFile(log4j2XML, "<Configuration/>", APPEND);
     System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY,
         log4j2XML.toURI().toString());
diff --git a/geode-core/src/test/resources/expected-pom.xml b/geode-core/src/test/resources/expected-pom.xml
index 16f7a75..1e3bb4f 100644
--- a/geode-core/src/test/resources/expected-pom.xml
+++ b/geode-core/src/test/resources/expected-pom.xml
@@ -221,12 +221,6 @@
       <scope>runtime</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-      <scope>runtime</scope>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
       <scope>runtime</scope>
@@ -281,30 +275,6 @@
       <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-      <scope>runtime</scope>
-      <exclusions>
-        <exclusion>
-          <artifactId>slf4j-api</artifactId>
-          <groupId>*</groupId>
-        </exclusion>
-      </exclusions>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-jcl</artifactId>
-      <scope>runtime</scope>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-jul</artifactId>
-      <scope>runtime</scope>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
       <groupId>io.swagger</groupId>
       <artifactId>swagger-annotations</artifactId>
       <scope>runtime</scope>
diff --git a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml b/geode-core/src/test/resources/log4j2-ignore.xml
similarity index 83%
copy from geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml
copy to geode-core/src/test/resources/log4j2-ignore.xml
index 58aaa1c..fed494c 100644
--- a/geode-core/src/integrationTest/resources/org/apache/geode/internal/logging/log4j/ConsoleAppenderWithLoggerContextRuleIntegrationTest_log4j2.xml
+++ b/geode-core/src/test/resources/log4j2-ignore.xml
@@ -13,9 +13,10 @@
   ~ or implied. See the License for the specific language governing permissions and limitations under
   ~ the License.
   -->
-<Configuration status="INFO" shutdownHook="disable" packages="org.apache.geode.internal.logging.log4j,org.apache.logging.log4j.test.appender">
+<Configuration status="WARN" shutdownHook="disable">
     <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} &lt;%thread&gt; tid=%threadId] %message%n%throwable%n</Property>
+        <Property name="geode-default">true</Property>
     </Properties>
     <Appenders>
         <Console name="STDOUT" target="SYSTEM_OUT">
@@ -31,8 +32,6 @@
         </Logger>
         <Logger name="org.jgroups" level="FATAL" additivity="true"/>
         <Logger name="org.eclipse.jetty" level="FATAL" additivity="true"/>
-        <Root level="INFO">
-            <AppenderRef ref="STDOUT"/>
-        </Root>
+        <Root level="INFO"/>
     </Loggers>
 </Configuration>
diff --git a/geode-core/src/test/resources/org/apache/geode/test/golden/log4j2-test.xml b/geode-core/src/test/resources/org/apache/geode/test/golden/log4j2-test.xml
index 32eac1a..b9e542a 100755
--- a/geode-core/src/test/resources/org/apache/geode/test/golden/log4j2-test.xml
+++ b/geode-core/src/test/resources/org/apache/geode/test/golden/log4j2-test.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">
+<Configuration status="WARN" shutdownHook="disable" packages="org.apache.geode">
   <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/upgradeTest/java/org/apache/geode/internal/cache/rollingupgrade/RollingUpgradeDUnitTest.java b/geode-core/src/upgradeTest/java/org/apache/geode/internal/cache/rollingupgrade/RollingUpgradeDUnitTest.java
index d7313ba..089b4ff 100644
--- a/geode-core/src/upgradeTest/java/org/apache/geode/internal/cache/rollingupgrade/RollingUpgradeDUnitTest.java
+++ b/geode-core/src/upgradeTest/java/org/apache/geode/internal/cache/rollingupgrade/RollingUpgradeDUnitTest.java
@@ -29,6 +29,9 @@ import java.util.Properties;
 import org.apache.commons.io.FileUtils;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
 
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheFactory;
@@ -53,7 +56,6 @@ import org.apache.geode.test.dunit.DistributedTestUtils;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.IgnoredException;
 import org.apache.geode.test.dunit.Invoke;
-import org.apache.geode.test.dunit.LogWriterUtils;
 import org.apache.geode.test.dunit.NetworkUtils;
 import org.apache.geode.test.dunit.VM;
 import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
@@ -77,28 +79,28 @@ import org.apache.geode.test.version.VersionManager;
  */
 
 @RunWith(Parameterized.class)
-@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
+@UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
 public abstract class RollingUpgradeDUnitTest extends JUnit4DistributedTestCase {
-  @Parameterized.Parameters(name = "from_v{0}")
+
+  @Parameters(name = "from_v{0}")
   public static Collection<String> data() {
     List<String> result = VersionManager.getInstance().getVersionsWithoutCurrent();
     if (result.size() < 1) {
       throw new RuntimeException("No older versions of Geode were found to test against");
-    } else {
-      System.out.println("running against these versions: " + result);
     }
+    System.out.println("running against these versions: " + result);
     return result;
   }
 
-  private File[] testingDirs = new File[2];
+  private final File[] testingDirs = new File[2];
 
-  private static String diskDir = "RollingUpgradeDUnitTest";
+  private static final String diskDir = "RollingUpgradeDUnitTest";
 
   // Each vm will have a cache object
   private static Cache cache;
 
   // the old version of Geode we're testing against
-  @Parameterized.Parameter
+  @Parameter
   public String oldVersion;
 
   private void deleteVMFiles() {
@@ -706,7 +708,6 @@ public abstract class RollingUpgradeDUnitTest extends JUnit4DistributedTestCase
       throws Exception {
     props.setProperty(DistributionConfig.MCAST_PORT_NAME, "0");
     props.setProperty(DistributionConfig.LOCATORS_NAME, locatorsString);
-    props.setProperty(DistributionConfig.LOG_LEVEL_NAME, LogWriterUtils.getDUnitLogLevel());
     props.setProperty(DistributionConfig.NAME_NAME, "vm" + VM.getCurrentVMNum());
 
     InetAddress bindAddr = null;
diff --git a/geode-docs/managing/logging/how_logging_works.html.md.erb b/geode-docs/managing/logging/how_logging_works.html.md.erb
index defd5cf..1118922 100644
--- a/geode-docs/managing/logging/how_logging_works.html.md.erb
+++ b/geode-docs/managing/logging/how_logging_works.html.md.erb
@@ -21,7 +21,7 @@ limitations under the License.
 
 <%=vars.product_name%> uses [Apache Log4j 2](http://logging.apache.org/log4j/2.x/) API and Core libraries as the basis for its logging system. Log4j 2 API is a popular and powerful front-end logging API used by all the <%=vars.product_name%> classes to generate log statements. Log4j 2 Core is a backend implementation for logging; you can route any of the front-end logging API libraries to log to this backend. <%=vars.product_name%> uses the Core backend to run two custom Log4j 2 Appender [...]
 
-<%=vars.product_name%> has been tested with Log4j 2.11.
+<%=vars.product_name%> has been tested with Log4j 2.12.
 <%=vars.product_name%> requires the 
 `log4j-api-2.11.0.jar` and `log4j-core-2.11.0.jar`
 JAR files to be in the classpath.
diff --git a/geode-dunit/build.gradle b/geode-dunit/build.gradle
index f7330dc..750fe00 100755
--- a/geode-dunit/build.gradle
+++ b/geode-dunit/build.gradle
@@ -24,6 +24,9 @@ dependencies {
   compile(platform(project(':boms:geode-all-bom')))
   implementation(project(':geode-serialization'))
   compile(project(':geode-core'))
+  implementation(project(':geode-log4j')) {
+    exclude module: 'geode-core'
+  }
 
   compile(project(':geode-junit')) {
     exclude module: 'geode-core'
@@ -31,7 +34,6 @@ dependencies {
 
   compile('com.jayway.jsonpath:json-path')
   compile('org.apache.logging.log4j:log4j-api')
-  compile('org.apache.logging.log4j:log4j-core')
   compile('commons-io:commons-io')
   compile('org.apache.commons:commons-lang3')
   compile('org.springframework.shell:spring-shell') {
@@ -58,7 +60,6 @@ dependencies {
     exclude module: 'hamcrest-core'
   }
 
-
   distributedTestRuntime(project(':geode-old-versions'))
 }
 
diff --git a/geode-dunit/src/main/java/org/apache/geode/security/SecurityTestUtils.java b/geode-dunit/src/main/java/org/apache/geode/security/SecurityTestUtils.java
index 6f34aaf..2e744e0 100644
--- a/geode-dunit/src/main/java/org/apache/geode/security/SecurityTestUtils.java
+++ b/geode-dunit/src/main/java/org/apache/geode/security/SecurityTestUtils.java
@@ -32,7 +32,7 @@ import static org.apache.geode.test.dunit.Assert.assertNull;
 import static org.apache.geode.test.dunit.Assert.assertTrue;
 import static org.apache.geode.test.dunit.Assert.fail;
 import static org.apache.geode.test.dunit.DistributedTestUtils.getDUnitLocatorPort;
-import static org.apache.geode.test.dunit.LogWriterUtils.getLogWriter;
+import static org.apache.geode.test.dunit.IgnoredException.addIgnoredException;
 import static org.apache.geode.test.dunit.NetworkUtils.getIPLiteral;
 
 import java.io.File;
@@ -59,6 +59,9 @@ import javax.net.ssl.SSLServerSocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 import org.apache.geode.cache.AttributesFactory;
 import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheFactory;
@@ -106,6 +109,7 @@ import org.apache.geode.test.version.VersionManager;
  */
 @Deprecated
 public class SecurityTestUtils {
+  private static final Logger logger = LogManager.getLogger();
 
   private final JUnit4DistributedTestCase distributedTestCase = new JUnit4DistributedTestCase() {};
 
@@ -143,30 +147,6 @@ public class SecurityTestUtils {
 
   private static Region regionRef = null;
 
-  /**
-   * @deprecated Please use {@link org.apache.geode.test.dunit.IgnoredException} instead
-   */
-  private static void addIgnoredExceptions(final String[] expectedExceptions) { // TODO: delete
-    if (expectedExceptions != null) {
-      for (int index = 0; index < expectedExceptions.length; index++) {
-        getLogWriter().info(
-            "<ExpectedException action=add>" + expectedExceptions[index] + "</ExpectedException>");
-      }
-    }
-  }
-
-  /**
-   * @deprecated Please use {@link org.apache.geode.test.dunit.IgnoredException} instead
-   */
-  private static void removeExpectedExceptions(final String[] expectedExceptions) { // TODO: delete
-    if (expectedExceptions != null) {
-      for (int index = 0; index < expectedExceptions.length; index++) {
-        getLogWriter().info("<ExpectedException action=remove>" + expectedExceptions[index]
-            + "</ExpectedException>");
-      }
-    }
-  }
-
   protected static void setJavaProps(final Properties javaProps) {
     removeJavaProperties(currentJavaProps);
     addJavaProperties(javaProps);
@@ -215,15 +195,15 @@ public class SecurityTestUtils {
     authProps.setProperty(LOCATORS, "localhost[" + getDUnitLocatorPort() + "]");
     authProps.setProperty(SECURITY_LOG_LEVEL, "finest");
 
-    getLogWriter().info("Set the server properties to: " + authProps);
-    getLogWriter().info("Set the java properties to: " + javaProps);
+    logger.info("Set the server properties to: " + authProps);
+    logger.info("Set the java properties to: " + javaProps);
 
     SecurityTestUtils tmpInstance = new SecurityTestUtils();
     try {
       tmpInstance.createSystem(authProps, javaProps);
     } catch (AuthenticationRequiredException ex) {
       if (expectedResult == AUTHREQ_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting peer: " + ex);
+        logger.info("Got expected exception when starting peer: " + ex);
         return 0;
       } else {
         fail("Got unexpected exception when starting peer", ex);
@@ -231,7 +211,7 @@ public class SecurityTestUtils {
 
     } catch (AuthenticationFailedException ex) {
       if (expectedResult == AUTHFAIL_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting peer: " + ex);
+        logger.info("Got expected exception when starting peer: " + ex);
         return 0;
       } else {
         fail("Got unexpected exception when starting peer", ex);
@@ -264,7 +244,7 @@ public class SecurityTestUtils {
       server1.start();
     } catch (AuthenticationRequiredException ex) {
       if (expectedResult == AUTHREQ_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting server: " + ex);
+        logger.info("Got expected exception when starting server: " + ex);
         return 0;
       } else {
         fail("Got unexpected exception when starting server", ex);
@@ -370,7 +350,7 @@ public class SecurityTestUtils {
 
       tmpInstance.openCache();
       try {
-        getLogWriter().info("multi-user mode " + multiUserAuthMode);
+        logger.info("multi-user mode " + multiUserAuthMode);
         proxyCaches[0] = (ProxyCache) ((PoolImpl) pool).createAuthenticatedCacheView(authProps);
         if (!multiUserAuthMode) {
           fail("Expected a UnsupportedOperationException but got none in single-user mode");
@@ -378,7 +358,7 @@ public class SecurityTestUtils {
 
       } catch (UnsupportedOperationException uoe) {
         if (!multiUserAuthMode) {
-          getLogWriter().info("Got expected UnsupportedOperationException in single-user mode");
+          logger.info("Got expected UnsupportedOperationException in single-user mode");
         } else {
           fail("Got unexpected exception in multi-user mode ", uoe);
         }
@@ -401,28 +381,28 @@ public class SecurityTestUtils {
 
     } catch (AuthenticationRequiredException ex) {
       if (expectedResult == AUTHREQ_EXCEPTION || expectedResult == NOFORCE_AUTHREQ_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
 
     } catch (AuthenticationFailedException ex) {
       if (expectedResult == AUTHFAIL_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
 
     } catch (ServerRefusedConnectionException ex) {
       if (expectedResult == CONNREFUSED_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
 
     } catch (GemFireSecurityException ex) {
       if (expectedResult == SECURITY_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
@@ -523,21 +503,21 @@ public class SecurityTestUtils {
 
     } catch (AuthenticationRequiredException ex) {
       if (expectedResult == AUTHREQ_EXCEPTION || expectedResult == NOFORCE_AUTHREQ_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
 
     } catch (AuthenticationFailedException ex) {
       if (expectedResult == AUTHFAIL_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
 
     } catch (ServerRefusedConnectionException ex) {
       if (expectedResult == CONNREFUSED_EXCEPTION) {
-        getLogWriter().info("Got expected exception when starting client: " + ex);
+        logger.info("Got expected exception when starting client: " + ex);
       } else {
         fail("Got unexpected exception when starting client", ex);
       }
@@ -574,7 +554,11 @@ public class SecurityTestUtils {
       File logFile = new File(name + "-locator" + port + ".log");
       FileOutputStream logOut = new FileOutputStream(logFile);
       PrintStream logStream = new PrintStream(logOut);
-      addIgnoredExceptions(expectedExceptions);
+      if (ignoredExceptions != null) {
+        for (String expectedException : expectedExceptions) {
+          addIgnoredException(expectedException);
+        }
+      }
       logStream.flush();
 
       locator = Locator.startLocatorAndDS(port, logFile, null, authProps);
@@ -587,7 +571,6 @@ public class SecurityTestUtils {
   protected static void stopLocator(final int port, final String[] expectedExceptions) {
     try {
       locator.stop();
-      removeExpectedExceptions(expectedExceptions);
 
     } catch (Exception ex) {
       fail("While stopping locator on port " + port, ex);
@@ -651,7 +634,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("PUT: MultiUser# " + i);
+      logger.info("PUT: MultiUser# " + i);
       doPutsP(num, i, expectedResults[i], false);
     }
   }
@@ -676,7 +659,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("GET_ALL" + (useTX ? " in TX" : "") + ": MultiUser# " + i);
+      logger.info("GET_ALL" + (useTX ? " in TX" : "") + ": MultiUser# " + i);
       doGetAllP(i, expectedResults[i], useTX);
     }
   }
@@ -689,7 +672,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("GET: MultiUser# " + i);
+      logger.info("GET: MultiUser# " + i);
       doGetsP(num, i, expectedResults[i], false);
     }
   }
@@ -702,7 +685,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = numOfUsers - 1; i >= 0; i--) {
-      getLogWriter().info("DESTROY: MultiUser# " + i);
+      logger.info("DESTROY: MultiUser# " + i);
       doRegionDestroysP(i, expectedResults[i]);
     }
   }
@@ -715,7 +698,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("DESTROY: MultiUser# " + i);
+      logger.info("DESTROY: MultiUser# " + i);
       doDestroysP(num, i, expectedResults[i]);
     }
   }
@@ -728,7 +711,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("INVALIDATE: MultiUser# " + i);
+      logger.info("INVALIDATE: MultiUser# " + i);
       doInvalidatesP(num, i, expectedResults[i]);
     }
   }
@@ -746,7 +729,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("CONTAINS_KEY: MultiUser# " + i);
+      logger.info("CONTAINS_KEY: MultiUser# " + i);
       doContainsKeysP(num, i, expectedResults[i], results[i]);
     }
   }
@@ -759,7 +742,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("QUERY: MultiUser# " + i);
+      logger.info("QUERY: MultiUser# " + i);
       doQueriesP(i, expectedResults[i], valueSize);
     }
   }
@@ -772,18 +755,18 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("FunctionExecute:onRegion MultiUser# " + i);
+      logger.info("FunctionExecute:onRegion MultiUser# " + i);
       doFunctionExecuteP(i, function, expectedResults[i], "region");
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("FunctionExecute:onServer MultiUser# " + i);
+      logger.info("FunctionExecute:onServer MultiUser# " + i);
       doFunctionExecuteP(i, function, expectedResults[i], "server");
     }
 
     if (!isFailOverCase) {
       for (int i = 0; i < numOfUsers; i++) {
-        getLogWriter().info("FunctionExecute:onServers MultiUser# " + i);
+        logger.info("FunctionExecute:onServers MultiUser# " + i);
         doFunctionExecuteP(i, function, expectedResults[i], "servers");
       }
     }
@@ -797,7 +780,7 @@ public class SecurityTestUtils {
     }
 
     for (int i = 0; i < numOfUsers; i++) {
-      getLogWriter().info("QueryExecute: MultiUser# " + i);
+      logger.info("QueryExecute: MultiUser# " + i);
       doQueryExecuteP(i, expectedResults[i], result);
     }
   }
@@ -839,7 +822,7 @@ public class SecurityTestUtils {
           fail("Expected " + expectedResult + " but found " + e.getClass().getSimpleName()
               + " in doSimpleGet()");
         } else {
-          getLogWriter().fine("Got expected " + e.getClass().getSimpleName() + " in doSimpleGet()");
+          logger.debug("Got expected " + e.getClass().getSimpleName() + " in doSimpleGet()");
         }
       }
     }
@@ -858,7 +841,7 @@ public class SecurityTestUtils {
           fail("Expected " + expectedResult + " but found " + e.getClass().getSimpleName()
               + " in doSimplePut()", e);
         } else {
-          getLogWriter().fine("Got expected " + e.getClass().getSimpleName() + " in doSimplePut()");
+          logger.debug("Got expected " + e.getClass().getSimpleName() + " in doSimplePut()");
         }
       }
     }
@@ -903,8 +886,6 @@ public class SecurityTestUtils {
   }
 
   protected static void closeCache() {
-    removeExpectedExceptions(ignoredExceptions);
-
     if (cache != null && !cache.isClosed()) {
       DistributedSystem sys = cache.getDistributedSystem();
       cache.close();
@@ -916,8 +897,6 @@ public class SecurityTestUtils {
   }
 
   protected static void closeCache(final Boolean keepAlive) {
-    removeExpectedExceptions(ignoredExceptions);
-
     if (cache != null && !cache.isClosed()) {
       DistributedSystem sys = cache.getDistributedSystem();
       cache.close(keepAlive);
@@ -1007,7 +986,7 @@ public class SecurityTestUtils {
 
       } catch (NoAvailableServersException ex) {
         if (expectedResult == NO_AVAILABLE_SERVERS) {
-          getLogWriter().info("Got expected NoAvailableServers when doing puts: " + ex.getCause());
+          logger.info("Got expected NoAvailableServers when doing puts: " + ex.getCause());
           continue;
         } else {
           fail("Got unexpected exception when doing puts", ex);
@@ -1016,32 +995,32 @@ public class SecurityTestUtils {
       } catch (ServerConnectivityException ex) {
         if ((expectedResult == NOTAUTHZ_EXCEPTION)
             && (ex.getCause() instanceof NotAuthorizedException)) {
-          getLogWriter()
+          logger
               .info("Got expected NotAuthorizedException when doing puts: " + ex.getCause());
           continue;
         }
 
         if ((expectedResult == AUTHREQ_EXCEPTION)
             && (ex.getCause() instanceof AuthenticationRequiredException)) {
-          getLogWriter().info(
+          logger.info(
               "Got expected AuthenticationRequiredException when doing puts: " + ex.getCause());
           continue;
         }
 
         if ((expectedResult == AUTHFAIL_EXCEPTION)
             && (ex.getCause() instanceof AuthenticationFailedException)) {
-          getLogWriter()
+          logger
               .info("Got expected AuthenticationFailedException when doing puts: " + ex.getCause());
           continue;
         } else if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing puts: " + ex);
+          logger.info("Got expected exception when doing puts: " + ex);
         } else {
           fail("Got unexpected exception when doing puts", ex);
         }
 
       } catch (Exception ex) {
         if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing puts: " + ex);
+          logger.info("Got expected exception when doing puts: " + ex);
         } else {
           fail("Got unexpected exception when doing puts", ex);
         }
@@ -1062,7 +1041,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception during getRegion: " + ex);
+        logger.info("Got expected exception during getRegion: " + ex);
       } else {
         fail("Got unexpected exception during getRegion", ex);
       }
@@ -1093,7 +1072,7 @@ public class SecurityTestUtils {
         }
 
       } catch (IllegalAccessException ex) {
-        getLogWriter().warning("Exception while getting SSL fields.", ex);
+        logger.warn("Exception while getting SSL fields.", ex);
       }
     }
     return resultFields;
@@ -1113,7 +1092,7 @@ public class SecurityTestUtils {
         assertNull(field.get(obj));
 
       } catch (IllegalAccessException ex) {
-        getLogWriter().warning("Exception while clearing SSL fields.", ex);
+        logger.warn("Exception while clearing SSL fields.", ex);
       }
     }
   }
@@ -1140,9 +1119,9 @@ public class SecurityTestUtils {
         }
 
       } catch (IllegalAccessException ex) {
-        getLogWriter().warning("Exception while clearing static SSL field.", ex);
+        logger.warn("Exception while clearing static SSL field.", ex);
       } catch (ClassCastException ex) {
-        getLogWriter().warning("Exception while clearing static SSL field.", ex);
+        logger.warn("Exception while clearing static SSL field.", ex);
       }
     }
   }
@@ -1160,7 +1139,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing query: " + ex);
+        logger.info("Got expected exception when executing query: " + ex);
       } else {
         fail("Got unexpected exception when executing query", ex);
       }
@@ -1184,7 +1163,7 @@ public class SecurityTestUtils {
 
     } catch (NoAvailableServersException ex) {
       if (expectedResult == NO_AVAILABLE_SERVERS) {
-        getLogWriter()
+        logger
             .info("Got expected NoAvailableServers when executing query: " + ex.getCause());
       } else {
         fail("Got unexpected exception when executing query", ex);
@@ -1193,17 +1172,17 @@ public class SecurityTestUtils {
     } catch (ServerConnectivityException ex) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (ex.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when executing query: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing query: " + ex);
+        logger.info("Got expected exception when executing query: " + ex);
       } else {
         fail("Got unexpected exception when executing query", ex);
       }
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing query: " + ex);
+        logger.info("Got expected exception when executing query: " + ex);
       } else {
         fail("Got unexpected exception when executing query", ex);
       }
@@ -1223,7 +1202,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing function: " + ex);
+        logger.info("Got expected exception when executing function: " + ex);
       } else {
         fail("Got unexpected exception when executing function", ex);
       }
@@ -1258,7 +1237,7 @@ public class SecurityTestUtils {
 
     } catch (NoAvailableServersException ex) {
       if (expectedResult == NO_AVAILABLE_SERVERS) {
-        getLogWriter()
+        logger
             .info("Got expected NoAvailableServers when executing function: " + ex.getCause());
       } else {
         fail("Got unexpected exception when executing function", ex);
@@ -1267,10 +1246,10 @@ public class SecurityTestUtils {
     } catch (ServerConnectivityException ex) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (ex.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when executing function: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing function: " + ex);
+        logger.info("Got expected exception when executing function: " + ex);
       } else {
         fail("Got unexpected exception when executing function", ex);
       }
@@ -1281,17 +1260,17 @@ public class SecurityTestUtils {
       if (expectedResult == NOTAUTHZ_EXCEPTION && (ex.getCause() instanceof NotAuthorizedException
           || (ex.getCause() instanceof ServerOperationException
               && ex.getCause().getCause() instanceof NotAuthorizedException))) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when executing function: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing function: " + ex);
+        logger.info("Got expected exception when executing function: " + ex);
       } else {
         fail("Got unexpected exception when executing function", ex);
       }
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when executing function: " + ex);
+        logger.info("Got expected exception when executing function: " + ex);
       } else {
         fail("Got unexpected exception when executing function", ex);
       }
@@ -1311,7 +1290,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing queries: " + ex);
+        logger.info("Got expected exception when doing queries: " + ex);
       } else {
         fail("Got unexpected exception when doing queries", ex);
       }
@@ -1328,7 +1307,7 @@ public class SecurityTestUtils {
 
     } catch (NoAvailableServersException ex) {
       if (expectedResult == NO_AVAILABLE_SERVERS) {
-        getLogWriter().info("Got expected NoAvailableServers when doing queries: " + ex.getCause());
+        logger.info("Got expected NoAvailableServers when doing queries: " + ex.getCause());
       } else {
         fail("Got unexpected exception when doing queries", ex);
       }
@@ -1336,10 +1315,10 @@ public class SecurityTestUtils {
     } catch (ServerConnectivityException ex) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (ex.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when doing queries: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing queries: " + ex);
+        logger.info("Got expected exception when doing queries: " + ex);
       } else {
         fail("Got unexpected exception when doing queries", ex);
       }
@@ -1347,17 +1326,17 @@ public class SecurityTestUtils {
     } catch (QueryInvocationTargetException qite) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (qite.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when doing queries: " + qite.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing queries: " + qite);
+        logger.info("Got expected exception when doing queries: " + qite);
       } else {
         fail("Got unexpected exception when doing queries", qite);
       }
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing queries: " + ex);
+        logger.info("Got expected exception when doing queries: " + ex);
       } else {
         fail("Got unexpected exception when doing queries", ex);
       }
@@ -1379,7 +1358,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+        logger.info("Got expected exception when doing containsKey: " + ex);
       } else {
         fail("Got unexpected exception when doing containsKey", ex);
       }
@@ -1396,7 +1375,7 @@ public class SecurityTestUtils {
 
       } catch (NoAvailableServersException ex) {
         if (expectedResult == NO_AVAILABLE_SERVERS) {
-          getLogWriter()
+          logger
               .info("Got expected NoAvailableServers when doing containsKey: " + ex.getCause());
           continue;
         } else {
@@ -1406,18 +1385,18 @@ public class SecurityTestUtils {
       } catch (ServerConnectivityException ex) {
         if ((expectedResult == NOTAUTHZ_EXCEPTION)
             && (ex.getCause() instanceof NotAuthorizedException)) {
-          getLogWriter()
+          logger
               .info("Got expected NotAuthorizedException when doing containsKey: " + ex.getCause());
           continue;
         } else if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+          logger.info("Got expected exception when doing containsKey: " + ex);
         } else {
           fail("Got unexpected exception when doing containsKey", ex);
         }
 
       } catch (Exception ex) {
         if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing containsKey: " + ex);
+          logger.info("Got expected exception when doing containsKey: " + ex);
         } else {
           fail("Got unexpected exception when doing containsKey", ex);
         }
@@ -1442,7 +1421,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+        logger.info("Got expected exception when doing invalidates: " + ex);
       } else {
         fail("Got unexpected exception when doing invalidates", ex);
       }
@@ -1457,7 +1436,7 @@ public class SecurityTestUtils {
 
       } catch (NoAvailableServersException ex) {
         if (expectedResult == NO_AVAILABLE_SERVERS) {
-          getLogWriter()
+          logger
               .info("Got expected NoAvailableServers when doing invalidates: " + ex.getCause());
           continue;
         } else {
@@ -1467,18 +1446,18 @@ public class SecurityTestUtils {
       } catch (ServerConnectivityException ex) {
         if ((expectedResult == NOTAUTHZ_EXCEPTION)
             && (ex.getCause() instanceof NotAuthorizedException)) {
-          getLogWriter()
+          logger
               .info("Got expected NotAuthorizedException when doing invalidates: " + ex.getCause());
           continue;
         } else if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+          logger.info("Got expected exception when doing invalidates: " + ex);
         } else {
           fail("Got unexpected exception when doing invalidates", ex);
         }
 
       } catch (Exception ex) {
         if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing invalidates: " + ex);
+          logger.info("Got expected exception when doing invalidates: " + ex);
         } else {
           fail("Got unexpected exception when doing invalidates", ex);
         }
@@ -1501,7 +1480,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing destroys: " + ex);
+        logger.info("Got expected exception when doing destroys: " + ex);
       } else {
         fail("Got unexpected exception when doing destroys", ex);
       }
@@ -1516,7 +1495,7 @@ public class SecurityTestUtils {
 
       } catch (NoAvailableServersException ex) {
         if (expectedResult == NO_AVAILABLE_SERVERS) {
-          getLogWriter()
+          logger
               .info("Got expected NoAvailableServers when doing destroys: " + ex.getCause());
           continue;
         } else {
@@ -1526,18 +1505,18 @@ public class SecurityTestUtils {
       } catch (ServerConnectivityException ex) {
         if ((expectedResult == NOTAUTHZ_EXCEPTION)
             && (ex.getCause() instanceof NotAuthorizedException)) {
-          getLogWriter()
+          logger
               .info("Got expected NotAuthorizedException when doing destroys: " + ex.getCause());
           continue;
         } else if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing destroys: " + ex);
+          logger.info("Got expected exception when doing destroys: " + ex);
         } else {
           fail("Got unexpected exception when doing destroys", ex);
         }
 
       } catch (Exception ex) {
         if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing destroys: " + ex);
+          logger.info("Got expected exception when doing destroys: " + ex);
         } else {
           fail("Got unexpected exception when doing destroys", ex);
         }
@@ -1557,7 +1536,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing region destroy: " + ex);
+        logger.info("Got expected exception when doing region destroy: " + ex);
       } else {
         fail("Got unexpected exception when doing region destroy", ex);
       }
@@ -1578,7 +1557,7 @@ public class SecurityTestUtils {
 
     } catch (NoAvailableServersException ex) {
       if (expectedResult == NO_AVAILABLE_SERVERS) {
-        getLogWriter()
+        logger
             .info("Got expected NoAvailableServers when doing region destroy: " + ex.getCause());
       } else {
         fail("Got unexpected exception when doing region destroy", ex);
@@ -1587,17 +1566,17 @@ public class SecurityTestUtils {
     } catch (ServerConnectivityException ex) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (ex.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter().info(
+        logger.info(
             "Got expected NotAuthorizedException when doing region destroy: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing region destroy: " + ex);
+        logger.info("Got expected exception when doing region destroy: " + ex);
       } else {
         fail("Got unexpected exception when doing region destroy", ex);
       }
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing region destroy: " + ex);
+        logger.info("Got expected exception when doing region destroy: " + ex);
       } else {
         fail("Got unexpected exception when doing region destroy", ex);
       }
@@ -1642,7 +1621,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing getAll: " + ex);
+        logger.info("Got expected exception when doing getAll: " + ex);
       } else {
         fail("Got unexpected exception when doing getAll", ex);
       }
@@ -1678,7 +1657,7 @@ public class SecurityTestUtils {
 
     } catch (NoAvailableServersException ex) {
       if (expectedResult == NO_AVAILABLE_SERVERS) {
-        getLogWriter().info("Got expected NoAvailableServers when doing getAll: " + ex.getCause());
+        logger.info("Got expected NoAvailableServers when doing getAll: " + ex.getCause());
       } else {
         fail("Got unexpected exception when doing getAll", ex);
       }
@@ -1686,17 +1665,17 @@ public class SecurityTestUtils {
     } catch (ServerConnectivityException ex) {
       if ((expectedResult == NOTAUTHZ_EXCEPTION)
           && (ex.getCause() instanceof NotAuthorizedException)) {
-        getLogWriter()
+        logger
             .info("Got expected NotAuthorizedException when doing getAll: " + ex.getCause());
       } else if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing getAll: " + ex);
+        logger.info("Got expected exception when doing getAll: " + ex);
       } else {
         fail("Got unexpected exception when doing getAll", ex);
       }
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing getAll: " + ex);
+        logger.info("Got expected exception when doing getAll: " + ex);
       } else {
         fail("Got unexpected exception when doing getAll", ex);
       }
@@ -1722,7 +1701,7 @@ public class SecurityTestUtils {
 
     } catch (Exception ex) {
       if (expectedResult == OTHER_EXCEPTION) {
-        getLogWriter().info("Got expected exception when doing gets: " + ex);
+        logger.info("Got expected exception when doing gets: " + ex);
       } else {
         fail("Got unexpected exception when doing gets", ex);
       }
@@ -1744,7 +1723,7 @@ public class SecurityTestUtils {
 
       } catch (NoAvailableServersException ex) {
         if (expectedResult == NO_AVAILABLE_SERVERS) {
-          getLogWriter().info("Got expected NoAvailableServers when doing gets: " + ex.getCause());
+          logger.info("Got expected NoAvailableServers when doing gets: " + ex.getCause());
           continue;
         } else {
           fail("Got unexpected exception when doing gets", ex);
@@ -1753,18 +1732,18 @@ public class SecurityTestUtils {
       } catch (ServerConnectivityException ex) {
         if ((expectedResult == NOTAUTHZ_EXCEPTION)
             && (ex.getCause() instanceof NotAuthorizedException)) {
-          getLogWriter()
+          logger
               .info("Got expected NotAuthorizedException when doing gets: " + ex.getCause());
           continue;
         } else if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing gets: " + ex);
+          logger.info("Got expected exception when doing gets: " + ex);
         } else {
           fail("Got unexpected exception when doing gets", ex);
         }
 
       } catch (Exception ex) {
         if (expectedResult == OTHER_EXCEPTION) {
-          getLogWriter().info("Got expected exception when doing gets: " + ex);
+          logger.info("Got expected exception when doing gets: " + ex);
         } else {
           fail("Got unexpected exception when doing gets", ex);
         }
@@ -1789,7 +1768,11 @@ public class SecurityTestUtils {
 
     DistributedSystem dsys = distributedTestCase.getSystem(sysProps);
     assertNotNull(dsys);
-    addIgnoredExceptions(ignoredExceptions);
+    if (ignoredExceptions != null) {
+      for (String ignoredException : ignoredExceptions) {
+        addIgnoredException(ignoredException);
+      }
+    }
     return dsys;
   }
 
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
index f80431e..5251852 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/DUnitLauncher.java
@@ -55,7 +55,7 @@ import org.apache.geode.distributed.internal.DistributionConfig;
 import org.apache.geode.distributed.internal.InternalLocator;
 import org.apache.geode.distributed.internal.membership.gms.membership.GMSJoinLeave;
 import org.apache.geode.internal.AvailablePortHelper;
-import org.apache.geode.internal.logging.Configuration;
+import org.apache.geode.logging.internal.spi.LoggingProvider;
 import org.apache.geode.test.dunit.DUnitEnv;
 import org.apache.geode.test.dunit.Host;
 import org.apache.geode.test.dunit.SerializableCallable;
@@ -256,7 +256,7 @@ public class DUnitLauncher {
 
     final LoggerContext appenderContext =
         ((org.apache.logging.log4j.core.Logger) LogManager
-            .getLogger(Configuration.MAIN_LOGGER_NAME))
+            .getLogger(LoggingProvider.MAIN_LOGGER_NAME))
                 .getContext();
 
     final PatternLayout layout = PatternLayout.createLayout(
@@ -269,7 +269,7 @@ public class DUnitLauncher {
     fileAppender.start();
 
     LoggerConfig loggerConfig =
-        appenderContext.getConfiguration().getLoggerConfig(Configuration.MAIN_LOGGER_NAME);
+        appenderContext.getConfiguration().getLoggerConfig(LoggingProvider.MAIN_LOGGER_NAME);
     loggerConfig.addAppender(fileAppender, Level.INFO, null);
   }
 
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
index 9bdca6f..5035d2e 100755
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java
@@ -250,10 +250,9 @@ class ProcessManager implements ChildVMLauncher {
     } else {
       // remove current-version product classes and resources from the classpath
       dunitClasspath =
-          removeModulesFromPath(dunitClasspath, "geode-serialization",
-              "geode-core", "geode-cq", "geode-common",
-              "geode-json", "geode-lucene",
-              "geode-wan", "geode-http-service");
+          removeModulesFromPath(dunitClasspath, "geode-common", "geode-core", "geode-cq",
+              "geode-http-service", "geode-json", "geode-log4j", "geode-lucene",
+              "geode-serialization", "geode-wan");
... 4261 lines suppressed ...


Mime
View raw message