You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tv...@apache.org on 2020/04/10 19:03:45 UTC

[commons-jcs] branch jcs-122-logging-abstraction created (now 0946c4d)

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

tv pushed a change to branch jcs-122-logging-abstraction
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git.


      at 0946c4d  JCS-122: Introduce log abstraction

This branch includes the following new commits:

     new 0946c4d  JCS-122: Introduce log abstraction

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[commons-jcs] 01/01: JCS-122: Introduce log abstraction

Posted by tv...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tv pushed a commit to branch jcs-122-logging-abstraction
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git

commit 0946c4d2ab9c2220f6f51390351b4278f4edadc0
Author: Thomas Vandahl <tv...@apache.org>
AuthorDate: Fri Apr 10 21:02:44 2020 +0200

    JCS-122: Introduce log abstraction
---
 commons-jcs-core/pom.xml                           |  14 +-
 .../org/apache/commons/jcs/access/CacheAccess.java |   9 +-
 .../commons/jcs/access/GroupCacheAccess.java       |   2 +
 .../commons/jcs/access/PartitionedCacheAccess.java |  37 +-
 .../auxiliary/AbstractAuxiliaryCacheMonitor.java   |  31 +-
 .../jcs/auxiliary/AuxiliaryCacheConfigurator.java  |  35 +-
 .../jcs/auxiliary/disk/AbstractDiskCache.java      |  39 +-
 .../disk/AbstractDiskCacheAttributes.java          |   8 +-
 .../jcs/auxiliary/disk/block/BlockDisk.java        |  40 +-
 .../jcs/auxiliary/disk/block/BlockDiskCache.java   | 101 ++--
 .../disk/block/BlockDiskCacheFactory.java          |  11 +-
 .../auxiliary/disk/block/BlockDiskKeyStore.java    |  79 +--
 .../jcs/auxiliary/disk/indexed/IndexedDisk.java    |  30 +-
 .../auxiliary/disk/indexed/IndexedDiskCache.java   | 270 ++++------
 .../disk/indexed/IndexedDiskCacheFactory.java      |  11 +-
 .../jcs/auxiliary/disk/jdbc/JDBCDiskCache.java     | 104 ++--
 .../auxiliary/disk/jdbc/JDBCDiskCacheFactory.java  |  15 +-
 .../jcs/auxiliary/disk/jdbc/ShrinkerThread.java    |  36 +-
 .../disk/jdbc/dsfactory/JndiDataSourceFactory.java |  28 +-
 .../dsfactory/SharedPoolDataSourceFactory.java     |   6 +-
 .../disk/jdbc/hsql/HSQLDiskCacheFactory.java       |  16 +-
 .../auxiliary/disk/jdbc/mysql/MySQLDiskCache.java  |  16 +-
 .../disk/jdbc/mysql/MySQLDiskCacheFactory.java     |  72 +--
 .../disk/jdbc/mysql/MySQLTableOptimizer.java       |  48 +-
 .../jcs/auxiliary/lateral/LateralCache.java        |  20 +-
 .../jcs/auxiliary/lateral/LateralCacheNoWait.java  |  11 +-
 .../lateral/LateralCacheNoWaitFacade.java          |  22 +-
 .../lateral/socket/tcp/LateralTCPCacheFactory.java |  68 +--
 .../socket/tcp/LateralTCPDiscoveryListener.java    |  80 +--
 .../lateral/socket/tcp/LateralTCPListener.java     | 196 +++----
 .../lateral/socket/tcp/LateralTCPSender.java       |  35 +-
 .../lateral/socket/tcp/LateralTCPService.java      |  20 +-
 .../remote/AbstractRemoteAuxiliaryCache.java       |  78 +--
 .../remote/AbstractRemoteCacheListener.java        |  76 +--
 .../remote/AbstractRemoteCacheNoWaitFacade.java    |  17 +-
 .../commons/jcs/auxiliary/remote/RemoteCache.java  |  16 +-
 .../remote/RemoteCacheFailoverRunner.java          | 116 ++---
 .../jcs/auxiliary/remote/RemoteCacheListener.java  |  11 +-
 .../jcs/auxiliary/remote/RemoteCacheManager.java   |  65 +--
 .../jcs/auxiliary/remote/RemoteCacheNoWait.java    |  42 +-
 .../auxiliary/remote/RemoteCacheNoWaitFacade.java  |  16 +-
 .../jcs/auxiliary/remote/RemoteLocation.java       |   8 +-
 .../commons/jcs/auxiliary/remote/RemoteUtils.java  |  53 +-
 .../remote/http/client/AbstractHttpClient.java     |   9 +-
 .../remote/http/client/RemoteHttpCache.java        |   6 +-
 .../remote/http/client/RemoteHttpCacheClient.java  |  42 +-
 .../http/client/RemoteHttpCacheDispatcher.java     |   6 +-
 .../remote/http/client/RemoteHttpCacheFactory.java |  14 +-
 .../http/server/AbstractRemoteCacheService.java    |  14 +-
 .../remote/http/server/RemoteHttpCacheServlet.java |  36 +-
 .../remote/server/RegistryKeepAliveRunner.java     |  22 +-
 .../auxiliary/remote/server/RemoteCacheServer.java | 255 +++------
 .../remote/server/RemoteCacheServerFactory.java    |  55 +-
 .../remote/server/RemoteCacheStartupServlet.java   |  25 +-
 .../remote/util/RemoteCacheRequestFactory.java     |  11 +-
 .../jcs/engine/AbstractCacheEventQueue.java        |  47 +-
 .../apache/commons/jcs/engine/CacheAdaptor.java    |  12 +-
 .../commons/jcs/engine/CacheEventQueueFactory.java |  11 +-
 .../commons/jcs/engine/CacheWatchRepairable.java   |  48 +-
 .../commons/jcs/engine/PooledCacheEventQueue.java  |  13 +-
 .../commons/jcs/engine/ZombieCacheService.java     |  27 +-
 .../jcs/engine/ZombieCacheServiceNonLocal.java     |  18 +-
 .../commons/jcs/engine/control/CompositeCache.java | 282 +++-------
 .../engine/control/CompositeCacheConfigurator.java |  89 +---
 .../jcs/engine/control/CompositeCacheManager.java  | 110 ++--
 .../engine/control/event/ElementEventQueue.java    |  35 +-
 .../logging/CacheEventLoggerDebugLogger.java       |  25 +-
 .../AbstractDoubleLinkedListMemoryCache.java       |  96 ++--
 .../jcs/engine/memory/AbstractMemoryCache.java     |  46 +-
 .../jcs/engine/memory/lru/LHMLRUMemoryCache.java   |  20 +-
 .../engine/memory/shrinking/ShrinkerThread.java    |  45 +-
 .../memory/soft/SoftReferenceMemoryCache.java      |   9 +-
 .../org/apache/commons/jcs/log/JulLogAdapter.java  | 574 +++++++++++++++++++++
 .../org/apache/commons/jcs/log/JulLogFactory.java  |  76 +++
 .../main/java/org/apache/commons/jcs/log/Log.java  | 343 ++++++++++++
 .../org/apache/commons/jcs/log/Log4j2Factory.java  |  83 +++
 .../apache/commons/jcs/log/Log4j2LogAdapter.java   | 521 +++++++++++++++++++
 .../org/apache/commons/jcs/log/LogFactory.java     |  68 +++
 .../org/apache/commons/jcs/log/LogManager.java     | 140 +++++
 .../apache/commons/jcs/log/MessageFormatter.java   | 130 +++++
 .../jcs/utils/access/AbstractJCSWorkerHelper.java  |  12 +-
 .../apache/commons/jcs/utils/access/JCSWorker.java |  37 +-
 .../commons/jcs/utils/config/OptionConverter.java  |  49 +-
 .../commons/jcs/utils/config/PropertySetter.java   |  14 +-
 .../jcs/utils/discovery/UDPCleanupRunner.java      |  21 +-
 .../jcs/utils/discovery/UDPDiscoveryManager.java   |  41 +-
 .../jcs/utils/discovery/UDPDiscoveryReceiver.java  |  82 +--
 .../jcs/utils/discovery/UDPDiscoverySender.java    |  67 +--
 .../utils/discovery/UDPDiscoverySenderThread.java  |  43 +-
 .../jcs/utils/discovery/UDPDiscoveryService.java   | 142 ++---
 .../apache/commons/jcs/utils/net/HostNameUtil.java |  21 +-
 .../serialization/SerializationConversionUtil.java |  17 +-
 .../utils/servlet/JCSServletContextListener.java   |  16 +-
 .../commons/jcs/utils/struct/AbstractLRUMap.java   | 121 ++---
 .../commons/jcs/utils/struct/DoubleLinkedList.java |  28 +-
 .../jcs/utils/threadpool/ThreadPoolManager.java    |  47 +-
 .../commons/jcs/utils/zip/CompressionUtil.java     |   6 +-
 .../services/org.apache.commons.jcs.log.LogFactory |  16 +
 .../commons/jcs/ConcurrentRemovalLoadTest.java     |  21 +-
 .../jcs/JCSCacheElementRetrievalUnitTest.java      |   7 +-
 .../apache/commons/jcs/JCSLightLoadUnitTest.java   |  32 +-
 .../java/org/apache/commons/jcs/JCSThrashTest.java |  26 +-
 .../java/org/apache/commons/jcs/JCSUnitTest.java   |  34 +-
 .../commons/jcs/JCSvsHashtablePerformanceTest.java |  48 +-
 .../org/apache/commons/jcs/RemovalTestUtil.java    |   4 +-
 .../commons/jcs/TestLogConfigurationUtil.java      |  61 ++-
 .../apache/commons/jcs/TestTCPLateralCache.java    |  16 +-
 .../apache/commons/jcs/access/TestCacheAccess.java |  13 +-
 .../disk/jdbc/JDBCDataSourceFactoryUnitTest.java   |   8 +-
 .../auxiliary/remote/MockRemoteCacheClient.java    |   6 +-
 .../jcs/auxiliary/remote/TestRemoteCache.java      |   6 +-
 .../client/RemoteHttpCacheFactoryUnitTest.java     |   6 +-
 .../server/RemoteCacheServerStartupUtil.java       |   6 +-
 .../control/event/ElementEventHandlerMockImpl.java |   6 +-
 .../CacheEventLoggerDebugLoggerUnitTest.java       |  42 +-
 .../engine/memory/mru/LRUvsMRUPerformanceTest.java |   8 +-
 .../struct/JCSvsCommonsLRUMapPerformanceTest.java  |  45 +-
 .../jcs/utils/struct/LRUMapConcurrentUnitTest.java |  19 +
 .../jcs/utils/struct/LRUMapPerformanceTest.java    |  36 +-
 .../src/test/test-conf/logger.properties           |  75 ---
 .../src/test/test-conf/logging.properties          |  26 +
 pom.xml                                            |   2 +-
 122 files changed, 3552 insertions(+), 3152 deletions(-)

diff --git a/commons-jcs-core/pom.xml b/commons-jcs-core/pom.xml
index 08c01c1..605be7a 100644
--- a/commons-jcs-core/pom.xml
+++ b/commons-jcs-core/pom.xml
@@ -40,10 +40,11 @@
 
   <dependencies>
 
-    <!--  REQUIRED FOR JCS CORE -->
     <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <version>2.13.1</version>
+      <optional>true</optional>
     </dependency>
 
     <!--  JDBC DISK CACHE -->
@@ -123,7 +124,12 @@
           <artifactId>maven-surefire-plugin</artifactId>
           <version>${commons.surefire.version}</version>
           <configuration>
-            <argLine>-Xmx256m -Djava.security.manager -Djava.security.policy=${basedir}/src/test/conf/cache.policy</argLine>
+            <systemPropertyVariables>
+              <java.security.manager>true</java.security.manager>
+              <java.security.policy>${basedir}/src/test/conf/cache.policy</java.security.policy>
+              <java.util.logging.config.file>${basedir}/src/test/test-conf/logging.properties</java.util.logging.config.file>
+            </systemPropertyVariables>              
+            <argLine>-Xmx256m</argLine>
             <forkCount>1</forkCount>
             <reuseForks>false</reuseForks>
             <includes>
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/CacheAccess.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/CacheAccess.java
index 9ca959a..90b42c0 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/CacheAccess.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/CacheAccess.java
@@ -35,8 +35,6 @@ import org.apache.commons.jcs.engine.CacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.IElementAttributes;
 import org.apache.commons.jcs.engine.control.CompositeCache;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This class provides an interface for all types of access to the cache.
@@ -53,9 +51,6 @@ public class CacheAccess<K, V>
     extends AbstractCacheAccess<K, V>
     implements ICacheAccess<K, V>
 {
-    /** The logger. */
-    private static final Log log = LogFactory.getLog( CacheAccess.class );
-
     /**
      * Constructor for the CacheAccess object.
      * <p>
@@ -319,7 +314,7 @@ public class CacheAccess<K, V>
      * @return Attributes for the object, null if object not in cache
      */
     @Override
-    public IElementAttributes getElementAttributes( K name )
+    public IElementAttributes getElementAttributes( K name ) throws CacheException
     {
         IElementAttributes attr = null;
 
@@ -329,7 +324,7 @@ public class CacheAccess<K, V>
         }
         catch ( IOException ioe )
         {
-            log.error( "Failure getting element attributes", ioe );
+            throw new CacheException("Failure getting element attributes", ioe);
         }
 
         return attr;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/GroupCacheAccess.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/GroupCacheAccess.java
index 88d4a28..d98fe1a 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/GroupCacheAccess.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/GroupCacheAccess.java
@@ -149,6 +149,8 @@ public class GroupCacheAccess<K, V>
     }
 
     /**
+     * Removes a single item by name from a group.
+     *
      * @param name
      * @param group
      */
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/PartitionedCacheAccess.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/PartitionedCacheAccess.java
index c516a54..62f728d 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/PartitionedCacheAccess.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/access/PartitionedCacheAccess.java
@@ -34,9 +34,9 @@ import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes;
 import org.apache.commons.jcs.engine.behavior.IElementAttributes;
 import org.apache.commons.jcs.engine.stats.behavior.ICacheStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.props.AbstractPropertyContainer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * TODO:  Add new methods that will allow you to provide a partition indicator for all major calls.  Add an interface as well.
@@ -61,7 +61,7 @@ public class PartitionedCacheAccess<K, V>
     implements ICacheAccess<K, V>
 {
     /** the logger. */
-    private static final Log log = LogFactory.getLog( PartitionedCacheAccess.class );
+    private static final Log log = LogManager.getLog( PartitionedCacheAccess.class );
 
     /** The number of partitions. */
     private int numberOfPartitions = 1;
@@ -98,7 +98,7 @@ public class PartitionedCacheAccess<K, V>
     {
         if ( key == null || object == null )
         {
-            log.warn( "Bad input key [" + key + "].  Cannot put null into the cache." );
+            log.warn( "Bad input key [{0}].  Cannot put null into the cache.", key );
             return;
         }
 
@@ -114,7 +114,7 @@ public class PartitionedCacheAccess<K, V>
         }
         catch ( CacheException e )
         {
-            log.error( "Problem putting value for key [" + key + "] in cache [" + partitions[partition] + "]" );
+            log.error( "Problem putting value for key [{0}] in cache [{1}]", key, partitions[partition] );
             throw e;
         }
     }
@@ -132,7 +132,7 @@ public class PartitionedCacheAccess<K, V>
     {
         if ( key == null || object == null )
         {
-            log.warn( "Bad input key [" + key + "].  Cannot putSafe null into the cache." );
+            log.warn("Bad input key [{0}].  Cannot putSafe null into the cache.", key);
         }
 
         if (!ensureInit())
@@ -158,7 +158,7 @@ public class PartitionedCacheAccess<K, V>
     {
         if ( key == null || object == null )
         {
-            log.warn( "Bad input key [" + key + "].  Cannot put null into the cache." );
+            log.warn( "Bad input key [{0}].  Cannot put null into the cache.", key );
             return;
         }
 
@@ -175,7 +175,7 @@ public class PartitionedCacheAccess<K, V>
         }
         catch ( CacheException e )
         {
-            log.error( "Problem putting value for key [" + key + "] in cache [" + partitions[partition] + "]" );
+            log.error( "Problem putting value for key [{0}] in cache [{1}]", key, partitions[partition] );
             throw e;
         }
     }
@@ -385,7 +385,7 @@ public class PartitionedCacheAccess<K, V>
         }
         catch ( CacheException e )
         {
-            log.error( "Problem removing value for key [" + key + "] in cache [" + partitions[partition] + "]" );
+            log.error( "Problem removing value for key [{0}] in cache [{1}]", key, partitions[partition] );
             throw e;
         }
     }
@@ -659,10 +659,7 @@ public class PartitionedCacheAccess<K, V>
 
         int partition = (int) ( keyNum % getNumberOfPartitions() );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Using partition [" + partition + "] for key [" + key + "]" );
-        }
+        log.debug( "Using partition [{0}] for key [{1}]", partition, key);
 
         return partition;
     }
@@ -685,7 +682,7 @@ public class PartitionedCacheAccess<K, V>
         {
             // THIS IS UGLY, but I can't think of a better failsafe right now.
             keyNum = key.hashCode();
-            log.warn( "Couldn't convert [" + key + "] into a number.  Will use hashcode [" + keyNum + "]" );
+            log.warn( "Couldn't convert [{0}] into a number.  Will use hashcode [{1}]", key, keyNum);
         }
         return keyNum;
     }
@@ -734,7 +731,7 @@ public class PartitionedCacheAccess<K, V>
             }
             catch ( CacheException e )
             {
-                log.error( "Problem getting cache for region [" + regionName + "]" );
+                log.error( "Problem getting cache for region [{0}]", regionName );
             }
         }
 
@@ -793,10 +790,7 @@ public class PartitionedCacheAccess<K, V>
         propertyValue = System.getProperty( propertyName );
         if ( propertyValue != null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Found system property override: Name [" + propertyName + "] Value [" + propertyValue + "]" );
-            }
+            log.info("Found system property override: Name [{0}] Value [{1}]", propertyName, propertyValue);
         }
         else
         {
@@ -810,10 +804,7 @@ public class PartitionedCacheAccess<K, V>
             }
             else
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Name [" + propertyName + "] Value [" + propertyValue + "]" );
-                }
+                log.info( "Name [{0}] Value [{1}]", propertyName, propertyValue);
             }
         }
         return propertyValue;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
index 4a3e3de..25aa937 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AbstractAuxiliaryCacheMonitor.java
@@ -24,8 +24,8 @@ import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Used to monitor and repair any failed connection for the lateral cache service. By default the
@@ -37,7 +37,7 @@ import org.apache.commons.logging.LogFactory;
 public abstract class AbstractAuxiliaryCacheMonitor extends Thread
 {
     /** The logger */
-    protected final Log log = LogFactory.getLog( this.getClass() );
+    protected final Log log = LogManager.getLog( this.getClass() );
 
     /** How long to wait between runs */
     protected static long idlePeriod = 20 * 1000;
@@ -135,16 +135,13 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
     {
         do
         {
-            if ( log.isDebugEnabled() )
+            if ( allright.get() )
             {
-                if ( allright.get() )
-                {
-                    log.debug( "ERROR DRIVEN MODE: allright = true, cache monitor will wait for an error." );
-                }
-                else
-                {
-                    log.debug( "ERROR DRIVEN MODE: allright = false cache monitor running." );
-                }
+                log.debug( "ERROR DRIVEN MODE: allright = true, cache monitor will wait for an error." );
+            }
+            else
+            {
+                log.debug( "ERROR DRIVEN MODE: allright = false cache monitor running." );
             }
 
             if ( allright.get() )
@@ -178,10 +175,7 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
             // Simply presume we can fix all the errors until proven otherwise.
             allright.set(true);
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Cache monitor running." );
-            }
+            log.debug( "Cache monitor running." );
 
             doWork();
 
@@ -189,10 +183,7 @@ public abstract class AbstractAuxiliaryCacheMonitor extends Thread
             {
                 // don't want to sleep after waking from an error
                 // run immediately and sleep here.
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Cache monitor sleeping for " + idlePeriod + " between runs." );
-                }
+                log.debug( "Cache monitor sleeping for {0} between runs.", idlePeriod );
 
                 Thread.sleep( idlePeriod );
             }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheConfigurator.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheConfigurator.java
index 1a87313..02aea4e 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheConfigurator.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/AuxiliaryCacheConfigurator.java
@@ -1,5 +1,7 @@
 package org.apache.commons.jcs.auxiliary;
 
+import java.util.Properties;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -21,13 +23,11 @@ package org.apache.commons.jcs.auxiliary;
 
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.OptionConverter;
 import org.apache.commons.jcs.utils.config.PropertySetter;
 import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.Properties;
 
 /**
  * Configuration util for auxiliary caches. I plan to move the auxiliary configuration from the
@@ -36,7 +36,7 @@ import java.util.Properties;
 public class AuxiliaryCacheConfigurator
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( AuxiliaryCacheConfigurator.class );
+    private static final Log log = LogManager.getLog( AuxiliaryCacheConfigurator.class );
 
     /** .attributes */
     public static final String ATTRIBUTE_PREFIX = ".attributes";
@@ -73,18 +73,12 @@ public class AuxiliaryCacheConfigurator
         {
             String cacheEventLoggerAttributePrefix = auxPrefix + CACHE_EVENT_LOGGER_PREFIX + ATTRIBUTE_PREFIX;
             PropertySetter.setProperties( cacheEventLogger, props, cacheEventLoggerAttributePrefix + "." );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Using custom cache event logger [" + cacheEventLogger + "] for auxiliary [" + auxPrefix
-                    + "]" );
-            }
+            log.info( "Using custom cache event logger [{0}] for auxiliary [{1}]",
+                    cacheEventLogger, auxPrefix );
         }
         else
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "No cache event logger defined for auxiliary [" + auxPrefix + "]" );
-            }
+            log.info( "No cache event logger defined for auxiliary [{0}]", auxPrefix );
         }
         return cacheEventLogger;
     }
@@ -108,20 +102,15 @@ public class AuxiliaryCacheConfigurator
         {
             String attributePrefix = auxPrefix + SERIALIZER_PREFIX + ATTRIBUTE_PREFIX;
             PropertySetter.setProperties( elementSerializer, props, attributePrefix + "." );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Using custom element serializer [" + elementSerializer + "] for auxiliary [" + auxPrefix
-                    + "]" );
-            }
+            log.info( "Using custom element serializer [{0}] for auxiliary [{1}]",
+                    elementSerializer, auxPrefix );
         }
         else
         {
             // use the default standard serializer
             elementSerializer = new StandardSerializer();
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Using standard serializer [" + elementSerializer + "] for auxiliary [" + auxPrefix + "]" );
-            }
+            log.info( "Using standard serializer [{0}] for auxiliary [{1}]",
+                    elementSerializer, auxPrefix );
         }
         return elementSerializer;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCache.java
index 1ceb231..e82712f 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCache.java
@@ -41,9 +41,9 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.struct.LRUMap;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Abstract class providing a base implementation of a disk cache, which can be easily extended to
@@ -61,7 +61,7 @@ public abstract class AbstractDiskCache<K, V>
     extends AbstractAuxiliaryCacheEventLogging<K, V>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( AbstractDiskCache.class );
+    private static final Log log = LogManager.getLog( AbstractDiskCache.class );
 
     /** Generic disk cache attributes */
     private IDiskCacheAttributes diskCacheAttributes = null;
@@ -190,10 +190,8 @@ public abstract class AbstractDiskCache<K, V>
     public final void update( ICacheElement<K, V> cacheElement )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Putting element in purgatory, cacheName: " + cacheName + ", key: " + cacheElement.getKey() );
-        }
+        log.debug( "Putting element in purgatory, cacheName: {0}, key: {1}",
+                () -> cacheName, () -> cacheElement.getKey() );
 
         try
         {
@@ -237,10 +235,7 @@ public abstract class AbstractDiskCache<K, V>
 
         if ( !alive )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "get was called, but the disk cache is not alive." );
-            }
+            log.debug( "get was called, but the disk cache is not alive." );
             return null;
         }
 
@@ -255,12 +250,9 @@ public abstract class AbstractDiskCache<K, V>
         {
             purgHits++;
 
-            if ( log.isDebugEnabled() )
+            if ( purgHits % 100 == 0 )
             {
-                if ( purgHits % 100 == 0 )
-                {
-                    log.debug( "Purgatory hits = " + purgHits );
-                }
+                log.debug( "Purgatory hits = {0}", purgHits );
             }
 
             // Since the element will go back to the memory cache, we could set
@@ -276,10 +268,8 @@ public abstract class AbstractDiskCache<K, V>
             // Do not set spoolable to false. Just let it go to disk. This
             // will allow the memory size = 0 setting to work well.
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Found element in purgatory, cacheName: " + cacheName + ", key: " + key );
-            }
+            log.debug( "Found element in purgatory, cacheName: {0}, key: {1}",
+                    cacheName, key );
 
             return pe.getCacheElement();
         }
@@ -413,10 +403,8 @@ public abstract class AbstractDiskCache<K, V>
         }
         else
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "RemoveAll was requested but the request was not fulfilled: allowRemoveAll is set to false." );
-            }
+            log.info( "RemoveAll was requested but the request was not "
+                    + "fulfilled: allowRemoveAll is set to false." );
         }
     }
 
@@ -456,7 +444,8 @@ public abstract class AbstractDiskCache<K, V>
                     break;
                 }
             }
-            log.info( "No longer waiting for event queue to finish: " + cacheEventQueue.getStatistics() );
+            log.info( "No longer waiting for event queue to finish: {0}",
+                    () -> cacheEventQueue.getStatistics() );
         });
         t.start();
         // wait up to 60 seconds for dispose and then quit if not done.
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
index 7d5ca70..da5213b 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/AbstractDiskCacheAttributes.java
@@ -23,8 +23,8 @@ import java.io.File;
 
 import org.apache.commons.jcs.auxiliary.AbstractAuxiliaryCacheAttributes;
 import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This has common attributes that any conceivable disk cache would need.
@@ -35,7 +35,7 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
     private static final long serialVersionUID = 8306631920391711229L;
 
     /** The logger */
-    private static final Log log = LogFactory.getLog(AbstractDiskCacheAttributes.class);
+    private static final Log log = LogManager.getLog(AbstractDiskCacheAttributes.class);
 
     /** path to disk */
     private File diskPath;
@@ -89,7 +89,7 @@ public abstract class AbstractDiskCacheAttributes extends AbstractAuxiliaryCache
         }
         if (!result)
         {
-            log.error("Failed to create directory " + diskPath);
+            log.error("Failed to create directory {0}", diskPath);
         }
     }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDisk.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDisk.java
index 1781299..e246770 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDisk.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDisk.java
@@ -29,9 +29,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This class manages reading an writing data to disk. When asked to write a value, it returns a
@@ -42,7 +42,7 @@ import org.apache.commons.logging.LogFactory;
 public class BlockDisk implements AutoCloseable
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog(BlockDisk.class);
+    private static final Log log = LogManager.getLog(BlockDisk.class);
 
     /** The size of the header that indicates the amount of data stored in an occupied block. */
     public static final byte HEADER_SIZE_BYTES = 4;
@@ -116,16 +116,13 @@ public class BlockDisk implements AutoCloseable
         throws IOException
     {
         this.filepath = file.getAbsolutePath();
-        this.fc = FileChannel.open(file.toPath(), 
-                StandardOpenOption.CREATE, 
-                StandardOpenOption.READ, 
+        this.fc = FileChannel.open(file.toPath(),
+                StandardOpenOption.CREATE,
+                StandardOpenOption.READ,
                 StandardOpenOption.WRITE);
         this.numberOfBlocks.set((int) Math.ceil(1f * this.fc.size() / blockSizeBytes));
 
-        if (log.isInfoEnabled())
-        {
-            log.info("Constructing BlockDisk, blockSizeBytes [" + blockSizeBytes + "]");
-        }
+        log.info("Constructing BlockDisk, blockSizeBytes [{0}]", blockSizeBytes);
 
         this.blockSizeBytes = blockSizeBytes;
         this.elementSerializer = elementSerializer;
@@ -179,10 +176,7 @@ public class BlockDisk implements AutoCloseable
         // serialize the object
         byte[] data = elementSerializer.serialize(object);
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("write, total pre-chunking data.length = " + data.length);
-        }
+        log.debug("write, total pre-chunking data.length = {0}", data.length);
 
         this.putBytes.addAndGet(data.length);
         this.putCount.incrementAndGet();
@@ -190,10 +184,7 @@ public class BlockDisk implements AutoCloseable
         // figure out how many blocks we need.
         int numBlocksNeeded = calculateTheNumberOfBlocksNeeded(data);
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("numBlocksNeeded = " + numBlocksNeeded);
-        }
+        log.debug("numBlocksNeeded = {0}", numBlocksNeeded);
 
         // allocate blocks
         int[] blocks = allocateBlocks(numBlocksNeeded);
@@ -218,7 +209,7 @@ public class BlockDisk implements AutoCloseable
             int written = fc.write(headerBuffer, position);
             assert written == HEADER_SIZE_BYTES;
 
-            //write the data 
+            //write the data
             written = fc.write(slice, position + HEADER_SIZE_BYTES);
             assert written == length;
 
@@ -278,7 +269,7 @@ public class BlockDisk implements AutoCloseable
     protected <T> T read(int[] blockNumbers)
         throws IOException, ClassNotFoundException
     {
-        ByteBuffer data = null;
+        final ByteBuffer data;
 
         if (blockNumbers.length == 1)
         {
@@ -297,10 +288,7 @@ public class BlockDisk implements AutoCloseable
             data.flip();
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("read, total post combination data.length = " + data.limit());
-        }
+        log.debug("read, total post combination data.length = {0}", () -> data.limit());
 
         return elementSerializer.deSerialize(data.array(), null);
     }
@@ -333,7 +321,7 @@ public class BlockDisk implements AutoCloseable
 //        else
         {
             ByteBuffer datalength = ByteBuffer.allocate(HEADER_SIZE_BYTES);
-            fc.read(datalength, position); 
+            fc.read(datalength, position);
             datalength.flip();
             datalen = datalength.getInt();
             if (position + datalen > fileLength)
@@ -345,7 +333,7 @@ public class BlockDisk implements AutoCloseable
 
         if (corrupted)
         {
-            log.warn("\n The file is corrupt: " + "\n " + message);
+            log.warn("\n The file is corrupt: \n {0}", message);
             throw new IOException("The File Is Corrupt, need to reset");
         }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
index 0847c5a..90df796 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCache.java
@@ -45,8 +45,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * There is one BlockDiskCache per region. It manages the key and data store.
@@ -58,7 +58,7 @@ public class BlockDiskCache<K, V>
     implements IRequireScheduler
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( BlockDiskCache.class );
+    private static final Log log = LogManager.getLog( BlockDiskCache.class );
 
     /** The name to prefix all log messages with. */
     private final String logCacheName;
@@ -110,19 +110,13 @@ public class BlockDiskCache<K, V>
         this.blockDiskCacheAttributes = cacheAttributes;
         this.logCacheName = "Region [" + getCacheName() + "] ";
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( logCacheName + "Constructing BlockDiskCache with attributes " + cacheAttributes );
-        }
+        log.info("{0}: Constructing BlockDiskCache with attributes {1}", logCacheName, cacheAttributes );
 
         // Make a clean file name
         this.fileName = getCacheName().replaceAll("[^a-zA-Z0-9-_\\.]", "_");
         this.rootDirectory = cacheAttributes.getDiskPath();
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( logCacheName + "Cache file root directory: [" + rootDirectory + "]");
-        }
+        log.info("{0}: Cache file root directory: [{1}]", logCacheName, rootDirectory);
 
         try
         {
@@ -149,15 +143,12 @@ public class BlockDiskCache<K, V>
 
             // Initialization finished successfully, so set alive to true.
             setAlive(true);
-            if ( log.isInfoEnabled() )
-            {
-                log.info( logCacheName + "Block Disk Cache is alive." );
-            }
+            log.info("{0}: Block Disk Cache is alive.", logCacheName);
         }
         catch ( IOException e )
         {
-            log.error( logCacheName + "Failure initializing for fileName: " + fileName + " and root directory: "
-                + rootDirectory, e );
+            log.error("{0}: Failure initializing for fileName: {1} and root directory: {2}",
+                    logCacheName, fileName, rootDirectory, e);
         }
     }
 
@@ -215,7 +206,7 @@ public class BlockDiskCache<K, V>
         }
         catch ( Exception e )
         {
-            log.warn(logCacheName + " Problem verifying disk.", e);
+            log.warn("{0}: Problem verifying disk.", logCacheName, e);
             alright = false;
         }
         finally
@@ -313,17 +304,11 @@ public class BlockDiskCache<K, V>
     {
         if ( !isAlive() )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( logCacheName + "No longer alive so returning null for key = " + key );
-            }
+            log.debug("{0}: No longer alive so returning null for key = {1}", logCacheName, key );
             return null;
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( logCacheName + "Trying to get from disk: " + key );
-        }
+        log.debug("{0}: Trying to get from disk: {1}", logCacheName, key );
 
         ICacheElement<K, V> object = null;
 
@@ -344,12 +329,12 @@ public class BlockDiskCache<K, V>
         }
         catch ( IOException ioe )
         {
-            log.error( logCacheName + "Failure getting from disk--IOException, key = " + key, ioe );
+            log.error("{0}: Failure getting from disk--IOException, key = {1}", logCacheName, key, ioe );
             reset();
         }
         catch ( Exception e )
         {
-            log.error( logCacheName + "Failure getting from disk, key = " + key, e );
+            log.error("{0}: Failure getting from disk, key = {1}", logCacheName, key, e );
         }
         return object;
     }
@@ -370,10 +355,8 @@ public class BlockDiskCache<K, V>
     {
         if ( !isAlive() )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( logCacheName + "No longer alive; aborting put of key = " + element.getKey() );
-            }
+            log.debug("{0}: No longer alive; aborting put of key = {1}",
+                    () -> logCacheName, () -> element.getKey());
             return;
         }
 
@@ -395,24 +378,21 @@ public class BlockDiskCache<K, V>
 
             this.keyStore.put( element.getKey(), blocks );
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( logCacheName + "Put to file [" + fileName + "] key [" + element.getKey() + "]" );
-            }
+            log.debug("{0}: Put to file [{1}] key [{2}]", () -> logCacheName,
+                    () -> fileName, () -> element.getKey());
         }
         catch ( IOException e )
         {
-            log.error( logCacheName + "Failure updating element, key: " + element.getKey() + " old: " + Arrays.toString(old), e );
+            log.error("{0}: Failure updating element, key: {1} old: {2}",
+                    logCacheName, element.getKey(), Arrays.toString(old), e);
         }
         finally
         {
             storageLock.writeLock().unlock();
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( logCacheName + "Storing element on disk, key: " + element.getKey() );
-        }
+        log.debug("{0}: Storing element on disk, key: {1}", () -> logCacheName,
+                () -> element.getKey() );
     }
 
     /**
@@ -428,10 +408,7 @@ public class BlockDiskCache<K, V>
     {
         if ( !isAlive() )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( logCacheName + "No longer alive so returning false for key = " + key );
-            }
+            log.debug("{0}: No longer alive so returning false for key = {1}", logCacheName, key );
             return false;
         }
 
@@ -457,7 +434,7 @@ public class BlockDiskCache<K, V>
         }
         catch ( Exception e )
         {
-            log.error( logCacheName + "Problem removing element.", e );
+            log.error("{0}: Problem removing element.", logCacheName, e );
             reset = true;
         }
         finally
@@ -538,11 +515,8 @@ public class BlockDiskCache<K, V>
 		    this.dataFile.freeBlocks( ded );
 		}
 
-		if ( log.isDebugEnabled() )
-		{
-		    log.debug( logCacheName + "Disk removal: Removed from key hash, key [" + key + "] removed = "
-		        + removed );
-		}
+	    log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
+	            logCacheName, key, removed);
 		return removed;
 	}
 
@@ -575,7 +549,8 @@ public class BlockDiskCache<K, V>
         }
         catch ( InterruptedException ex )
         {
-            log.error( logCacheName + "Interrupted while waiting for disposal thread to finish.", ex );
+            log.error("{0}: Interrupted while waiting for disposal thread to finish.",
+                    logCacheName, ex );
         }
     }
 
@@ -586,7 +561,7 @@ public class BlockDiskCache<K, V>
     {
         if ( !isAlive() )
         {
-            log.error( logCacheName + "Not alive and dispose was called, filename: " + fileName );
+            log.error("{0}: Not alive and dispose was called, filename: {1}", logCacheName, fileName);
             return;
         }
         storageLock.writeLock().lock();
@@ -603,10 +578,7 @@ public class BlockDiskCache<K, V>
 
             try
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( logCacheName + "Closing files, base filename: " + fileName );
-                }
+                log.debug("{0}: Closing files, base filename: {1}", logCacheName, fileName );
                 dataFile.close();
                 // dataFile = null;
 
@@ -616,7 +588,8 @@ public class BlockDiskCache<K, V>
             }
             catch ( IOException e )
             {
-                log.error( logCacheName + "Failure closing files in dispose, filename: " + fileName, e );
+                log.error("{0}: Failure closing files in dispose, filename: {1}",
+                        logCacheName, fileName, e );
             }
         }
         finally
@@ -624,10 +597,7 @@ public class BlockDiskCache<K, V>
             storageLock.writeLock().unlock();
         }
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( logCacheName + "Shutdown complete." );
-        }
+        log.info("{0}: Shutdown complete.", logCacheName);
     }
 
     /**
@@ -648,10 +618,7 @@ public class BlockDiskCache<K, V>
      */
     private void reset()
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( logCacheName + "Resetting cache" );
-        }
+        log.info("{0}: Resetting cache", logCacheName);
 
         try
         {
@@ -666,7 +633,7 @@ public class BlockDiskCache<K, V>
         }
         catch ( IOException e )
         {
-            log.error( logCacheName + "Failure resetting state", e );
+            log.error("{0}: Failure resetting state", logCacheName, e );
         }
         finally
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
index c54c573..7a88db4 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskCacheFactory.java
@@ -24,8 +24,8 @@ import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Creates disk cache instances.
@@ -34,7 +34,7 @@ public class BlockDiskCacheFactory
     extends AbstractAuxiliaryCacheFactory
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( BlockDiskCacheFactory.class );
+    private static final Log log = LogManager.getLog( BlockDiskCacheFactory.class );
 
     /**
      * Create an instance of the BlockDiskCache.
@@ -52,10 +52,7 @@ public class BlockDiskCacheFactory
                                        ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
         BlockDiskCacheAttributes idca = (BlockDiskCacheAttributes) iaca;
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Creating DiskCache for attributes = " + idca );
-        }
+        log.debug("Creating DiskCache for attributes = {0}", idca);
 
         BlockDiskCache<K, V> cache = new BlockDiskCache<>( idca, elementSerializer );
         cache.setCacheEventLogger( cacheEventLogger );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
index bf4909a..94118c4 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/block/BlockDiskKeyStore.java
@@ -38,11 +38,11 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.commons.jcs.auxiliary.disk.behavior.IDiskCacheAttributes.DiskLimitType;
 import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.struct.AbstractLRUMap;
 import org.apache.commons.jcs.utils.struct.LRUMap;
 import org.apache.commons.jcs.utils.timing.ElapsedTimer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This is responsible for storing the keys.
@@ -53,7 +53,7 @@ import org.apache.commons.logging.LogFactory;
 public class BlockDiskKeyStore<K>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog(BlockDiskKeyStore.class);
+    private static final Log log = LogManager.getLog(BlockDiskKeyStore.class);
 
     /** Attributes governing the behavior of the block disk cache. */
     private final BlockDiskCacheAttributes blockDiskCacheAttributes;
@@ -103,24 +103,18 @@ public class BlockDiskKeyStore<K>
 
         File rootDirectory = cacheAttributes.getDiskPath();
 
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Cache file root directory [" + rootDirectory + "]");
-        }
+        log.info("{0}: Cache file root directory [{1}]", logCacheName, rootDirectory);
 
         this.keyFile = new File(rootDirectory, fileName + ".key");
 
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Key File [" + this.keyFile.getAbsolutePath() + "]");
-        }
+        log.info("{0}: Key File [{1}]", logCacheName, this.keyFile.getAbsolutePath());
 
         if (keyFile.length() > 0)
         {
             loadKeys();
             if (!verify())
             {
-                log.warn(logCacheName + "Key File is invalid. Resetting file.");
+                log.warn("{0}: Key File is invalid. Resetting file.", logCacheName);
                 initKeyMap();
                 reset();
             }
@@ -141,10 +135,8 @@ public class BlockDiskKeyStore<K>
         {
             ElapsedTimer timer = new ElapsedTimer();
             int numKeys = keyHash.size();
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Saving keys to [" + this.keyFile.getAbsolutePath() + "], key count [" + numKeys + "]");
-            }
+            log.info("{0}: Saving keys to [{1}], key count [{2}]", () -> logCacheName,
+                    () -> this.keyFile.getAbsolutePath(), () -> numKeys);
 
             synchronized (keyFile)
             {
@@ -170,15 +162,13 @@ public class BlockDiskKeyStore<K>
                 }
             }
 
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Finished saving keys. It took " + timer.getElapsedTimeString() + " to store " + numKeys
-                        + " keys.  Key file length [" + keyFile.length() + "]");
-            }
+            log.info("{0}: Finished saving keys. It took {1} to store {2} keys. Key file length [{3}]",
+                    () -> logCacheName, () -> timer.getElapsedTimeString(), () -> numKeys,
+                    () -> keyFile.length());
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Problem storing keys.", e);
+            log.error("{0}: Problem storing keys.", logCacheName, e);
         }
     }
 
@@ -219,10 +209,7 @@ public class BlockDiskKeyStore<K>
             {
                 keyHash = new LRUMapCountLimited(maxKeySize);
             }
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Set maxKeySize to: '" + maxKeySize + "'");
-            }
+            log.info("{0}: Set maxKeySize to: \"{1}\"", logCacheName, maxKeySize);
         }
         else
         {
@@ -230,10 +217,7 @@ public class BlockDiskKeyStore<K>
             // efficiency.
             keyHash = new HashMap<>();
             // keyHash = Collections.synchronizedMap( new HashMap() );
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Set maxKeySize to unlimited'");
-            }
+            log.info("{0}: Set maxKeySize to unlimited", logCacheName);
         }
     }
 
@@ -243,10 +227,7 @@ public class BlockDiskKeyStore<K>
      */
     protected void loadKeys()
     {
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Loading keys for " + keyFile.toString());
-        }
+        log.info("{0}: Loading keys for {1}", () -> logCacheName, () -> keyFile.toString());
 
         try
         {
@@ -283,21 +264,15 @@ public class BlockDiskKeyStore<K>
             {
                 keyHash.putAll(keys);
 
-                if (log.isDebugEnabled())
-                {
-                    log.debug(logCacheName + "Found " + keys.size() + " in keys file.");
-                }
-
-                if (log.isInfoEnabled())
-                {
-                    log.info(logCacheName + "Loaded keys from [" + fileName + "], key count: " + keyHash.size() + "; up to "
-                            + maxKeySize + " will be available.");
-                }
+                log.debug("{0}: Found {1} in keys file.", logCacheName, keys.size());
+                log.info("{0}: Loaded keys from [{1}], key count: {2}; up to {3} will be available.",
+                        () -> logCacheName, () -> fileName, () -> keyHash.size(),
+                        () -> maxKeySize);
             }
         }
         catch (Exception e)
         {
-            log.error(logCacheName + "Problem loading keys for file " + fileName, e);
+            log.error("{0}: Problem loading keys for file {1}", logCacheName, fileName, e);
         }
     }
 
@@ -388,7 +363,7 @@ public class BlockDiskKeyStore<K>
                     keys = new HashSet<>();
                     blockAllocationMap.put(block, keys);
                 }
-                else if (!log.isDebugEnabled())
+                else if (!log.isTraceEnabled())
                 {
                     // keys are not null, and no debug - fail fast
                     return false;
@@ -397,11 +372,11 @@ public class BlockDiskKeyStore<K>
             }
         }
         boolean ok = true;
-        if (log.isDebugEnabled())
+        if (log.isTraceEnabled())
         {
             for (Entry<Integer, Set<K>> e : blockAllocationMap.entrySet())
             {
-                log.debug("Block " + e.getKey() + ":" + e.getValue());
+                log.trace("Block {0}: {1}", e.getKey(), e.getValue());
                 if (e.getValue().size() > 1)
                 {
                     ok = false;
@@ -519,8 +494,8 @@ public class BlockDiskKeyStore<K>
             blockDiskCache.freeBlocks(value);
             if (log.isDebugEnabled())
             {
-                log.debug(logCacheName + "Removing key: [" + key + "] from key store.");
-                log.debug(logCacheName + "Key store size: [" + super.size() + "].");
+                log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+                log.debug("{0}: Key store size: [{1}].", logCacheName, super.size());
             }
 
             if (value != null)
@@ -567,8 +542,8 @@ public class BlockDiskKeyStore<K>
             blockDiskCache.freeBlocks(value);
             if (log.isDebugEnabled())
             {
-                log.debug(logCacheName + "Removing key: [" + key + "] from key store.");
-                log.debug(logCacheName + "Key store size: [" + super.size() + "].");
+                log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+                log.debug("{0}: Key store size: [{1}].", logCacheName, super.size());
             }
         }
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDisk.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDisk.java
index 4d59f5e..7df2a58 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDisk.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDisk.java
@@ -26,8 +26,8 @@ import java.nio.channels.FileChannel;
 import java.nio.file.StandardOpenOption;
 
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /** Provides thread safe access to the underlying random access file. */
 public class IndexedDisk implements AutoCloseable
@@ -39,7 +39,7 @@ public class IndexedDisk implements AutoCloseable
     private final IElementSerializer elementSerializer;
 
     /** The logger */
-    private static final Log log = LogFactory.getLog(IndexedDisk.class);
+    private static final Log log = LogManager.getLog(IndexedDisk.class);
 
     /** The path to the log directory. */
     private final String filepath;
@@ -59,9 +59,9 @@ public class IndexedDisk implements AutoCloseable
     {
         this.filepath = file.getAbsolutePath();
         this.elementSerializer = elementSerializer;
-        this.fc = FileChannel.open(file.toPath(), 
-                StandardOpenOption.CREATE, 
-                StandardOpenOption.READ, 
+        this.fc = FileChannel.open(file.toPath(),
+                StandardOpenOption.CREATE,
+                StandardOpenOption.READ,
                 StandardOpenOption.WRITE);
     }
 
@@ -107,7 +107,7 @@ public class IndexedDisk implements AutoCloseable
 
         if (corrupted)
         {
-            log.warn("\n The file is corrupt: " + "\n " + message);
+            log.warn("\n The file is corrupt: \n {0}", message);
             throw new IOException("The File Is Corrupt, need to reset");
         }
 
@@ -179,8 +179,8 @@ public class IndexedDisk implements AutoCloseable
         long pos = ded.pos;
         if (log.isTraceEnabled())
         {
-            log.trace("write> pos=" + pos);
-            log.trace(fc + " -- data.length = " + data.length);
+            log.trace("write> pos={0}", pos);
+            log.trace("{0} -- data.length = {1}", fc, data.length);
         }
 
         if (data.length != ded.len)
@@ -198,7 +198,7 @@ public class IndexedDisk implements AutoCloseable
         //write the data
         ByteBuffer dataBuffer = ByteBuffer.wrap(data);
         written = fc.write(dataBuffer, pos + HEADER_SIZE_BYTES);
-        
+
         return written == data.length;
     }
 
@@ -249,10 +249,7 @@ public class IndexedDisk implements AutoCloseable
     protected synchronized void reset()
         throws IOException
     {
-        if (log.isDebugEnabled())
-        {
-            log.debug("Resetting Indexed File [" + filepath + "]");
-        }
+        log.debug("Resetting Indexed File [{0}]", filepath);
         fc.truncate(0);
         fc.force(true);
     }
@@ -266,10 +263,7 @@ public class IndexedDisk implements AutoCloseable
     protected void truncate(long length)
         throws IOException
     {
-        if (log.isInfoEnabled())
-        {
-            log.info("Truncating file [" + filepath + "] to " + length);
-        }
+        log.info("Truncating file [{0}] to {1}", filepath, length);
         fc.truncate(length);
     }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
index ec196e2..ed4ecf9 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCache.java
@@ -51,11 +51,11 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.struct.AbstractLRUMap;
 import org.apache.commons.jcs.utils.struct.LRUMap;
 import org.apache.commons.jcs.utils.timing.ElapsedTimer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Disk cache that uses a RandomAccessFile with keys stored in memory. The maximum number of keys
@@ -65,7 +65,7 @@ import org.apache.commons.logging.LogFactory;
 public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog(IndexedDiskCache.class);
+    private static final Log log = LogManager.getLog(IndexedDiskCache.class);
 
     /** Cache name used in log messages */
     protected final String logCacheName;
@@ -185,10 +185,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
             // Initialization finished successfully, so set alive to true.
             setAlive(true);
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Indexed Disk Cache is alive.");
-            }
+            log.info("{0}: Indexed Disk Cache is alive.", logCacheName);
 
             // TODO: Should we improve detection of whether or not the file should be optimized.
             if (isRealTimeOptimizationEnabled && keyHash.size() > 0)
@@ -199,9 +196,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         }
         catch (IOException e)
         {
-            log.error(
-                logCacheName + "Failure initializing for fileName: " + fileName + " and directory: "
-                    + this.rafDir.getAbsolutePath(), e);
+            log.error("{0}: Failure initializing for fileName: {1} and directory: {2}",
+                    logCacheName, fileName, this.rafDir.getAbsolutePath(), e);
         }
     }
 
@@ -214,10 +210,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     private void initializeFileSystem(IndexedDiskCacheAttributes cattr)
     {
         this.rafDir = cattr.getDiskPath();
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Cache file root directory: " + rafDir);
-        }
+        log.info("{0}: Cache file root directory: {1}", logCacheName, rafDir);
     }
 
     /**
@@ -236,10 +229,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
         if (cattr.isClearDiskOnStartup())
         {
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "ClearDiskOnStartup is set to true.  Ingnoring any persisted data.");
-            }
+            log.info("{0}: ClearDiskOnStartup is set to true.  Ingnoring any persisted data.",
+                    logCacheName);
             initializeEmptyStore();
         }
         else if (keyFile.length() > 0)
@@ -295,7 +286,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                 keyHash.clear();
                 keyFile.reset();
                 dataFile.reset();
-                log.warn(logCacheName + "Corruption detected.  Reseting data and keys files.");
+                log.warn("{0}: Corruption detected. Resetting data and keys files.", logCacheName);
             }
             else
             {
@@ -313,10 +304,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
      */
     protected void loadKeys()
     {
-        if (log.isDebugEnabled())
-        {
-            log.debug(logCacheName + "Loading keys for " + keyFile.toString());
-        }
+        log.debug("{0}: Loading keys for {1}", () -> logCacheName, () -> keyFile.toString());
 
         storageLock.writeLock().lock();
 
@@ -330,28 +318,22 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
             if (keys != null)
             {
-                if (log.isDebugEnabled())
-                {
-                    log.debug(logCacheName + "Found " + keys.size() + " in keys file.");
-                }
+                log.debug("{0}: Found {1} in keys file.", logCacheName, keys.size());
 
                 keyHash.putAll(keys);
 
-                if (log.isInfoEnabled())
-                {
-                    log.info(logCacheName + "Loaded keys from [" + fileName + "], key count: " + keyHash.size() + "; up to "
-                        + maxKeySize + " will be available.");
-                }
+                log.info("{0}: Loaded keys from [{1}], key count: {2}; up to {3} will be available.",
+                        () -> logCacheName, () -> fileName, () -> keyHash.size(), () -> maxKeySize);
             }
 
-            if (log.isDebugEnabled())
+            if (log.isTraceEnabled())
             {
                 dump(false);
             }
         }
         catch (Exception e)
         {
-            log.error(logCacheName + "Problem loading keys for file " + fileName, e);
+            log.error("{0}: Problem loading keys for file {1}", logCacheName, fileName, e);
         }
         finally
         {
@@ -373,7 +355,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     private boolean checkKeyDataConsistency(boolean checkForDedOverlaps)
     {
         ElapsedTimer timer = new ElapsedTimer();
-        log.debug(logCacheName + "Performing inital consistency check");
+        log.debug("{0}: Performing inital consistency check", logCacheName);
 
         boolean isOk = true;
         long fileLength = 0;
@@ -389,8 +371,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
                 if (!isOk)
                 {
-                    log.warn(logCacheName + "The dataFile is corrupted!" + "\n raf.length() = " + fileLength + "\n ded.pos = "
-                        + ded.pos);
+                    log.warn("{0}: The dataFile is corrupted!\n raf.length() = {1}\n ded.pos = {2}",
+                            logCacheName, fileLength, ded.pos);
                     break;
                 }
             }
@@ -406,10 +388,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             isOk = false;
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Finished inital consistency check, isOk = " + isOk + " in " + timer.getElapsedTimeString());
-        }
+        log.info("{0}: Finished inital consistency check, isOk = {1} in {2}",
+                logCacheName, isOk, timer.getElapsedTimeString());
 
         return isOk;
     }
@@ -433,7 +413,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             IndexedDiskElementDescriptor ded = sortedDescriptors[i];
             if (expectedNextPos > ded.pos)
             {
-                log.error(logCacheName + "Corrupt file: overlapping deds " + ded);
+                log.error("{0}: Corrupt file: overlapping deds {1}", logCacheName, ded);
                 isOk = false;
                 break;
             }
@@ -443,10 +423,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             }
         }
         long end = System.currentTimeMillis();
-        if (log.isDebugEnabled())
-        {
-            log.debug(logCacheName + "Check for DED overlaps took " + (end - start) + " ms.");
-        }
+        log.debug("{0}: Check for DED overlaps took {1} ms.", logCacheName, end - start);
 
         return isOk;
     }
@@ -458,10 +435,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         try
         {
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Saving keys to: " + fileName + ", key count: " + keyHash.size());
-            }
+            log.info("{0}: Saving keys to: {1}, key count: {2}",
+                    () -> logCacheName, () -> fileName, () -> keyHash.size());
 
             keyFile.reset();
 
@@ -473,14 +448,11 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                 keyFile.writeObject(keys, 0);
             }
 
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Finished saving keys.");
-            }
+            log.info("{0}: Finished saving keys.", logCacheName);
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Problem storing keys.", e);
+            log.error("{0}: Problem storing keys.", logCacheName, e);
         }
     }
 
@@ -497,14 +469,13 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         if (!isAlive())
         {
-            log.error(logCacheName + "No longer alive; aborting put of key = " + ce.getKey());
+            log.error("{0}: No longer alive; aborting put of key = {1}",
+                    () -> logCacheName, () -> ce.getKey());
             return;
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug(logCacheName + "Storing element on disk, key: " + ce.getKey());
-        }
+        log.debug("{0}: Storing element on disk, key: {1}",
+                () -> logCacheName, () -> ce.getKey());
 
         IndexedDiskElementDescriptor ded = null;
 
@@ -546,11 +517,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                             ded.len = data.length;
                             recycleCnt++;
                             this.adjustBytesFree(ded, false);
-                            if (log.isDebugEnabled())
-                            {
-                                log.debug(logCacheName + "using recycled ded " + ded.pos + " rep.len = " + rep.len + " ded.len = "
-                                    + ded.len);
-                            }
+                            log.debug("{0}: using recycled ded {1} rep.len = {2} ded.len = {3}",
+                                    logCacheName, ded.pos, rep.len, ded.len);
                         }
                     }
 
@@ -560,10 +528,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                     if (queueInput)
                     {
                         queuedPutList.add(ded);
-                        if (log.isDebugEnabled())
-                        {
-                            log.debug(logCacheName + "added to queued put list." + queuedPutList.size());
-                        }
+                        log.debug("{0}: added to queued put list. {1}",
+                                () -> logCacheName, () -> queuedPutList.size());
                     }
 
                     // add the old slot to the recycle bin
@@ -580,15 +546,13 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                 storageLock.writeLock().unlock();
             }
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "Put to file: " + fileName + ", key: " + ce.getKey() + ", position: " + ded.pos
-                    + ", size: " + ded.len);
-            }
+            log.debug("{0}: Put to file: {1}, key: {2}, position: {3}, size: {4}",
+                    logCacheName, fileName, ce.getKey(), ded.pos, ded.len);
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Failure updating element, key: " + ce.getKey() + " old: " + old, e);
+            log.error("{0}: Failure updating element, key: {1} old: {2}",
+                    logCacheName, ce.getKey(), old, e);
         }
     }
 
@@ -605,14 +569,12 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         if (!isAlive())
         {
-            log.error(logCacheName + "No longer alive so returning null for key = " + key);
+            log.error("{0}: No longer alive so returning null for key = {1}",
+                    logCacheName, key);
             return null;
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug(logCacheName + "Trying to get from disk: " + key);
-        }
+        log.debug("{0}: Trying to get from disk: {1}", logCacheName, key);
 
         ICacheElement<K, V> object = null;
         try
@@ -634,7 +596,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         }
         catch (IOException ioe)
         {
-            log.error(logCacheName + "Failure getting from disk, key = " + key, ioe);
+            log.error("{0}: Failure getting from disk, key = {1}", logCacheName, key, ioe);
             reset();
         }
         return object;
@@ -692,10 +654,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
         if (ded != null)
         {
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "Found on disk, key: " + key);
-            }
+            log.debug("{0}: Found on disk, key: ", logCacheName, key);
+
             try
             {
                 ICacheElement<K, V> readObject = dataFile.readObject(ded);
@@ -704,13 +664,13 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             }
             catch (IOException e)
             {
-                log.error(logCacheName + "IO Exception, Problem reading object from file", e);
+                log.error("{0}: IO Exception, Problem reading object from file", logCacheName, e);
                 throw e;
             }
             catch (Exception e)
             {
-                log.error(logCacheName + "Exception, Problem reading object from file", e);
-                throw new IOException(logCacheName + "Problem reading object from disk. " + e.getMessage());
+                log.error("{0}: Exception, Problem reading object from file", logCacheName, e);
+                throw new IOException(logCacheName + "Problem reading object from disk.", e);
             }
         }
 
@@ -755,7 +715,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         if (!isAlive())
         {
-            log.error(logCacheName + "No longer alive so returning false for key = " + key);
+            log.error("{0}: No longer alive so returning false for key = {1}", logCacheName, key);
             return false;
         }
 
@@ -897,10 +857,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         removed = ded != null;
         addToRecycleBin(ded);
 
-        if (log.isDebugEnabled())
-        {
-            log.debug(logCacheName + "Disk removal: Removed from key hash, key [" + key + "] removed = " + removed);
-        }
+        log.debug("{0}: Disk removal: Removed from key hash, key [{1}] removed = {2}",
+                logCacheName, key, removed);
         return removed;
     }
 
@@ -910,7 +868,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     @Override
     public void processRemoveAll()
     {
-        ICacheEvent<String> cacheEvent = createICacheEvent(getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT);
+        ICacheEvent<String> cacheEvent =
+                createICacheEvent(getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT);
         try
         {
             reset();
@@ -928,10 +887,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
      */
     private void reset()
     {
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Resetting cache");
-        }
+        log.info("{0}: Resetting cache", logCacheName);
 
         try
         {
@@ -941,7 +897,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             {
                 dataFile.close();
             }
-            
+
             File dataFileTemp = new File(rafDir, fileName + ".data");
             Files.delete(dataFileTemp.toPath());
 
@@ -952,15 +908,15 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             File keyFileTemp = new File(rafDir, fileName + ".key");
             Files.delete(keyFileTemp.toPath());
 
-            dataFile = new IndexedDisk(new File(rafDir, fileName + ".data"), getElementSerializer());
-            keyFile = new IndexedDisk(new File(rafDir, fileName + ".key"), getElementSerializer());
+            dataFile = new IndexedDisk(dataFileTemp, getElementSerializer());
+            keyFile = new IndexedDisk(keyFileTemp, getElementSerializer());
 
             this.recycle.clear();
             this.keyHash.clear();
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Failure resetting state", e);
+            log.error("{0}: Failure resetting state", logCacheName, e);
         }
         finally
         {
@@ -970,7 +926,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
     /**
      * Create the map for keys that contain the index position on disk.
-     * 
+     *
      * @return a new empty Map for keys and IndexedDiskElementDescriptors
      */
     private Map<K, IndexedDiskElementDescriptor> createInitialKeyMap()
@@ -987,22 +943,16 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                 keyMap = new LRUMapSizeLimited(maxKeySize);
             }
 
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Set maxKeySize to: '" + maxKeySize + "'");
-            }
+            log.info("{0}: Set maxKeySize to: \"{1}\"", logCacheName, maxKeySize);
         }
         else
         {
             // If no max size, use a plain map for memory and processing efficiency.
             keyMap = new HashMap<>();
             // keyHash = Collections.synchronizedMap( new HashMap() );
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Set maxKeySize to unlimited'");
-            }
+            log.info("{0}: Set maxKeySize to unlimited", logCacheName);
         }
-        
+
         return keyMap;
     }
 
@@ -1027,7 +977,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             }
             catch (InterruptedException ex)
             {
-                log.error(logCacheName + "Interrupted while waiting for disposal thread to finish.", ex);
+                log.error("{0}: Interrupted while waiting for disposal thread to finish.",
+                        logCacheName, ex);
             }
         }
         finally
@@ -1043,7 +994,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         if (!isAlive())
         {
-            log.error(logCacheName + "Not alive and dispose was called, filename: " + fileName);
+            log.error("{0}: Not alive and dispose was called, filename: {1}",
+                    logCacheName, fileName);
             return;
         }
 
@@ -1054,17 +1006,17 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         if (isRealTimeOptimizationEnabled && optimizationThread != null)
         {
             // Join with the current optimization thread.
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "In dispose, optimization already in progress; waiting for completion.");
-            }
+            log.debug("{0}: In dispose, optimization already in progress; waiting for completion.",
+                    logCacheName);
+
             try
             {
                 optimizationThread.join();
             }
             catch (InterruptedException e)
             {
-                log.error(logCacheName + "Unable to join current optimization thread.", e);
+                log.error("{0}: Unable to join current optimization thread.",
+                        logCacheName, e);
             }
         }
         else if (isShutdownOptimizationEnabled && this.getBytesFree() > 0)
@@ -1076,10 +1028,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
         try
         {
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "Closing files, base filename: " + fileName);
-            }
+            log.debug("{0}: Closing files, base filename: {1}", logCacheName,
+                    fileName);
             dataFile.close();
             dataFile = null;
             keyFile.close();
@@ -1087,13 +1037,11 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Failure closing files in dispose, filename: " + fileName, e);
+            log.error("{0}: Failure closing files in dispose, filename: {1}",
+                    logCacheName, fileName, e);
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Shutdown complete.");
-        }
+        log.info("{0}: Shutdown complete.", logCacheName);
     }
 
     /**
@@ -1121,11 +1069,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
                 if (doRecycle)
                 {
                     recycle.add(ded);
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug(logCacheName + "recycled ded " + ded);
-                    }
-
+                    log.debug("{0}: recycled ded {1}", logCacheName, ded);
                 }
             }
             finally
@@ -1140,15 +1084,13 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
      */
     protected void doOptimizeRealTime()
     {
-        if (isRealTimeOptimizationEnabled && !isOptimizing && removeCount++ >= cattr.getOptimizeAtRemoveCount())
+        if (isRealTimeOptimizationEnabled && !isOptimizing
+            && removeCount++ >= cattr.getOptimizeAtRemoveCount())
         {
             isOptimizing = true;
 
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Optimizing file. removeCount [" + removeCount + "] OptimizeAtRemoveCount ["
-                    + cattr.getOptimizeAtRemoveCount() + "]");
-            }
+            log.info("{0}: Optimizing file. removeCount [{1}] OptimizeAtRemoveCount [{2}]",
+                    logCacheName, removeCount, cattr.getOptimizeAtRemoveCount());
 
             if (currentOptimizationThread == null)
             {
@@ -1201,10 +1143,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
     {
         ElapsedTimer timer = new ElapsedTimer();
         timesOptimized++;
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Beginning Optimization #" + timesOptimized);
-        }
+        log.info("{0}: Beginning Optimization #{1}", logCacheName, timesOptimized);
 
         // CREATE SNAPSHOT
         IndexedDiskElementDescriptor[] defragList = null;
@@ -1220,7 +1159,6 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         }
         finally
         {
-            // Release if I acquired.
             storageLock.writeLock().unlock();
         }
 
@@ -1247,7 +1185,7 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             }
             catch (IOException e)
             {
-                log.error(logCacheName + "Error optimizing queued puts.", e);
+                log.error("{0}: Error optimizing queued puts.", logCacheName, e);
             }
 
             // RESTORE NORMAL OPERATION
@@ -1265,10 +1203,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
             storageLock.writeLock().unlock();
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info(logCacheName + "Finished #" + timesOptimized + " Optimization took " + timer.getElapsedTimeString());
-        }
+        log.info("{0}: Finished #{1}, Optimization took {2}",
+                logCacheName, timesOptimized, timer.getElapsedTimeString());
     }
 
     /**
@@ -1318,15 +1254,12 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         }
         catch (IOException e)
         {
-            log.error(logCacheName + "Error occurred during defragmentation.", e);
+            log.error("{0}: Error occurred during defragmentation.", logCacheName, e);
         }
         finally
         {
-            if (log.isInfoEnabled())
-            {
-                log.info(logCacheName + "Defragmentation took " + timer.getElapsedTimeString() + ". File Size (before="
-                    + preFileSize + ") (after=" + postFileSize + ") (truncating to " + expectedNextPos + ")");
-            }
+            log.info("{0}: Defragmentation took {1}. File Size (before={2}) (after={3}) (truncating to {4})",
+                    logCacheName, timer.getElapsedTimeString(), preFileSize, postFileSize, expectedNextPos);
         }
 
         return 0;
@@ -1470,17 +1403,18 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
      */
     public void dump(boolean dumpValues)
     {
-        if (log.isDebugEnabled())
+        if (log.isTraceEnabled())
         {
-            log.debug(logCacheName + "[dump] Number of keys: " + keyHash.size());
+            log.trace("{0}: [dump] Number of keys: {1}", logCacheName, keyHash.size());
 
             for (Map.Entry<K, IndexedDiskElementDescriptor> e : keyHash.entrySet())
             {
                 K key = e.getKey();
                 IndexedDiskElementDescriptor ded = e.getValue();
 
-                log.debug(logCacheName + "[dump] Disk element, key: " + key + ", pos: " + ded.pos + ", ded.len" + ded.len
-                    + (dumpValues ? ", val: " + get(key) : ""));
+                log.trace("{0}: [dump] Disk element, key: {1}, pos: {2}, len: {3}" +
+                        (dumpValues ? ", val: " + get(key) : ""),
+                        logCacheName, key, ded.pos, ded.len);
             }
         }
     }
@@ -1512,8 +1446,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         elems.add(new StatElement<>("Key Map Size", Integer.valueOf(this.keyHash != null ? this.keyHash.size() : -1)));
         try
         {
-            elems
-                .add(new StatElement<>("Data File Length", Long.valueOf(this.dataFile != null ? this.dataFile.length() : -1L)));
+            elems.add(
+                    new StatElement<>("Data File Length", Long.valueOf(this.dataFile != null ? this.dataFile.length() : -1L)));
         }
         catch (IOException e)
         {
@@ -1700,11 +1634,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
 
             addToRecycleBin(value);
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "Removing key: [" + key + "] from key store.");
-                log.debug(logCacheName + "Key store size: [" + this.size() + "].");
-            }
+            log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+            log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
 
             doOptimizeRealTime();
         }
@@ -1741,11 +1672,8 @@ public class IndexedDiskCache<K, V> extends AbstractDiskCache<K, V>
         protected void processRemovedLRU(K key, IndexedDiskElementDescriptor value)
         {
             addToRecycleBin(value);
-            if (log.isDebugEnabled())
-            {
-                log.debug(logCacheName + "Removing key: [" + key + "] from key store.");
-                log.debug(logCacheName + "Key store size: [" + this.size() + "].");
-            }
+            log.debug("{0}: Removing key: [{1}] from key store.", logCacheName, key);
+            log.debug("{0}: Key store size: [{1}].", logCacheName, this.size());
 
             doOptimizeRealTime();
         }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
index e34bd51..7d0822f 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/indexed/IndexedDiskCacheFactory.java
@@ -24,8 +24,8 @@ import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Creates disk cache instances.
@@ -34,7 +34,7 @@ public class IndexedDiskCacheFactory
     extends AbstractAuxiliaryCacheFactory
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( IndexedDiskCacheFactory.class );
+    private static final Log log = LogManager.getLog( IndexedDiskCacheFactory.class );
 
     /**
      * Create an instance of an IndexedDiskCache.
@@ -52,10 +52,7 @@ public class IndexedDiskCacheFactory
                                        ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
         IndexedDiskCacheAttributes idca = (IndexedDiskCacheAttributes) iaca;
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Creating DiskCache for attributes = " + idca );
-        }
+        log.debug( "Creating DiskCache for attributes = {0}", idca );
 
         IndexedDiskCache<K, V> cache = new IndexedDiskCache<>( idca, elementSerializer );
         cache.setCacheEventLogger( cacheEventLogger );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
index 30ffaee..2bd7ff2 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
@@ -45,9 +45,9 @@ import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
 import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This is the jdbc disk cache plugin.
@@ -83,7 +83,7 @@ public class JDBCDiskCache<K, V>
     extends AbstractDiskCache<K, V>
 {
     /** The local logger. */
-    private static final Log log = LogFactory.getLog( JDBCDiskCache.class );
+    private static final Log log = LogManager.getLog( JDBCDiskCache.class );
 
     /** custom serialization */
     private IElementSerializer elementSerializer = new StandardSerializer();
@@ -126,10 +126,7 @@ public class JDBCDiskCache<K, V>
         setTableState( tableState );
         setJdbcDiskCacheAttributes( cattr );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "jdbcDiskCacheAttributes = " + getJdbcDiskCacheAttributes() );
-        }
+        log.info( "jdbcDiskCacheAttributes = {0}", () -> getJdbcDiskCacheAttributes() );
 
         // This initializes the pool access.
         this.dsFactory = dsFactory;
@@ -150,17 +147,11 @@ public class JDBCDiskCache<K, V>
     {
     	updateCount.incrementAndGet();
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "updating, ce = " + ce );
-        }
+        log.debug( "updating, ce = {0}", ce );
 
         try (Connection con = getDataSource().getConnection())
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Putting [" + ce.getKey() + "] on disk." );
-            }
+            log.debug( "Putting [{0}] on disk.",  () -> ce.getKey());
 
             byte[] element;
 
@@ -186,7 +177,7 @@ public class JDBCDiskCache<K, V>
             if ( updateCount.get() % LOG_INTERVAL == 0 )
             {
                 // TODO make a log stats method
-                log.info( "Update Count [" + updateCount + "]" );
+                log.info( "Update Count [{0}]", updateCount);
             }
         }
     }
@@ -315,14 +306,11 @@ public class JDBCDiskCache<K, V>
             psUpdate.setString( 6, this.getCacheName() );
             psUpdate.execute();
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "ran update " + sqlU );
-            }
+            log.debug( "ran update {0}", sqlU );
         }
-        catch ( SQLException e2 )
+        catch ( SQLException e )
         {
-            log.error( "e2 sql [" + sqlU + "] Exception: ", e2 );
+            log.error( "Error executing update sql [{0}]", sqlU, e );
         }
     }
 
@@ -350,10 +338,7 @@ public class JDBCDiskCache<K, V>
                 exists = rs.next();
             }
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "[" + ce.getKey() + "] existing status is " + exists );
-            }
+            log.debug( "[{0}] existing status is {1}", ce.getKey(), exists );
         }
         catch ( SQLException e )
         {
@@ -375,10 +360,7 @@ public class JDBCDiskCache<K, V>
     {
     	getCount.incrementAndGet();
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Getting [" + key + "] from disk" );
-        }
+        log.debug( "Getting [{0}] from disk", key );
 
         if ( !isAlive() )
         {
@@ -414,13 +396,9 @@ public class JDBCDiskCache<K, V>
                                 // USE THE SERIALIZER
                                 obj = getElementSerializer().deSerialize( data, null );
                             }
-                            catch ( IOException ioe )
-                            {
-                                log.error( "Problem getting item for key [" + key + "]", ioe );
-                            }
                             catch ( Exception e )
                             {
-                                log.error( "Problem getting item for key [" + key + "]", e );
+                                log.error( "Problem getting item for key [{0}]", key, e );
                             }
                         }
                     }
@@ -429,7 +407,8 @@ public class JDBCDiskCache<K, V>
         }
         catch ( SQLException sqle )
         {
-            log.error( "Caught a SQL exception trying to get the item for key [" + key + "]", sqle );
+            log.error( "Caught a SQL exception trying to get the item for key [{0}]",
+                    key, sqle );
         }
 
         if ( log.isInfoEnabled() )
@@ -437,7 +416,7 @@ public class JDBCDiskCache<K, V>
             if ( getCount.get() % LOG_INTERVAL == 0 )
             {
                 // TODO make a log stats method
-                log.info( "Get Count [" + getCount + "]" );
+                log.info( "Get Count [{0}]", getCount );
             }
         }
         return obj;
@@ -455,10 +434,7 @@ public class JDBCDiskCache<K, V>
     {
     	getMatchingCount.incrementAndGet();
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Getting [" + pattern + "] from disk" );
-        }
+        log.debug( "Getting [{0}] from disk", pattern);
 
         if ( !isAlive() )
         {
@@ -494,13 +470,9 @@ public class JDBCDiskCache<K, V>
                                     ICacheElement<K, V> value = getElementSerializer().deSerialize( data, null );
                                     results.put( (K) key, value );
                                 }
-                                catch ( IOException ioe )
-                                {
-                                    log.error( "Problem getting items for pattern [" + pattern + "]", ioe );
-                                }
                                 catch ( Exception e )
                                 {
-                                    log.error( "Problem getting items for pattern [" + pattern + "]", e );
+                                    log.error( "Problem getting items for pattern [{0}]", pattern, e );
                                 }
                             }
                         }
@@ -510,7 +482,8 @@ public class JDBCDiskCache<K, V>
         }
         catch ( SQLException sqle )
         {
-            log.error( "Caught a SQL exception trying to get items for pattern [" + pattern + "]", sqle );
+            log.error( "Caught a SQL exception trying to get items for pattern [{0}]",
+                    pattern, sqle );
         }
 
         if ( log.isInfoEnabled() )
@@ -518,7 +491,7 @@ public class JDBCDiskCache<K, V>
             if ( getMatchingCount.get() % LOG_INTERVAL == 0 )
             {
                 // TODO make a log stats method
-                log.info( "Get Matching Count [" + getMatchingCount + "]" );
+                log.info( "Get Matching Count [{0}]", getMatchingCount);
             }
         }
         return results;
@@ -533,10 +506,7 @@ public class JDBCDiskCache<K, V>
         String likePattern = pattern.replaceAll( "\\.\\+", "%" );
         likePattern = likePattern.replaceAll( "\\.", "_" );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "pattern = [" + likePattern + "]" );
-        }
+        log.debug( "pattern = [{0}]", likePattern );
 
         return likePattern;
     }
@@ -584,7 +554,7 @@ public class JDBCDiskCache<K, V>
             }
             catch ( SQLException e )
             {
-                log.error( "Problem creating statement. sql [" + sql + "]", e );
+                log.error( "Problem creating statement. sql [{0}]", sql, e );
                 setAlive(false);
             }
         }
@@ -622,7 +592,7 @@ public class JDBCDiskCache<K, V>
                     setAlive(false);
                 }
             }
-            catch ( Exception e )
+            catch ( SQLException e )
             {
                 log.error( "Problem removing all.", e );
                 reset();
@@ -630,10 +600,8 @@ public class JDBCDiskCache<K, V>
         }
         else
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "RemoveAll was requested but the request was not fulfilled: allowRemoveAll is set to false." );
-            }
+            log.info( "RemoveAll was requested but the request was not fulfilled: "
+                    + "allowRemoveAll is set to false." );
         }
     }
 
@@ -680,10 +648,10 @@ public class JDBCDiskCache<K, V>
             logApplicationEvent( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
                                  "Deleted expired elements.  URL: " + getDiskLocation() );
         }
-        catch ( Exception e )
+        catch ( SQLException e )
         {
-            logError( getAuxiliaryCacheAttributes().getName(), "deleteExpired", e.getMessage() + " URL: "
-                + getDiskLocation() );
+            logError( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
+                    e.getMessage() + " URL: " + getDiskLocation() );
             log.error( "Problem removing expired elements from the table.", e );
             reset();
         }
@@ -708,16 +676,14 @@ public class JDBCDiskCache<K, V>
     public void processDispose()
     {
         ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), (K)"none", ICacheEventLogger.DISPOSE_EVENT );
+
         try
         {
-            try
-            {
-            	dsFactory.close();
-            }
-            catch ( SQLException e )
-            {
-                log.error( "Problem shutting down.", e );
-            }
+        	dsFactory.close();
+        }
+        catch ( SQLException e )
+        {
+            log.error( "Problem shutting down.", e );
         }
         finally
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
index 0ba22ea..2868e82 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
@@ -35,9 +35,9 @@ import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.behavior.IRequireScheduler;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.PropertySetter;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This factory should create JDBC auxiliary caches.
@@ -49,7 +49,7 @@ public class JDBCDiskCacheFactory
     implements IRequireScheduler
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( JDBCDiskCacheFactory.class );
+    private static final Log log = LogManager.getLog( JDBCDiskCacheFactory.class );
 
     /**
      * A map of TableState objects to table names. Each cache has a table state object, which is
@@ -133,7 +133,7 @@ public class JDBCDiskCacheFactory
 			}
         	catch (SQLException e)
         	{
-        		log.error("Could not close data source factory " + dsFactory.getName(), e);
+        		log.error("Could not close data source factory {0}", dsFactory.getName(), e);
 			}
         }
 
@@ -188,11 +188,8 @@ public class JDBCDiskCacheFactory
                 ShrinkerThread newShrinkerThread = new ShrinkerThread();
 
                 long intervalMillis = Math.max( 999, cattr.getShrinkerIntervalSeconds() * 1000 );
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Setting the shrinker to run every [" + intervalMillis + "] ms. for table ["
-                        + key + "]" );
-                }
+                log.info( "Setting the shrinker to run every [{0}] ms. for table [{1}]",
+                        intervalMillis, key );
                 shrinkerService.scheduleAtFixedRate(newShrinkerThread, 0, intervalMillis, TimeUnit.MILLISECONDS);
 
                 return newShrinkerThread;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/ShrinkerThread.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/ShrinkerThread.java
index 752845b..427cce6 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/ShrinkerThread.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/ShrinkerThread.java
@@ -1,5 +1,9 @@
 package org.apache.commons.jcs.auxiliary.disk.jdbc;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,12 +23,8 @@ package org.apache.commons.jcs.auxiliary.disk.jdbc;
  * under the License.
  */
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Calls delete expired on the disk caches. The shrinker is run by a clock daemon. The shrinker
@@ -36,7 +36,7 @@ public class ShrinkerThread
     implements Runnable
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( ShrinkerThread.class );
+    private static final Log log = LogManager.getLog( ShrinkerThread.class );
 
     /** A set of JDBCDiskCache objects to call deleteExpired on. */
     private final Set<JDBCDiskCache<?, ?>> shrinkSet =
@@ -86,7 +86,7 @@ public class ShrinkerThread
         }
         catch ( Throwable e )
         {
-            log.error( "Caught an expcetion while trying to delete expired items.", e );
+            log.error( "Caught an exception while trying to delete expired items.", e );
         }
     }
 
@@ -95,10 +95,8 @@ public class ShrinkerThread
      */
     private void deleteExpiredFromAllRegisteredRegions()
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Running JDBC disk cache shrinker.  Number of regions [" + shrinkSet.size() + "]" );
-        }
+        log.info( "Running JDBC disk cache shrinker. Number of regions [{0}]",
+                () -> shrinkSet.size() );
 
         Object[] caches = null;
 
@@ -117,20 +115,14 @@ public class ShrinkerThread
                 int deleted = cache.deleteExpired();
                 long end = System.currentTimeMillis();
 
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Deleted [" + deleted + "] expired for region [" + cache.getCacheName() + "] for table ["
-                        + cache.getTableName() + "] in " + ( end - start ) + " ms." );
-                }
+                log.info( "Deleted [{0}] expired for region [{1}] for table [{2}] in {3} ms.",
+                        deleted, cache.getCacheName(), cache.getTableName(), end - start );
 
                 // don't pause after the last call to delete expired.
                 if ( i < caches.length - 1 )
                 {
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( "Pausing for [" + this.getPauseBetweenRegionCallsMillis()
-                            + "] ms. before shrinking the next region." );
-                    }
+                    log.info( "Pausing for [{0}] ms before shrinking the next region.",
+                            this.getPauseBetweenRegionCallsMillis() );
 
                     try
                     {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
index 4c8f12b..ce84aef 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/JndiDataSourceFactory.java
@@ -29,8 +29,8 @@ import javax.naming.NamingException;
 import javax.sql.DataSource;
 
 import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheAttributes;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * A factory that looks up the DataSource from JNDI.  It is also able
@@ -48,7 +48,7 @@ import org.apache.commons.logging.LogFactory;
 public class JndiDataSourceFactory implements DataSourceFactory
 {
     /** The log. */
-    private static Log log = LogFactory.getLog(JndiDataSourceFactory.class);
+    private static Log log = LogManager.getLog(JndiDataSourceFactory.class);
 
     /** The name of the factory. */
     private String name;
@@ -127,23 +127,17 @@ public class JndiDataSourceFactory implements DataSourceFactory
         try
         {
             this.path = config.getJndiPath();
-            if (log.isDebugEnabled())
-            {
-                log.debug("JNDI path: " + path);
-            }
+            log.debug("JNDI path: {0}", path);
 
             this.ttl = config.getJndiTTL();
-            if (log.isDebugEnabled())
-            {
-                log.debug("Time between context lookups: " + ttl);
-            }
+            log.debug("Time between context lookups: {0}", ttl);
 
     		Hashtable<String, Object> env = new Hashtable<>();
             ctx = new InitialContext(env);
 
-            if (log.isDebugEnabled())
+            if (log.isTraceEnabled())
             {
-            	log.debug("Created new InitialContext");
+            	log.trace("Created new InitialContext");
             	debugCtx(ctx);
             }
         }
@@ -170,10 +164,10 @@ public class JndiDataSourceFactory implements DataSourceFactory
      */
     private void debugCtx(Context ctx) throws NamingException
     {
-        log.debug("InitialContext -------------------------------");
+        log.trace("InitialContext -------------------------------");
         Map<?, ?> env = ctx.getEnvironment();
-        log.debug("Environment properties:" + env.size());
-        env.forEach((key, value) -> log.debug("    " + key + ": " + value));
-        log.debug("----------------------------------------------");
+        log.trace("Environment properties: {0}", env.size());
+        env.forEach((key, value) -> log.trace("    {0}: {1}", key, value));
+        log.trace("----------------------------------------------");
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
index d5417a8..27037b8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/dsfactory/SharedPoolDataSourceFactory.java
@@ -28,8 +28,8 @@ import org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS;
 import org.apache.commons.dbcp2.datasources.InstanceKeyDataSource;
 import org.apache.commons.dbcp2.datasources.SharedPoolDataSource;
 import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheAttributes;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * A factory that looks up the DataSource using the JDBC2 pool methods.
@@ -42,7 +42,7 @@ import org.apache.commons.logging.LogFactory;
 public class SharedPoolDataSourceFactory implements DataSourceFactory
 {
     /** The log. */
-    private static Log log = LogFactory.getLog(SharedPoolDataSourceFactory.class);
+    private static Log log = LogManager.getLog(SharedPoolDataSourceFactory.class);
 
     /** The name of the factory. */
     private String name;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
index a821a26..e2e964d 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
@@ -34,8 +34,8 @@ import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCacheFactory;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This factory should create hsql disk caches.
@@ -46,7 +46,7 @@ public class HSQLDiskCacheFactory
     extends JDBCDiskCacheFactory
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( HSQLDiskCacheFactory.class );
+    private static final Log log = LogManager.getLog( HSQLDiskCacheFactory.class );
 
     /** The databases. */
     private Set<String> databases;
@@ -101,10 +101,7 @@ public class HSQLDiskCacheFactory
 
         if ( databases.contains( database ) )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "We already setup database [" + database + "]" );
-            }
+            log.info("We already setup database [{0}]", database);
             return;
         }
 
@@ -130,10 +127,7 @@ public class HSQLDiskCacheFactory
         Connection cConn = DriverManager.getConnection( database, user, password );
         setupTable( cConn, attributes.getTableName() );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Finished setting up database [" + database + "]" );
-        }
+        log.info( "Finished setting up database [{0}]", database);
 
         databases.add( database );
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
index 6888275..b1fe59a 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCache.java
@@ -27,8 +27,8 @@ import org.apache.commons.jcs.auxiliary.disk.jdbc.TableState;
 import org.apache.commons.jcs.auxiliary.disk.jdbc.dsfactory.DataSourceFactory;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * The MySQLDiskCache extends the core JDBCDiskCache.
@@ -42,7 +42,7 @@ public class MySQLDiskCache<K, V>
 	extends JDBCDiskCache<K, V>
 {
     /** local logger */
-    private static final Log log = LogFactory.getLog( MySQLDiskCache.class );
+    private static final Log log = LogManager.getLog( MySQLDiskCache.class );
 
     /** config attributes */
     private final MySQLDiskCacheAttributes mySQLDiskCacheAttributes;
@@ -64,10 +64,7 @@ public class MySQLDiskCache<K, V>
 
         mySQLDiskCacheAttributes = attributes;
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "MySQLDiskCacheAttributes = " + attributes );
-        }
+        log.debug( "MySQLDiskCacheAttributes = {0}", attributes );
     }
 
     /**
@@ -120,10 +117,7 @@ public class MySQLDiskCache<K, V>
         String likePattern = pattern.replaceAll( "\\.\\+", "%" );
         likePattern = likePattern.replaceAll( "\\.", "_" );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "pattern = [" + likePattern + "]" );
-        }
+        log.debug( "pattern = [{0}]", likePattern );
 
         return likePattern;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
index 090f766..728201c 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLDiskCacheFactory.java
@@ -34,8 +34,8 @@ import org.apache.commons.jcs.auxiliary.disk.jdbc.mysql.util.ScheduleParser;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This factory should create mysql disk caches.
@@ -46,7 +46,7 @@ public class MySQLDiskCacheFactory
     extends JDBCDiskCacheFactory
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( MySQLDiskCacheFactory.class );
+    private static final Log log = LogManager.getLog( MySQLDiskCacheFactory.class );
 
     /**
      * This factory method should create an instance of the mysqlcache.
@@ -93,11 +93,8 @@ public class MySQLDiskCacheFactory
         {
             if ( attributes.getOptimizationSchedule() != null )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Will try to configure optimization for table [" + attributes.getTableName()
-                        + "] on schedule [" + attributes.getOptimizationSchedule() + "]" );
-                }
+                log.info( "Will try to configure optimization for table [{0}] on schedule [{1}]",
+                        () -> attributes.getTableName(),  () -> attributes.getOptimizationSchedule());
 
                 MySQLTableOptimizer optimizer = new MySQLTableOptimizer( attributes, tableState, ds );
 
@@ -115,15 +112,14 @@ public class MySQLDiskCacheFactory
                 }
                 catch ( ParseException e )
                 {
-                    log.warn( "Problem creating optimization schedule for table [" + attributes.getTableName() + "]", e );
+                    log.warn( "Problem creating optimization schedule for table [{0}]",
+                            attributes.getTableName(), e );
                 }
             }
             else
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Optimization is not configured for table [" + attributes.getTableName() + "]" );
-                }
+                log.info( "Optimization is not configured for table [{0}]",
+                        attributes.getTableName());
             }
         }
     }
@@ -136,18 +132,14 @@ public class MySQLDiskCacheFactory
      */
     protected void scheduleOptimization( Date startTime, MySQLTableOptimizer optimizer )
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "startTime [" + startTime + "] for optimizer " + optimizer );
-        }
+        log.info( "startTime [{0}] for optimizer {1}", startTime, optimizer );
 
-        // get the runnable from the factory
-        OptimizerTask runnable = new OptimizerTask( optimizer );
         Date now = new Date();
         long initialDelay = startTime.getTime() - now.getTime();
 
-        // have the daemon execute our runnable
-        getScheduledExecutorService().scheduleAtFixedRate(runnable, initialDelay, 86400000L, TimeUnit.MILLISECONDS );
+        // have the daemon execute the optimization
+        getScheduledExecutorService().scheduleAtFixedRate(() -> optimizeTable(optimizer),
+                initialDelay, 86400L, TimeUnit.SECONDS );
     }
 
     /**
@@ -155,42 +147,16 @@ public class MySQLDiskCacheFactory
      * <p>
      * @author Aaron Smuts
      */
-    private static class OptimizerTask
-        implements Runnable
+    private void optimizeTable(MySQLTableOptimizer optimizer)
     {
-        /** Handles optimization */
-        private MySQLTableOptimizer optimizer = null;
-
-        /**
-         * Get a handle on the optimizer.
-         * <p>
-         * @param optimizer
-         */
-        public OptimizerTask( MySQLTableOptimizer optimizer )
+        if ( optimizer != null )
         {
-            this.optimizer = optimizer;
+            boolean success = optimizer.optimizeTable();
+            log.info( "Optimization success status [{0}]", success );
         }
-
-        /**
-         * This calls optimize on the optimizer.
-         * <p>
-         * @see java.lang.Runnable#run()
-         */
-        @Override
-        public void run()
+        else
         {
-            if ( optimizer != null )
-            {
-                boolean success = optimizer.optimizeTable();
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Optimization success status [" + success + "]" );
-                }
-            }
-            else
-            {
-                log.warn( "OptimizerRunner: The optimizer is null.  Could not optimize table." );
-            }
+            log.warn( "OptimizerRunner: The optimizer is null. Could not optimize table." );
         }
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLTableOptimizer.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLTableOptimizer.java
index 3b9b9b6..58a8fd3 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLTableOptimizer.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/mysql/MySQLTableOptimizer.java
@@ -27,8 +27,8 @@ import java.sql.Statement;
 import javax.sql.DataSource;
 
 import org.apache.commons.jcs.auxiliary.disk.jdbc.TableState;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * The MySQL Table Optimizer can optimize MySQL tables. It knows how to optimize for MySQL databases
@@ -42,7 +42,7 @@ import org.apache.commons.logging.LogFactory;
 public class MySQLTableOptimizer
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( MySQLTableOptimizer.class );
+    private static final Log log = LogManager.getLog( MySQLTableOptimizer.class );
 
     /** The data source */
     private DataSource dataSource = null;
@@ -120,18 +120,15 @@ public class MySQLTableOptimizer
 
         if ( tableState.getState() == TableState.OPTIMIZATION_RUNNING )
         {
-            log
-                .warn( "Skipping optimization.  Optimize was called, but the table state indicates that an optimization is currently running." );
+            log.warn( "Skipping optimization. Optimize was called, but the "
+                    + "table state indicates that an optimization is currently running." );
             return false;
         }
 
         try
         {
             tableState.setState( TableState.OPTIMIZATION_RUNNING );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Optimizing table [" + this.getTableName() + "]" );
-            }
+            log.info( "Optimizing table [{0}]", this.getTableName());
 
             try (Connection con = dataSource.getConnection())
             {
@@ -150,16 +147,13 @@ public class MySQLTableOptimizer
                         String status = rs.getString( "Msg_type" );
                         String message = rs.getString( "Msg_text" );
 
-                        if ( log.isInfoEnabled() )
-                        {
-                            log.info( "Message Type: " + status );
-                            log.info( "Message: " + message );
-                        }
+                        log.info( "Message Type: {0}", status );
+                        log.info( "Message: {0}", message );
 
                         if ( "error".equals( status ) )
                         {
-                            log.warn( "Optimization was in error. Will attempt to repair the table. Message: "
-                                + message );
+                            log.warn( "Optimization was in error. Will attempt "
+                                    + "to repair the table. Message: {0}", message);
 
                             // try to repair the table.
                             success = repairTable( sStatement );
@@ -172,14 +166,13 @@ public class MySQLTableOptimizer
 
                     // log the table status
                     String statusString = getTableStatus( sStatement );
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( "Table status after optimizing table [" + this.getTableName() + "]\n" + statusString );
-                    }
+                    log.info( "Table status after optimizing table [{0}]: {1}",
+                            this.getTableName(), statusString );
                 }
                 catch ( SQLException e )
                 {
-                    log.error( "Problem optimizing table [" + this.getTableName() + "]", e );
+                    log.error( "Problem optimizing table [{0}]",
+                            this.getTableName(), e );
                     return false;
                 }
             }
@@ -193,10 +186,8 @@ public class MySQLTableOptimizer
             tableState.setState( TableState.FREE );
 
             long end = System.currentTimeMillis();
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Optimization of table [" + this.getTableName() + "] took " + ( end - start ) + " ms." );
-            }
+            log.info( "Optimization of table [{0}] took {1} ms.",
+                    this.getTableName(), end - start );
         }
 
         return success;
@@ -260,14 +251,11 @@ public class MySQLTableOptimizer
                 success = true;
             }
         }
-        if ( log.isInfoEnabled() )
-        {
-            log.info( repairString );
-        }
+        log.info("{0}", repairString);
 
         if ( !success )
         {
-            log.warn( "Failed to repair the table. " + repairString );
+            log.warn( "Failed to repair the table. {0}", repairString );
         }
         return success;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCache.java
index 0a7ccea..44e7a5d 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCache.java
@@ -35,8 +35,8 @@ import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
 import org.apache.commons.jcs.engine.behavior.IZombie;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Lateral distributor. Returns null on get by default. Net search not implemented.
@@ -45,7 +45,7 @@ public class LateralCache<K, V>
     extends AbstractAuxiliaryCacheEventLogging<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( LateralCache.class );
+    private static final Log log = LogManager.getLog( LateralCache.class );
 
     /** generalize this, use another interface */
     private final ILateralCacheAttributes lateralCacheAttributes;
@@ -99,11 +99,8 @@ public class LateralCache<K, V>
         {
             if (ce != null)
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "update: lateral = [" + lateralCacheService + "], " + "CacheInfo.listenerId = "
-                        + CacheInfo.listenerId );
-                }
+                log.debug( "update: lateral = [{0}], CacheInfo.listenerId = {1}",
+                        lateralCacheService, CacheInfo.listenerId );
                 lateralCacheService.update( ce, CacheInfo.listenerId );
             }
         }
@@ -200,10 +197,7 @@ public class LateralCache<K, V>
     protected boolean processRemove( K key )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "removing key:" + key );
-        }
+        log.debug( "removing key: {0}", key );
 
         try
         {
@@ -317,7 +311,7 @@ public class LateralCache<K, V>
     private void handleException( Exception ex, String msg )
         throws IOException
     {
-        log.error( "Disabling lateral cache due to error " + msg, ex );
+        log.error( "Disabling lateral cache due to error {0}", msg, ex );
 
         lateralCacheService = new ZombieCacheServiceNonLocal<>( lateralCacheAttributes.getZombieQueueMaxSize() );
         // may want to flush if region specifies
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java
index 3a7d9d4..3ac2bfd 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWait.java
@@ -41,8 +41,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Used to queue up update requests to the underlying cache. These requests will be processed in
@@ -52,7 +52,7 @@ public class LateralCacheNoWait<K, V>
     extends AbstractAuxiliaryCache<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( LateralCacheNoWait.class );
+    private static final Log log = LogManager.getLog( LateralCacheNoWait.class );
 
     /** The cache */
     private final LateralCache<K, V> cache;
@@ -79,10 +79,7 @@ public class LateralCacheNoWait<K, V>
     {
         this.cache = cache;
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Constructing LateralCacheNoWait, LateralCache = [" + cache + "]" );
-        }
+        log.debug( "Constructing LateralCacheNoWait, LateralCache = [{0}]", cache );
 
         CacheEventQueueFactory<K, V> fact = new CacheEventQueueFactory<>();
         this.eventQueue = fact.createCacheEventQueue( new CacheAdaptor<>( cache ), CacheInfo.listenerId, cache
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
index 807ec69..4d15a3e 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/LateralCacheNoWaitFacade.java
@@ -40,8 +40,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Used to provide access to multiple services under nowait protection. Composite factory should
@@ -53,7 +53,7 @@ public class LateralCacheNoWaitFacade<K, V>
     extends AbstractAuxiliaryCache<K, V>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( LateralCacheNoWaitFacade.class );
+    private static final Log log = LogManager.getLog( LateralCacheNoWaitFacade.class );
 
     /** The queuing facade to the client. */
     public LateralCacheNoWait<K, V>[] noWaits;
@@ -78,10 +78,7 @@ public class LateralCacheNoWaitFacade<K, V>
      */
     public LateralCacheNoWaitFacade(ILateralCacheListener<K, V> listener, LateralCacheNoWait<K, V>[] noWaits, ILateralCacheAttributes cattr )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "CONSTRUCTING NO WAIT FACADE" );
-        }
+        log.debug( "CONSTRUCTING NO WAIT FACADE" );
         this.listener = listener;
         this.noWaits = noWaits;
         this.cacheName = cattr.getCacheName();
@@ -119,10 +116,7 @@ public class LateralCacheNoWaitFacade<K, V>
 
         if ( containsNoWait( noWait ) )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "No Wait already contained, [" + noWait + "]" );
-            }
+            log.debug( "No Wait already contained, [{0}]", noWait );
             return false;
         }
 
@@ -189,10 +183,8 @@ public class LateralCacheNoWaitFacade<K, V>
     public void update( ICacheElement<K, V> ce )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "updating through lateral cache facade, noWaits.length = " + noWaits.length );
-        }
+        log.debug( "updating through lateral cache facade, noWaits.length = {0}",
+                noWaits.length );
 
         for (LateralCacheNoWait<K, V> nw : noWaits)
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
index c254a45..5374043 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPCacheFactory.java
@@ -41,10 +41,10 @@ import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.behavior.IShutdownObserver;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.discovery.UDPDiscoveryManager;
 import org.apache.commons.jcs.utils.discovery.UDPDiscoveryService;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Constructs a LateralCacheNoWaitFacade for the given configuration. Each lateral service / local
@@ -57,7 +57,7 @@ public class LateralTCPCacheFactory
     extends AbstractAuxiliaryCacheFactory
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( LateralTCPCacheFactory.class );
+    private static final Log log = LogManager.getLog( LateralTCPCacheFactory.class );
 
     /** Address to service map. */
     private ConcurrentHashMap<String, ICacheServiceNonLocal<?, ?>> csnlInstances;
@@ -97,17 +97,12 @@ public class LateralTCPCacheFactory
         if ( lac.getTcpServers() != null )
         {
             StringTokenizer it = new StringTokenizer( lac.getTcpServers(), "," );
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Configured for [" + it.countTokens() + "]  servers." );
-            }
+            log.debug( "Configured for [{0}] servers.", () -> it.countTokens() );
+
             while ( it.hasMoreElements() )
             {
                 String server = (String) it.nextElement();
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "tcp server = " + server );
-                }
+                log.debug( "tcp server = {0}", server );
                 ITCPLateralCacheAttributes lacC = (ITCPLateralCacheAttributes) lac.clone();
                 lacC.setTcpServer( server );
 
@@ -142,20 +137,14 @@ public class LateralTCPCacheFactory
         cache.setCacheEventLogger( cacheEventLogger );
         cache.setElementSerializer( elementSerializer );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Created cache for noWait, cache [" + cache + "]" );
-        }
+        log.debug( "Created cache for noWait, cache [{0}]", cache );
 
         LateralCacheNoWait<K, V> lateralNoWait = new LateralCacheNoWait<>( cache );
         lateralNoWait.setCacheEventLogger( cacheEventLogger );
         lateralNoWait.setElementSerializer( elementSerializer );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Created LateralCacheNoWait for [" + lca + "] LateralCacheNoWait = [" + lateralNoWait
-                + "]" );
-        }
+        log.info( "Created LateralCacheNoWait for [{0}] LateralCacheNoWait = [{1}]",
+                lca, lateralNoWait );
 
         return lateralNoWait;
     }
@@ -233,7 +222,7 @@ public class LateralTCPCacheFactory
             // If service creation did not succeed last time, force retry
             if (service instanceof ZombieCacheServiceNonLocal)
             {
-                log.info("Disposing of zombie service instance for [" + name + "]");
+                log.info("Disposing of zombie service instance for [{0}]", name);
                 return null;
             }
 
@@ -243,15 +232,12 @@ public class LateralTCPCacheFactory
         ICacheServiceNonLocal<K, V> service =
                 (ICacheServiceNonLocal<K, V>) csnlInstances.computeIfAbsent(key, name -> {
 
-                    log.info( "Instance for [" + name + "] is null, creating" );
+                    log.info( "Instance for [{0}] is null, creating", name );
 
                     // Create the service
                     try
                     {
-                        if ( log.isInfoEnabled() )
-                        {
-                            log.info( "Creating TCP service, lca = " + lca );
-                        }
+                        log.info( "Creating TCP service, lca = {0}", lca );
 
                         return new LateralTCPService<>( lca );
                     }
@@ -289,10 +275,8 @@ public class LateralTCPCacheFactory
         String key = ilca.getUdpDiscoveryAddr() + ":" + ilca.getUdpDiscoveryPort();
 
         LateralTCPDiscoveryListener ins = lTCPDLInstances.computeIfAbsent(key, key1 -> {
-            if ( log.isInfoEnabled() )
-            {
-                log.info("Created new discovery listener for " + key1 + " cacheName for request " + ilca.getCacheName());
-            }
+            log.info("Created new discovery listener for cacheName {0} for request {1}",
+                    key1, ilca.getCacheName());
             return new LateralTCPDiscoveryListener( this.getName(),  cacheManager);
         });
 
@@ -312,7 +296,8 @@ public class LateralTCPCacheFactory
         {
             try
             {
-                addLateralCacheListener( iaca.getCacheName(), LateralTCPListener.getInstance( iaca, cacheMgr ) );
+                addLateralCacheListener( iaca.getCacheName(),
+                        LateralTCPListener.getInstance( iaca, cacheMgr ) );
             }
             catch ( IOException ioe )
             {
@@ -321,10 +306,7 @@ public class LateralTCPCacheFactory
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Not creating a listener since we are not receiving." );
-            }
+            log.debug( "Not creating a listener since we are not receiving." );
         }
     }
 
@@ -363,10 +345,7 @@ public class LateralTCPCacheFactory
         // don't create a listener if we are not receiving.
         if ( attr.isReceive() )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Getting listener for " + attr );
-            }
+            log.info( "Getting listener for {0}", attr );
 
             // make a listener. if one doesn't exist
             listener = LateralTCPListener.getInstance( attr, cacheMgr );
@@ -376,10 +355,7 @@ public class LateralTCPCacheFactory
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Not creating a listener since we are not receiving." );
-            }
+            log.debug( "Not creating a listener since we are not receiving." );
         }
 
         return listener;
@@ -420,10 +396,8 @@ public class LateralTCPCacheFactory
             discovery.addParticipatingCacheName( lac.getCacheName() );
             discovery.addDiscoveryListener( discoveryListener );
 
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Registered TCP lateral cache [" + lac.getCacheName() + "] with UDPDiscoveryService." );
-            }
+            log.info( "Registered TCP lateral cache [{0}] with UDPDiscoveryService.",
+                    () -> lac.getCacheName() );
         }
         return discovery;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java
index 60170f1..94d37d8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPDiscoveryListener.java
@@ -1,5 +1,12 @@
 package org.apache.commons.jcs.auxiliary.lateral.socket.tcp;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -26,17 +33,10 @@ import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWait;
 import org.apache.commons.jcs.auxiliary.lateral.LateralCacheNoWaitFacade;
 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.discovery.DiscoveredService;
 import org.apache.commons.jcs.utils.discovery.behavior.IDiscoveryListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * This knows how to add and remove discovered services. It observes UDP discovery events.
@@ -47,7 +47,7 @@ public class LateralTCPDiscoveryListener
     implements IDiscoveryListener
 {
     /** The log factory */
-    private static final Log log = LogFactory.getLog( LateralTCPDiscoveryListener.class );
+    private static final Log log = LogManager.getLog( LateralTCPDiscoveryListener.class );
 
     /**
      * Map of no wait facades. these are used to determine which regions are locally configured to
@@ -148,29 +148,21 @@ public class LateralTCPDiscoveryListener
     {
         @SuppressWarnings("unchecked") // Need to cast because of common map for all facades
         LateralCacheNoWaitFacade<K, V> facade = (LateralCacheNoWaitFacade<K, V>)facades.get( noWait.getCacheName() );
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "addNoWait > Got facade for " + noWait.getCacheName() + " = " + facade );
-        }
+        log.debug( "addNoWait > Got facade for {0} = {1}", noWait.getCacheName(), facade );
 
         if ( facade != null )
         {
             boolean isNew = facade.addNoWait( noWait );
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Called addNoWait, isNew = " + isNew );
-            }
+            log.debug( "Called addNoWait, isNew = {0}", isNew );
             return isNew;
         }
         else
         {
             if ( !knownDifferentlyConfiguredRegions.contains( noWait.getCacheName() ) )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "addNoWait > Different nodes are configured differently or region ["
-                        + noWait.getCacheName() + "] is not yet used on this side.  " );
-                }
+                log.info( "addNoWait > Different nodes are configured differently "
+                        + "or region [{0}] is not yet used on this side.",
+                        () -> noWait.getCacheName() );
                 knownDifferentlyConfiguredRegions.add( noWait.getCacheName() );
             }
             return false;
@@ -188,29 +180,21 @@ public class LateralTCPDiscoveryListener
     {
         @SuppressWarnings("unchecked") // Need to cast because of common map for all facades
         LateralCacheNoWaitFacade<K, V> facade = (LateralCacheNoWaitFacade<K, V>)facades.get( noWait.getCacheName() );
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "removeNoWait > Got facade for " + noWait.getCacheName() + " = " + facade );
-        }
+        log.debug( "removeNoWait > Got facade for {0} = {1}", noWait.getCacheName(), facade);
 
         if ( facade != null )
         {
             boolean removed = facade.removeNoWait( noWait );
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Called removeNoWait, removed " + removed );
-            }
+            log.debug( "Called removeNoWait, removed {0}", removed );
             return removed;
         }
         else
         {
             if ( !knownDifferentlyConfiguredRegions.contains( noWait.getCacheName() ) )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "removeNoWait > Different nodes are configured differently or region ["
-                        + noWait.getCacheName() + "] is not yet used on this side.  " );
-                }
+                log.info( "removeNoWait > Different nodes are configured differently "
+                        + "or region [{0}] is not yet used on this side.",
+                        () -> noWait.getCacheName() );
                 knownDifferentlyConfiguredRegions.add( noWait.getCacheName() );
             }
             return false;
@@ -249,10 +233,7 @@ public class LateralTCPDiscoveryListener
             {
                 AuxiliaryCache<?, ?> ic = cacheManager.getAuxiliaryCache(factoryName, cacheName);
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Got cache, ic = " + ic );
-                }
+                log.debug( "Got cache, ic = {0}", ic );
 
                 // add this to the nowaits for this cachename
                 if ( ic != null )
@@ -270,16 +251,13 @@ public class LateralTCPDiscoveryListener
                     }
 
                     addNoWait( (LateralCacheNoWait<?, ?>) ic );
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Called addNoWait for cacheName [" + cacheName + "]" );
-                    }
+                    log.debug( "Called addNoWait for cacheName [{0}]", cacheName );
                 }
             }
         }
         else
         {
-            log.warn( "No cache names found in message " + service );
+            log.warn( "No cache names found in message {0}", service );
         }
     }
 
@@ -307,10 +285,7 @@ public class LateralTCPDiscoveryListener
             {
                 AuxiliaryCache<?, ?> ic = cacheManager.getAuxiliaryCache(factoryName, cacheName);
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Got cache, ic = " + ic );
-                }
+                log.debug( "Got cache, ic = {0}", ic );
 
                 // remove this to the nowaits for this cachename
                 if ( ic != null )
@@ -328,16 +303,13 @@ public class LateralTCPDiscoveryListener
                     }
 
                     removeNoWait( (LateralCacheNoWait<?, ?>) ic );
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Called removeNoWait for cacheName [" + cacheName + "]" );
-                    }
+                    log.debug( "Called removeNoWait for cacheName [{0}]", cacheName );
                 }
             }
         }
         else
         {
-            log.warn( "No cache names found in message " + service );
+            log.warn( "No cache names found in message {0}", service );
         }
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
index 9506a34..84e68cb 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPListener.java
@@ -29,9 +29,9 @@ import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -47,9 +47,9 @@ import org.apache.commons.jcs.engine.behavior.IShutdownObserver;
 import org.apache.commons.jcs.engine.control.CompositeCache;
 import org.apache.commons.jcs.engine.control.CompositeCacheManager;
 import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Listens for connections from other TCP lateral caches and handles them. The initialization method
@@ -60,7 +60,7 @@ public class LateralTCPListener<K, V>
     implements ILateralCacheListener<K, V>, IShutdownObserver
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( LateralTCPListener.class );
+    private static final Log log = LogManager.getLog( LateralTCPListener.class );
 
     /** How long the server will block on an accept(). 0 is infinite. */
     private static final int acceptTimeOut = 1000;
@@ -69,8 +69,8 @@ public class LateralTCPListener<K, V>
     private transient ICompositeCacheManager cacheManager;
 
     /** Map of available instances, keyed by port */
-    private static final HashMap<String, ILateralCacheListener<?, ?>> instances =
-        new HashMap<>();
+    private static final ConcurrentHashMap<String, ILateralCacheListener<?, ?>> instances =
+        new ConcurrentHashMap<>();
 
     /** The socket listener */
     private ListenerThread receiver;
@@ -112,26 +112,23 @@ public class LateralTCPListener<K, V>
      * @param cacheMgr
      * @return The instance value
      */
-    public synchronized static <K, V> LateralTCPListener<K, V>
+    public static <K, V> LateralTCPListener<K, V>
         getInstance( ITCPLateralCacheAttributes ilca, ICompositeCacheManager cacheMgr )
     {
         @SuppressWarnings("unchecked") // Need to cast because of common map for all instances
-        LateralTCPListener<K, V> ins = (LateralTCPListener<K, V>) instances.get( String.valueOf( ilca.getTcpListenerPort() ) );
+        LateralTCPListener<K, V> ins = (LateralTCPListener<K, V>) instances.computeIfAbsent(
+                String.valueOf( ilca.getTcpListenerPort() ),
+                k -> {
+                    LateralTCPListener<K, V> newIns = new LateralTCPListener<>( ilca );
 
-        if ( ins == null )
-        {
-            ins = new LateralTCPListener<>( ilca );
-
-            ins.init();
-            ins.setCacheManager( cacheMgr );
+                    newIns.init();
+                    newIns.setCacheManager( cacheMgr );
 
-            instances.put( String.valueOf( ilca.getTcpListenerPort() ), ins );
+                    log.info( "Created new listener {0}",
+                            () -> ilca.getTcpListenerPort() );
 
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Created new listener " + ilca.getTcpListenerPort() );
-            }
-        }
+                    return newIns;
+                });
 
         return ins;
     }
@@ -161,7 +158,7 @@ public class LateralTCPListener<K, V>
             terminated = new AtomicBoolean(false);
             shutdown = new AtomicBoolean(false);
 
-            log.info( "Listening on port " + port );
+            log.info( "Listening on port {0}", port );
 
             ServerSocket serverSocket = new ServerSocket( port );
             serverSocket.setSoTimeout( acceptTimeOut );
@@ -196,10 +193,7 @@ public class LateralTCPListener<K, V>
         throws IOException
     {
         this.listenerId = id;
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "set listenerId = " + id );
-        }
+        log.debug( "set listenerId = {0}", id );
     }
 
     /**
@@ -226,19 +220,15 @@ public class LateralTCPListener<K, V>
         throws IOException
     {
         putCnt++;
-        if ( log.isInfoEnabled() )
+        if ( log.isInfoEnabled() && getPutCnt() % 100 == 0 )
         {
-            if ( getPutCnt() % 100 == 0 )
-            {
-                log.info( "Put Count (port " + getTcpLateralCacheAttributes().getTcpListenerPort() + ") = "
-                    + getPutCnt() );
-            }
+            log.info( "Put Count (port {0}) = {1}",
+                    () -> getTcpLateralCacheAttributes().getTcpListenerPort(),
+                    () -> getPutCnt() );
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handlePut> cacheName=" + element.getCacheName() + ", key=" + element.getKey() );
-        }
+        log.debug( "handlePut> cacheName={0}, key={1}",
+                () -> element.getCacheName(), () -> element.getKey() );
 
         getCache( element.getCacheName() ).localUpdate( element );
     }
@@ -255,18 +245,12 @@ public class LateralTCPListener<K, V>
         throws IOException
     {
         removeCnt++;
-        if ( log.isInfoEnabled() )
+        if ( log.isInfoEnabled() && getRemoveCnt() % 100 == 0 )
         {
-            if ( getRemoveCnt() % 100 == 0 )
-            {
-                log.info( "Remove Count = " + getRemoveCnt() );
-            }
+            log.info( "Remove Count = {0}", () -> getRemoveCnt() );
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleRemove> cacheName=" + cacheName + ", key=" + key );
-        }
+        log.debug( "handleRemove> cacheName={0}, key={1}", cacheName, key );
 
         getCache( cacheName ).localRemove( key );
     }
@@ -280,10 +264,7 @@ public class LateralTCPListener<K, V>
     public void handleRemoveAll( String cacheName )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleRemoveAll> cacheName=" + cacheName );
-        }
+        log.debug( "handleRemoveAll> cacheName={0}", cacheName );
 
         getCache( cacheName ).localRemoveAll();
     }
@@ -300,19 +281,14 @@ public class LateralTCPListener<K, V>
         throws IOException
     {
         getCnt++;
-        if ( log.isInfoEnabled() )
+        if ( log.isInfoEnabled() && getGetCnt() % 100 == 0 )
         {
-            if ( getGetCnt() % 100 == 0 )
-            {
-                log.info( "Get Count (port " + getTcpLateralCacheAttributes().getTcpListenerPort() + ") = "
-                    + getGetCnt() );
-            }
+            log.info( "Get Count (port {0}) = {1}",
+                    () -> getTcpLateralCacheAttributes().getTcpListenerPort(),
+                    () -> getGetCnt() );
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleGet> cacheName=" + cacheName + ", key = " + key );
-        }
+        log.debug( "handleGet> cacheName={0}, key={1}", cacheName, key );
 
         return getCache( cacheName ).localGet( key );
     }
@@ -329,19 +305,14 @@ public class LateralTCPListener<K, V>
         throws IOException
     {
         getCnt++;
-        if ( log.isInfoEnabled() )
+        if ( log.isInfoEnabled() && getGetCnt() % 100 == 0 )
         {
-            if ( getGetCnt() % 100 == 0 )
-            {
-                log.info( "GetMatching Count (port " + getTcpLateralCacheAttributes().getTcpListenerPort() + ") = "
-                    + getGetCnt() );
-            }
+            log.info( "GetMatching Count (port {0}) = {1}",
+                    () -> getTcpLateralCacheAttributes().getTcpListenerPort(),
+                    () -> getGetCnt() );
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleGetMatching> cacheName=" + cacheName + ", pattern = " + pattern );
-        }
+        log.debug( "handleGetMatching> cacheName={0}, pattern={1}", cacheName, pattern );
 
         return getCache( cacheName ).localGetMatching( pattern );
     }
@@ -367,10 +338,8 @@ public class LateralTCPListener<K, V>
     public void handleDispose( String cacheName )
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "handleDispose > cacheName=" + cacheName + " | Ignoring message.  Do not dispose from remote." );
-        }
+        log.info( "handleDispose > cacheName={0} | Ignoring message. "
+                + "Do not dispose from remote.", cacheName );
 
         // TODO handle active deregistration, rather than passive detection
         terminated.set(true);
@@ -408,10 +377,7 @@ public class LateralTCPListener<K, V>
                 throw new RuntimeException("Could not retrieve cache manager instance", e);
             }
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "cacheMgr = " + getCacheManager() );
-            }
+            log.debug( "cacheMgr = {0}", () -> getCacheManager() );
         }
 
         return getCacheManager().getCache( name );
@@ -509,10 +475,7 @@ public class LateralTCPListener<K, V>
 
                 outer: while ( true )
                 {
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Waiting for clients to connect " );
-                    }
+                    log.debug( "Waiting for clients to connect " );
 
                     Socket socket = null;
                     inner: while (true)
@@ -520,10 +483,7 @@ public class LateralTCPListener<K, V>
                         // Check to see if we've been asked to exit, and exit
                         if (terminated.get())
                         {
-                            if (log.isDebugEnabled())
-                            {
-                                log.debug("Thread terminated, exiting gracefully");
-                            }
+                            log.debug("Thread terminated, exiting gracefully");
                             break outer;
                         }
 
@@ -542,7 +502,7 @@ public class LateralTCPListener<K, V>
                     if ( socket != null && log.isDebugEnabled() )
                     {
                         InetAddress inetAddress = socket.getInetAddress();
-                        log.debug( "Connected to client at " + inetAddress );
+                        log.debug( "Connected to client at {0}", inetAddress );
                     }
 
                     handler = new ConnectionHandler( socket );
@@ -582,26 +542,13 @@ public class LateralTCPListener<K, V>
             "synthetic-access" })
         public void run()
         {
-            ObjectInputStream ois;
-
-            try
-            {
-                ois = new ObjectInputStreamClassLoaderAware( socket.getInputStream(), null );
-            }
-            catch ( Exception e )
-            {
-                log.error( "Could not open ObjectInputStream on " + socket, e );
-
-                return;
-            }
-
-            LateralElementDescriptor<K, V> led;
-
-            try
+            try (ObjectInputStream ois =
+                    new ObjectInputStreamClassLoaderAware( socket.getInputStream(), null ))
             {
                 while ( true )
                 {
-                    led = (LateralElementDescriptor<K, V>) ois.readObject();
+                    LateralElementDescriptor<K, V> led =
+                            (LateralElementDescriptor<K, V>) ois.readObject();
 
                     if ( led == null )
                     {
@@ -614,11 +561,8 @@ public class LateralTCPListener<K, V>
                     }
                     else
                     {
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "receiving LateralElementDescriptor from another" + "led = " + led
-                                + ", led.command = " + led.command + ", led.ce = " + led.ce );
-                        }
+                        log.debug( "receiving LateralElementDescriptor from another led = {0}",
+                                led );
 
                         handle( led );
                     }
@@ -626,25 +570,16 @@ public class LateralTCPListener<K, V>
             }
             catch ( EOFException e )
             {
-                log.info( "Caught java.io.EOFException closing connection." + e.getMessage() );
+                log.info( "Caught EOFException, closing connection.", e );
             }
             catch ( SocketException e )
             {
-                log.info( "Caught java.net.SocketException closing connection." + e.getMessage() );
+                log.info( "Caught SocketException, closing connection.", e );
             }
             catch ( Exception e )
             {
                 log.error( "Unexpected exception.", e );
             }
-
-            try
-            {
-                ois.close();
-            }
-            catch ( IOException e )
-            {
-                log.error( "Could not close object input stream.", e );
-            }
         }
 
         /**
@@ -681,20 +616,15 @@ public class LateralTCPListener<K, V>
                             {
                                 if ( test.getVal().hashCode() == led.valHashCode )
                                 {
-                                    if ( log.isDebugEnabled() )
-                                    {
-                                        log.debug( "Filtering detected identical hashCode [" + led.valHashCode
-                                            + "], not issuing a remove for led " + led );
-                                    }
+                                    log.debug( "Filtering detected identical hashCode [{0}], "
+                                            + "not issuing a remove for led {1}",
+                                            led.valHashCode, led );
                                     return;
                                 }
                                 else
                                 {
-                                    if ( log.isDebugEnabled() )
-                                    {
-                                        log.debug( "Different hashcodes, in cache [" + test.getVal().hashCode()
-                                            + "] sent [" + led.valHashCode + "]" );
-                                    }
+                                    log.debug( "Different hashcodes, in cache [{0}] sent [{1}]",
+                                            test.getVal().hashCode(), led.valHashCode );
                                 }
                             }
                         }
@@ -738,19 +668,13 @@ public class LateralTCPListener<K, V>
     {
         if ( shutdown.compareAndSet(false, true) )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Shutting down TCP Lateral receiver." );
-            }
+            log.info( "Shutting down TCP Lateral receiver." );
 
             receiver.interrupt();
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Shutdown already called." );
-            }
+            log.debug( "Shutdown already called." );
         }
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
index f0f49ed..69b23b2 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPSender.java
@@ -28,8 +28,8 @@ import java.net.Socket;
 import org.apache.commons.jcs.auxiliary.lateral.LateralElementDescriptor;
 import org.apache.commons.jcs.auxiliary.lateral.socket.tcp.behavior.ITCPLateralCacheAttributes;
 import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class is based on the log4j SocketAppender class. I'm using a different repair structure, so
@@ -38,7 +38,7 @@ import org.apache.commons.logging.LogFactory;
 public class LateralTCPSender
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( LateralTCPSender.class );
+    private static final Log log = LogManager.getLog( LateralTCPSender.class );
 
     /** Config */
     private int socketOpenTimeOut;
@@ -76,11 +76,7 @@ public class LateralTCPSender
 
         String h2 = p1.substring( 0, p1.indexOf( ":" ) );
         int po = Integer.parseInt( p1.substring( p1.indexOf( ":" ) + 1 ) );
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "h2 = " + h2 );
-            log.debug( "po = " + po );
-        }
+        log.debug( "h2 = {0}, po = {1}", h2, po );
 
         if ( h2.length() == 0 )
         {
@@ -102,10 +98,7 @@ public class LateralTCPSender
     {
         try
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Attempting connection to [" + host + "]" );
-            }
+            log.info( "Attempting connection to [{0}]", host );
 
             // have time out socket open do this for us
             try
@@ -131,12 +124,12 @@ public class LateralTCPSender
         }
         catch ( java.net.ConnectException e )
         {
-            log.debug( "Remote host [" + host + "] refused connection." );
+            log.debug( "Remote host [{0}] refused connection.", host );
             throw e;
         }
         catch ( IOException e )
         {
-            log.debug( "Could not connect to [" + host + "]. Exception is " + e );
+            log.debug( "Could not connect to [{0}]", host, e );
             throw e;
         }
     }
@@ -153,13 +146,10 @@ public class LateralTCPSender
         sendCnt++;
         if ( log.isInfoEnabled() && sendCnt % 100 == 0 )
         {
-            log.info( "Send Count (port " + socket.getPort() + ") = " + sendCnt );
+            log.info( "Send Count (port {0}) = {1}", socket.getPort(), sendCnt );
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "sending LateralElementDescriptor" );
-        }
+        log.debug( "sending LateralElementDescriptor" );
 
         if ( led == null )
         {
@@ -221,7 +211,7 @@ public class LateralTCPSender
             }
             catch ( IOException ioe )
             {
-                log.error( "Problem cleaning socket before send " + socket, ioe );
+                log.error( "Problem cleaning socket before send {0}", socket, ioe );
                 throw ioe;
             }
 
@@ -261,10 +251,7 @@ public class LateralTCPSender
     public void dispose()
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Dispose called" );
-        }
+        log.info( "Dispose called" );
         // WILL CLOSE CONNECTION USED BY ALL
         oos.close();
         socket.close();
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
index 068ad3c..553ad95 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/lateral/socket/tcp/LateralTCPService.java
@@ -35,8 +35,8 @@ import org.apache.commons.jcs.engine.CacheElement;
 import org.apache.commons.jcs.engine.CacheInfo;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * A lateral cache service implementation. Does not implement getGroupKey
@@ -46,7 +46,7 @@ public class LateralTCPService<K, V>
     implements ICacheServiceNonLocal<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( LateralTCPService.class );
+    private static final Log log = LogManager.getLog( LateralTCPService.class );
 
     /** special configuration */
     private boolean allowPut;
@@ -76,18 +76,14 @@ public class LateralTCPService<K, V>
         {
             sender = new LateralTCPSender( lca );
 
-            if ( log.isInfoEnabled() )
-            {
-                log.debug( "Created sender to [" + lca.getTcpServer() + "]" );
-            }
+            log.debug( "Created sender to [{0}]", () -> lca.getTcpServer() );
         }
         catch ( IOException e )
         {
             // log.error( "Could not create sender", e );
             // This gets thrown over and over in recovery mode.
             // The stack trace isn't useful here.
-            log.error( "Could not create sender to [" + lca.getTcpServer() + "] -- " + e.getMessage() );
-
+            log.error( "Could not create sender to [{0}] -- {1}", lca.getTcpServer(), e.getMessage());
             throw e;
         }
     }
@@ -135,10 +131,8 @@ public class LateralTCPService<K, V>
         // on the other end, this will be a server config option
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Issuing a remove for a put" );
-            }
+            log.debug( "Issuing a remove for a put" );
+
             // set the value to null so we don't send the item
             CacheElement<K, V> ce = new CacheElement<>( item.getCacheName(), item.getKey(), null );
             LateralElementDescriptor<K, V> led = new LateralElementDescriptor<>( ce );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteAuxiliaryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteAuxiliaryCache.java
index 0a50d0f..f599a43 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteAuxiliaryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteAuxiliaryCache.java
@@ -48,10 +48,10 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.serialization.SerializationConversionUtil;
 import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /** Abstract base for remote caches. I'm trying to break out and reuse common functionality. */
 public abstract class AbstractRemoteAuxiliaryCache<K, V>
@@ -59,7 +59,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
     implements IRemoteCacheClient<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( AbstractRemoteAuxiliaryCache.class );
+    private static final Log log = LogManager.getLog( AbstractRemoteAuxiliaryCache.class );
 
     /**
      * This does the work. In an RMI instances, it will be a remote reference. In an http remote
@@ -99,25 +99,20 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
 
         if ( log.isDebugEnabled() )
         {
-            log.debug( "Construct> cacheName=" + cattr.getCacheName() );
-            log.debug( "irca = " + getRemoteCacheAttributes() );
-            log.debug( "remote = " + remote );
-            log.debug( "listener = " + listener );
+            log.debug( "Construct> cacheName={0}", () -> cattr.getCacheName() );
+            log.debug( "irca = {0}", () -> getRemoteCacheAttributes() );
+            log.debug( "remote = {0}", remote );
+            log.debug( "listener = {0}", listener );
         }
 
         // use a pool if it is greater than 0
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "GetTimeoutMillis() = " + getRemoteCacheAttributes().getGetTimeoutMillis() );
-        }
+        log.debug( "GetTimeoutMillis() = {0}",
+                () -> getRemoteCacheAttributes().getGetTimeoutMillis() );
 
         if ( getRemoteCacheAttributes().getGetTimeoutMillis() > 0 )
         {
             pool = ThreadPoolManager.getInstance().getExecutorService( getRemoteCacheAttributes().getThreadPoolName() );
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Thread Pool = " + pool );
-            }
+            log.debug( "Thread Pool = {0}", pool );
             usePoolForGet = true;
         }
     }
@@ -131,10 +126,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
     protected void processDispose()
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Disposing of remote cache." );
-        }
+        log.info( "Disposing of remote cache." );
         try
         {
             if ( getRemoteCacheListener() != null )
@@ -228,27 +220,24 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
             // used timed get in order to timeout
             ICacheElement<K, V> ice = future.get(timeout, TimeUnit.MILLISECONDS);
 
-            if ( log.isDebugEnabled() )
+            if ( ice == null )
             {
-                if ( ice == null )
-                {
-                    log.debug( "nothing found in remote cache" );
-                }
-                else
-                {
-                    log.debug( "found item in remote cache" );
-                }
+                log.debug( "nothing found in remote cache" );
+            }
+            else
+            {
+                log.debug( "found item in remote cache" );
             }
             return ice;
         }
         catch ( TimeoutException te )
         {
-            log.warn( "TimeoutException, Get Request timed out after " + timeout );
+            log.warn( "TimeoutException, Get Request timed out after {0}", timeout );
             throw new IOException( "Get Request timed out after " + timeout );
         }
         catch ( InterruptedException ex )
         {
-            log.warn( "InterruptedException, Get Request timed out after " + timeout );
+            log.warn( "InterruptedException, Get Request timed out after {0}", timeout );
             throw new IOException( "Get Request timed out after " + timeout );
         }
         catch (ExecutionException ex)
@@ -323,10 +312,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
     {
         if ( !this.getRemoteCacheAttributes().getGetOnly() )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "remove> key=" + key );
-            }
+            log.debug( "remove> key={0}", key );
             try
             {
                 getRemoteCacheService().remove( cacheName, key, getListenerId() );
@@ -380,10 +366,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
             ICacheElementSerialized<K, V> serialized = null;
             try
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "sending item to remote server" );
-                }
+                log.debug( "sending item to remote server" );
 
                 // convert so we don't have to know about the object on the
                 // other end.
@@ -393,7 +376,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
             }
             catch ( NullPointerException npe )
             {
-                log.error( "npe for ce = " + ce + "ce.attr = " + ce.getElementAttributes(), npe );
+                log.error( "npe for ce = {0} ce.attr = {1}", ce, ce.getElementAttributes(), npe );
             }
             catch ( Exception ex )
             {
@@ -404,10 +387,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "get only mode, not sending to remote server" );
-            }
+            log.debug( "get only mode, not sending to remote server" );
         }
     }
 
@@ -450,10 +430,7 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
             {
                 getRemoteCacheListener().setListenerId( id );
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "set listenerId = " + id );
-                }
+                log.debug( "set listenerId = {0}", id );
             }
             catch ( Exception e )
             {
@@ -474,13 +451,10 @@ public abstract class AbstractRemoteAuxiliaryCache<K, V>
         {
             try
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "get listenerId = " + getRemoteCacheListener().getListenerId() );
-                }
+                log.debug( "get listenerId = {0}", getRemoteCacheListener().getListenerId() );
                 return getRemoteCacheListener().getListenerId();
             }
-            catch ( Exception e )
+            catch ( IOException e )
             {
                 log.error( "Problem getting listenerId", e );
             }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheListener.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheListener.java
index 090011d..e2681a7 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheListener.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheListener.java
@@ -31,17 +31,17 @@ import org.apache.commons.jcs.engine.behavior.ICacheElementSerialized;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.control.CompositeCacheManager;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.net.HostNameUtil;
 import org.apache.commons.jcs.utils.serialization.SerializationConversionUtil;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /** Shared listener base. */
 public abstract class AbstractRemoteCacheListener<K, V>
     implements IRemoteCacheListener<K, V>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( AbstractRemoteCacheListener.class );
+    private static final Log log = LogManager.getLog( AbstractRemoteCacheListener.class );
 
     /** The cached name of the local host. The remote server gets this for logging purposes. */
     private static String localHostName = null;
@@ -91,10 +91,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
         throws IOException
     {
         listenerId = id;
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "set listenerId = [" + id + "]" );
-        }
+        log.info( "set listenerId = [{0}]", id );
     }
 
     /**
@@ -108,10 +105,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public long getListenerId()
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "get listenerId = [" + listenerId + "]" );
-        }
+        log.debug( "get listenerId = [{0}]", listenerId );
         return listenerId;
 
     }
@@ -126,10 +120,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public RemoteType getRemoteType()
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "getRemoteType = [" + irca.getRemoteType() + "]" );
-        }
+        log.debug( "getRemoteType = [{0}]", () -> irca.getRemoteType() );
         return irca.getRemoteType();
     }
 
@@ -149,35 +140,23 @@ public abstract class AbstractRemoteCacheListener<K, V>
     {
         if ( irca.getRemoveUponRemotePut() )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "PUTTING ELEMENT FROM REMOTE, (  invalidating ) " );
-            }
+            log.debug( "PUTTING ELEMENT FROM REMOTE, (  invalidating ) " );
             handleRemove( cb.getCacheName(), cb.getKey() );
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "PUTTING ELEMENT FROM REMOTE, ( updating ) " );
-                log.debug( "cb = " + cb );
-            }
+            log.debug( "PUTTING ELEMENT FROM REMOTE, ( updating ) " );
+            log.debug( "cb = {0}", cb );
 
             // Eventually the instance of will not be necessary.
             if ( cb instanceof ICacheElementSerialized )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Object needs to be deserialized." );
-                }
+                log.debug( "Object needs to be deserialized." );
                 try
                 {
                     cb = SerializationConversionUtil.getDeSerializedCacheElement(
                             (ICacheElementSerialized<K, V>) cb, this.elementSerializer );
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Deserialized result = " + cb );
-                    }
+                    log.debug( "Deserialized result = {0}", cb );
                 }
                 catch ( IOException e )
                 {
@@ -204,10 +183,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public void handleRemove( String cacheName, K key )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleRemove> cacheName=" + cacheName + ", key=" + key );
-        }
+        log.debug( "handleRemove> cacheName={0}, key={1}", cacheName, key );
 
         getCacheManager().<K, V>getCache( cacheName ).localRemove( key );
     }
@@ -222,10 +198,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public void handleRemoveAll( String cacheName )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleRemoveAll> cacheName=" + cacheName );
-        }
+        log.debug( "handleRemoveAll> cacheName={0}", cacheName );
 
         getCacheManager().<K, V>getCache( cacheName ).localRemoveAll();
     }
@@ -238,10 +211,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public void handleDispose( String cacheName )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "handleDispose> cacheName=" + cacheName );
-        }
+        log.debug( "handleDispose> cacheName={0}", cacheName );
         // TODO consider what to do here, we really don't want to
         // dispose, we just want to disconnect.
         // just allow the cache to go into error recovery mode.
@@ -260,11 +230,8 @@ public abstract class AbstractRemoteCacheListener<K, V>
             {
                 cacheMgr = CompositeCacheManager.getInstance();
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "had to get cacheMgr" );
-                    log.debug( "cacheMgr = " + cacheMgr );
-                }
+                log.debug( "had to get cacheMgr" );
+                log.debug( "cacheMgr = {0}", cacheMgr );
             }
             catch (CacheException e)
             {
@@ -273,10 +240,7 @@ public abstract class AbstractRemoteCacheListener<K, V>
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "already got cacheMgr = " + cacheMgr );
-            }
+            log.debug( "already got cacheMgr = {0}", cacheMgr );
         }
 
         return cacheMgr;
@@ -315,9 +279,9 @@ public abstract class AbstractRemoteCacheListener<K, V>
     public String toString()
     {
         StringBuilder buf = new StringBuilder();
-        buf.append( "\n AbstractRemoteCacheListener: " );
-        buf.append( "\n RemoteHost = " + irca.getRemoteLocation().toString() );
-        buf.append( "\n ListenerId = " + listenerId );
+        buf.append( "\n AbstractRemoteCacheListener: " )
+           .append( "\n RemoteHost = ").append(irca.getRemoteLocation())
+           .append( "\n ListenerId = ").append(listenerId);
         return buf.toString();
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheNoWaitFacade.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheNoWaitFacade.java
index 9ae49ee..3c9650f 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheNoWaitFacade.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/AbstractRemoteCacheNoWaitFacade.java
@@ -37,15 +37,15 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /** An abstract base for the No Wait Facade.  Different implementations will failover differently. */
 public abstract class AbstractRemoteCacheNoWaitFacade<K, V>
     extends AbstractAuxiliaryCache<K, V>
 {
     /** log instance */
-    private static final Log log = LogFactory.getLog( AbstractRemoteCacheNoWaitFacade.class );
+    private static final Log log = LogManager.getLog( AbstractRemoteCacheNoWaitFacade.class );
 
     /** The connection to a remote server, or a zombie. */
     protected List<RemoteCacheNoWait<K, V>> noWaits;
@@ -64,10 +64,7 @@ public abstract class AbstractRemoteCacheNoWaitFacade<K, V>
     public AbstractRemoteCacheNoWaitFacade( List<RemoteCacheNoWait<K,V>> noWaits, IRemoteCacheAttributes rca,
                                     ICacheEventLogger cacheEventLogger, IElementSerializer elementSerializer )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "CONSTRUCTING NO WAIT FACADE" );
-        }
+        log.debug( "CONSTRUCTING NO WAIT FACADE" );
         this.remoteCacheAttributes = rca;
         setCacheEventLogger( cacheEventLogger );
         setElementSerializer( elementSerializer );
@@ -89,10 +86,8 @@ public abstract class AbstractRemoteCacheNoWaitFacade<K, V>
     public void update( ICacheElement<K, V> ce )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "updating through cache facade, noWaits.length = " + noWaits.size() );
-        }
+        log.debug( "updating through cache facade, noWaits.length = {0}",
+                () -> noWaits.size() );
 
         for (RemoteCacheNoWait<K, V> nw : noWaits)
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCache.java
index 2db1577..de06f59 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCache.java
@@ -31,8 +31,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Client proxy for an RMI remote cache.
@@ -44,7 +44,7 @@ public class RemoteCache<K, V>
     extends AbstractRemoteAuxiliaryCache<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( RemoteCache.class );
+    private static final Log log = LogManager.getLog( RemoteCache.class );
 
     /** for error notifications */
     private RemoteCacheMonitor monitor;
@@ -151,17 +151,11 @@ public class RemoteCache<K, V>
         // process.
         monitor.notifyError();
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Initiating failover, rcnwf = " + facade );
-        }
+        log.debug( "Initiating failover, rcnwf = {0}", facade );
 
         if ( facade != null && facade.getAuxiliaryCacheAttributes().getRemoteType() == RemoteType.LOCAL )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Found facade, calling failover" );
-            }
+            log.debug( "Found facade, calling failover" );
             // may need to remove the noWait index here. It will be 0 if it is
             // local since there is only 1 possible listener.
             facade.failover( facade.getPrimaryServer() );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheFailoverRunner.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheFailoverRunner.java
index 8a8c4a9..effc4fd 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheFailoverRunner.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheFailoverRunner.java
@@ -112,7 +112,7 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
         if ( log.isInfoEnabled() )
         {
             int failoverIndex = facade.getAuxiliaryCacheAttributes().getFailoverIndex();
-            log.info( "Exiting failover runner. Failover index = " + failoverIndex);
+            log.info( "Exiting failover runner. Failover index = {0}", failoverIndex);
 
             if ( failoverIndex <= 0 )
             {
@@ -162,35 +162,28 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                 }
 
                 int fidx = rca0.getFailoverIndex();
-                log.debug( "fidx = " + fidx + " failovers.size = " + failovers.size() );
+                log.debug( "fidx = {0} failovers.size = {1}", () -> fidx,
+                        () -> failovers.size() );
 
                 // shouldn't we see if the primary is backup?
                 // If we don't check the primary, if it gets connected in the
                 // background,
                 // we will disconnect it only to put it right back
                 ListIterator<RemoteLocation> i = failovers.listIterator(fidx); // + 1; // +1 skips the primary
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "starting at failover i = " + i.nextIndex() );
-                }
+                log.debug( "starting at failover i = {0}", i );
 
                 // try them one at a time until successful
                 for ( ; i.hasNext() && !allright.get();)
                 {
                     RemoteLocation server = i.next();
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Trying server [" + server + "] at failover index i = " + i );
-                    }
+                    log.debug( "Trying server [{1}] at failover index i = {1}",
+                            server, i );
 
                     RemoteCacheAttributes rca = (RemoteCacheAttributes) rca0.clone();
                     rca.setRemoteLocation(server);
                     RemoteCacheManager rcm = cacheFactory.getManager( rca );
 
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "RemoteCacheAttributes for failover = " + rca.toString() );
-                    }
+                    log.debug( "RemoteCacheAttributes for failover = {0}", rca );
 
                     if (rcm != null)
                     {
@@ -204,25 +197,20 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                             facade.restorePrimaryServer((RemoteCacheNoWait<K, V>) ic);
                             rca0.setFailoverIndex( i.nextIndex() );
 
-                            if ( log.isDebugEnabled() )
+                            log.debug( "setting ALLRIGHT to true" );
+                            if ( i.hasPrevious() )
                             {
-                                log.debug( "setting ALLRIGHT to true" );
-                                if ( i.hasPrevious() )
-                                {
-                                    log.debug( "Moving to Primary Recovery Mode, failover index = " + i.nextIndex() );
-                                }
-                                else
-                                {
-                                    log.debug( "No need to connect to failover, the primary server is back up." );
-                                }
+                                log.debug( "Moving to Primary Recovery Mode, failover index = {0}", i );
+                            }
+                            else
+                            {
+                                log.debug( "No need to connect to failover, the primary server is back up." );
                             }
 
                             allright.set(true);
 
-                            if ( log.isInfoEnabled() )
-                            {
-                                log.info( "CONNECTED to host = [" + rca.getRemoteLocation() + "]" );
-                            }
+                            log.info( "CONNECTED to host = [{0}]",
+                                    () -> rca.getRemoteLocation() );
                         }
                     }
                 }
@@ -232,15 +220,10 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
             // connected to some backup server.
             else
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "ALLRIGHT is true " );
-                }
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Failover runner is in primary recovery mode. Failover index = "
-                        + rca0.getFailoverIndex() + "\n" + "Will now try to reconnect to primary server." );
-                }
+                log.debug( "ALLRIGHT is true " );
+                log.info( "Failover runner is in primary recovery mode. "
+                        + "Failover index = {0} Will now try to reconnect to "
+                        + "primary server.", () -> rca0.getFailoverIndex() );
             }
 
             boolean primaryRestoredSuccessfully = false;
@@ -248,10 +231,8 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
             if ( rca0.getFailoverIndex() > 0 )
             {
                 primaryRestoredSuccessfully = restorePrimary();
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Primary recovery success state = " + primaryRestoredSuccessfully );
-                }
+                log.debug( "Primary recovery success state = {0}",
+                        primaryRestoredSuccessfully );
             }
 
             if ( !primaryRestoredSuccessfully )
@@ -260,8 +241,9 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                 // attempt.
                 try
                 {
-                    log.warn( "Failed to reconnect to primary server. Cache failover runner is going to sleep for "
-                        + idlePeriod + " milliseconds." );
+                    log.warn( "Failed to reconnect to primary server. "
+                            + "Cache failover runner is going to sleep for "
+                            + "{0} milliseconds.", idlePeriod );
                     Thread.sleep( idlePeriod );
                 }
                 catch ( InterruptedException ex )
@@ -292,10 +274,8 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
         // try to move back to the primary
         RemoteLocation server = rca0.getFailovers().get(0);
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Trying to restore connection to primary remote server [" + server + "]" );
-        }
+        log.info( "Trying to restore connection to primary remote server "
+                + "[{0}]", server );
 
         RemoteCacheAttributes rca = (RemoteCacheAttributes) rca0.clone();
         rca.setRemoteLocation(server);
@@ -329,11 +309,8 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                         {
                             RemoteLocation serverOld = rca0.getFailovers().get(fidx);
 
-                            if ( log.isDebugEnabled() )
-                            {
-                                log.debug( "Failover Index = " + fidx + " the server at that index is ["
-                                    + serverOld + "]" );
-                            }
+                            log.debug( "Failover Index = {0} the server at that "
+                                    + "index is [{1}]", fidx, serverOld );
 
                             if ( serverOld != null )
                             {
@@ -349,11 +326,8 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                                     // necessary
                                     rcmOld.removeRemoteCacheListener( rcaOld );
                                 }
-                                if ( log.isInfoEnabled() )
-                                {
-                                    log.info( "Successfully deregistered from FAILOVER remote server = "
-                                        + serverOld );
-                                }
+                                log.info( "Successfully deregistered from "
+                                        + "FAILOVER remote server = {0}", serverOld );
                             }
                         }
                         else if ( fidx == 0 )
@@ -376,8 +350,9 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                 catch ( IOException e )
                 {
                     // TODO, should try again, or somehow stop the listener
-                    log.error("Trouble trying to deregister old failover listener prior to restoring the primary = "
-                           + server, e );
+                    log.error("Trouble trying to deregister old failover "
+                            + "listener prior to restoring the primary = {0}",
+                            server, e );
                 }
 
                 // Restore primary
@@ -388,16 +363,16 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
                 facade.restorePrimaryServer((RemoteCacheNoWait<K, V>) ic);
                 rca0.setFailoverIndex( 0 );
 
-                if ( log.isInfoEnabled() )
-                {
-                    String message = "Successfully reconnected to PRIMARY remote server.  Substituted primary for failoverNoWait ["
-                        + failoverNoWait + "]";
-                    log.info( message );
+                String message = "Successfully reconnected to PRIMARY "
+                        + "remote server. Substituted primary for "
+                        + "failoverNoWait [" + failoverNoWait + "]";
+                log.info( message );
 
-                    if ( facade.getCacheEventLogger() != null )
-                    {
-                        facade.getCacheEventLogger().logApplicationEvent( "RemoteCacheFailoverRunner", "RestoredPrimary", message );
-                    }
+                if ( facade.getCacheEventLogger() != null )
+                {
+                    facade.getCacheEventLogger().logApplicationEvent(
+                            "RemoteCacheFailoverRunner", "RestoredPrimary",
+                            message );
                 }
                 return true;
             }
@@ -407,10 +382,7 @@ public class RemoteCacheFailoverRunner<K, V> extends AbstractAuxiliaryCacheMonit
         // if the failover index was at 0 here, we would be in a bad
         // situation, unless there were just
         // no failovers configured.
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Primary server status in error, not connected." );
-        }
+        log.debug( "Primary server status in error, not connected." );
 
         return false;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheListener.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheListener.java
index 2d5aa2f..29942fe 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheListener.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheListener.java
@@ -27,8 +27,8 @@ import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheAttributes;
 import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheConstants;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Registered with RemoteCache server. The server updates the local caches via this listener. Each
@@ -42,7 +42,7 @@ public class RemoteCacheListener<K, V>
     implements IRemoteCacheConstants
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( RemoteCacheListener.class );
+    private static final Log log = LogManager.getLog( RemoteCacheListener.class );
 
     /** Has this client been shutdown. */
     private boolean disposed = false;
@@ -85,10 +85,7 @@ public class RemoteCacheListener<K, V>
     {
         if ( !disposed )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Unexporting listener." );
-            }
+            log.info( "Unexporting listener." );
             try
             {
                 UnicastRemoteObject.unexportObject( this, true );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheManager.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheManager.java
index d3960c4..ac40eef 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheManager.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheManager.java
@@ -36,8 +36,8 @@ import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * An instance of RemoteCacheManager corresponds to one remote connection of a specific host and
@@ -50,7 +50,7 @@ import org.apache.commons.logging.LogFactory;
 public class RemoteCacheManager
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( RemoteCacheManager.class );
+    private static final Log log = LogManager.getLog( RemoteCacheManager.class );
 
     /** Contains instances of RemoteCacheNoWait managed by a RemoteCacheManager instance. */
     private final ConcurrentMap<String, RemoteCacheNoWait<?, ?>> caches =
@@ -126,24 +126,15 @@ public class RemoteCacheManager
      */
     protected void lookupRemoteService() throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Looking up server [" + registry + "]" );
-        }
+        log.info( "Looking up server [{0}]", registry );
         try
         {
             Object obj = Naming.lookup( registry );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Server found: " + obj );
-            }
+            log.info( "Server found: {0}", obj );
 
             // Successful connection to the remote server.
             this.remoteService = (ICacheServiceNonLocal<?, ?>) obj;
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Remote Service = " + remoteService );
-            }
+            log.debug( "Remote Service = {0}", remoteService );
             remoteWatch.setCacheWatch( (ICacheObserver) remoteService );
         }
         catch ( Exception ex )
@@ -169,22 +160,16 @@ public class RemoteCacheManager
     {
         if ( cattr.isReceive() )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "The remote cache is configured to receive events from the remote server.  "
-                    + "We will register a listener. remoteWatch = " + remoteWatch + " | IRemoteCacheListener = "
-                    + listener + " | cacheName " + cattr.getCacheName() );
-            }
+            log.info( "The remote cache is configured to receive events from the remote server. "
+                + "We will register a listener. remoteWatch = {0} | IRemoteCacheListener = {1}"
+                + " | cacheName ", remoteWatch, listener, cattr.getCacheName() );
 
             remoteWatch.addCacheListener( cattr.getCacheName(), listener );
         }
         else
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "The remote cache is configured to NOT receive events from the remote server.  "
+            log.info( "The remote cache is configured to NOT receive events from the remote server. "
                     + "We will NOT register a listener." );
-            }
         }
     }
 
@@ -211,7 +196,7 @@ public class RemoteCacheManager
             {
                 log.warn( "Trying to deregister Cache Listener that was never registered." );
             }
-            else if ( log.isDebugEnabled() )
+            else
             {
                 log.debug( "Since the remote cache is configured to not receive, "
                     + "there is no listener to deregister." );
@@ -223,10 +208,8 @@ public class RemoteCacheManager
 	private void removeListenerFromCache(RemoteCacheNoWait<?, ?> cache) throws IOException
 	{
 		IRemoteCacheClient<?, ?> rc = cache.getRemoteCache();
-		if ( log.isDebugEnabled() )
-		{
-		    log.debug( "Found cache for [" + cache.getCacheName() + "], deregistering listener." );
-		}
+	    log.debug( "Found cache for [{0}], deregistering listener.",
+	            () -> cache.getCacheName() );
 		// could also store the listener for a server in the manager.
 		IRemoteCacheListener<?, ?> listener = rc.getListener();
         remoteWatch.removeCacheListener( cache.getCacheName(), listener );
@@ -271,15 +254,10 @@ public class RemoteCacheManager
             listener = new RemoteCacheListener<>( cattr, cacheMgr, elementSerializer );
             addRemoteCacheListener( cattr, listener );
         }
-        catch ( IOException ioe )
-        {
-            log.error( "Problem adding listener. Message: " + ioe.getMessage()
-                + " | RemoteCacheListener = " + listener, ioe );
-        }
         catch ( Exception e )
         {
-            log.error( "Problem adding listener. Message: " + e.getMessage() + " | RemoteCacheListener = "
-                + listener, e );
+            log.error( "Problem adding listener. RemoteCacheListener = {0}",
+                    listener, e );
         }
 
         IRemoteCacheClient<K, V> remoteCacheClient =
@@ -301,17 +279,14 @@ public class RemoteCacheManager
         {
             try
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "freeCache [" + c.getCacheName() + "]" );
-                }
+                log.info( "freeCache [{0}]", () -> c.getCacheName() );
 
                 removeListenerFromCache(c);
                 c.dispose();
             }
             catch ( IOException ex )
             {
-                log.error( "Problem releasing " + c.getCacheName(), ex );
+                log.error( "Problem releasing {0}", c.getCacheName(), ex );
             }
         }
 
@@ -328,10 +303,8 @@ public class RemoteCacheManager
             return;
         }
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Fixing caches. ICacheServiceNonLocal " + remoteService + " | IRemoteCacheObserver " + remoteWatch );
-        }
+        log.info( "Fixing caches. ICacheServiceNonLocal {0} | IRemoteCacheObserver {1}",
+                remoteService, remoteWatch );
 
         for (RemoteCacheNoWait<?, ?> c : caches.values())
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWait.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWait.java
index 1721ded..8e13786 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWait.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWait.java
@@ -40,8 +40,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * The RemoteCacheNoWait wraps the RemoteCacheClient. The client holds a handle on the
@@ -67,7 +67,7 @@ public class RemoteCacheNoWait<K, V>
     extends AbstractAuxiliaryCache<K, V>
 {
     /** log instance */
-    private static final Log log = LogFactory.getLog( RemoteCacheNoWait.class );
+    private static final Log log = LogManager.getLog( RemoteCacheNoWait.class );
 
     /** The remote cache client */
     private final IRemoteCacheClient<K, V> remoteCacheClient;
@@ -164,10 +164,7 @@ public class RemoteCacheNoWait<K, V>
         }
         catch ( UnmarshalException ue )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Retrying the get owing to UnmarshalException." );
-            }
+            log.debug( "Retrying the get owing to UnmarshalException." );
 
             try
             {
@@ -175,10 +172,7 @@ public class RemoteCacheNoWait<K, V>
             }
             catch ( IOException ex )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Failed in retrying the get for the second time. " + ex.getMessage() );
-                }
+                log.info( "Failed in retrying the get for the second time. ", ex );
             }
         }
         catch ( IOException ex )
@@ -209,10 +203,7 @@ public class RemoteCacheNoWait<K, V>
         }
         catch ( UnmarshalException ue )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Retrying the getMatching owing to UnmarshalException." );
-            }
+            log.debug( "Retrying the getMatching owing to UnmarshalException." );
 
             try
             {
@@ -220,10 +211,7 @@ public class RemoteCacheNoWait<K, V>
             }
             catch ( IOException ex )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Failed in retrying the getMatching for the second time. " + ex.getMessage() );
-                }
+                log.info( "Failed in retrying the getMatching for the second time.", ex );
             }
         }
         catch ( IOException ex )
@@ -257,10 +245,7 @@ public class RemoteCacheNoWait<K, V>
         }
         catch ( UnmarshalException ue )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Retrying the getMultiple owing to UnmarshalException..." );
-            }
+            log.debug( "Retrying the getMultiple owing to UnmarshalException..." );
 
             try
             {
@@ -268,10 +253,7 @@ public class RemoteCacheNoWait<K, V>
             }
             catch ( IOException ex )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Failed in retrying the getMultiple for the second time. " + ex.getMessage() );
-                }
+                log.info( "Failed in retrying the getMultiple for the second time.", ex );
             }
         }
         catch ( IOException ex )
@@ -430,10 +412,8 @@ public class RemoteCacheNoWait<K, V>
         if ( previousQueue.isWorking() )
         {
             // we don't expect anything, it would have all gone to the zombie
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "resetEventQ, previous queue has [" + previousQueue.size() + "] items queued up." );
-            }
+            log.info( "resetEventQ, previous queue has [{0}] items queued up.",
+                    () -> previousQueue.size() );
             previousQueue.destroy();
         }
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java
index 5b7fa04..bdd7aa8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteCacheNoWaitFacade.java
@@ -26,8 +26,8 @@ import org.apache.commons.jcs.auxiliary.remote.server.behavior.RemoteType;
 import org.apache.commons.jcs.engine.CacheStatus;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Used to provide access to multiple services under nowait protection. Factory should construct
@@ -41,7 +41,7 @@ public class RemoteCacheNoWaitFacade<K, V>
     extends AbstractRemoteCacheNoWaitFacade<K, V>
 {
     /** log instance */
-    private static final Log log = LogFactory.getLog( RemoteCacheNoWaitFacade.class );
+    private static final Log log = LogManager.getLog( RemoteCacheNoWaitFacade.class );
 
     /** Provide factory instance to RemoteCacheFailoverRunner */
     private final RemoteCacheFactory cacheFactory;
@@ -73,10 +73,7 @@ public class RemoteCacheNoWaitFacade<K, V>
     @Override
     protected void failover( RemoteCacheNoWait<K, V> rcnw )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "in failover for " + rcnw );
-        }
+        log.debug( "in failover for {0}", rcnw );
 
         if ( getAuxiliaryCacheAttributes().getRemoteType() == RemoteType.LOCAL )
         {
@@ -96,10 +93,7 @@ public class RemoteCacheNoWaitFacade<K, V>
             }
             else
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "The noWait is not in error" );
-                }
+                log.info( "The noWait is not in error" );
             }
         }
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteLocation.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteLocation.java
index 813aecf..0ff1472 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteLocation.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteLocation.java
@@ -3,8 +3,8 @@ package org.apache.commons.jcs.auxiliary.remote;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -31,7 +31,7 @@ import org.apache.commons.logging.LogFactory;
 public final class RemoteLocation
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( RemoteLocation.class );
+    private static final Log log = LogManager.getLog( RemoteLocation.class );
 
     /** Pattern for parsing server:port */
     private static final Pattern SERVER_COLON_PORT = Pattern.compile("(\\S+)\\s*:\\s*(\\d+)");
@@ -136,7 +136,7 @@ public final class RemoteLocation
         }
         else
         {
-            log.error("Invalid server descriptor: " + server);
+            log.error("Invalid server descriptor: {0}", server);
         }
 
         return null;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteUtils.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteUtils.java
index fef1ac9..b3075a6 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteUtils.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/RemoteUtils.java
@@ -31,11 +31,10 @@ import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.rmi.server.RMISocketFactory;
-import java.util.Enumeration;
 import java.util.Properties;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class provides some basic utilities for doing things such as starting
@@ -44,7 +43,7 @@ import org.apache.commons.logging.LogFactory;
 public class RemoteUtils
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog(RemoteUtils.class);
+    private static final Log log = LogManager.getLog(RemoteUtils.class);
 
     /** No instances please. */
     private RemoteUtils()
@@ -72,21 +71,20 @@ public class RemoteUtils
 
         if (port < 1024)
         {
-            if (log.isWarnEnabled())
-            {
-                log.warn("createRegistry> Port chosen was less than 1024, will use default [" + Registry.REGISTRY_PORT + "] instead.");
-            }
+            log.warn("createRegistry> Port chosen was less than 1024, will use default [{0}] instead.",
+                    Registry.REGISTRY_PORT);
             port = Registry.REGISTRY_PORT;
         }
 
         try
         {
             registry = LocateRegistry.createRegistry(port);
-            log.info("createRegistry> Created the registry on port " + port);
+            log.info("createRegistry> Created the registry on port {0}", port);
         }
         catch (RemoteException e)
         {
-            log.warn("createRegistry> Problem creating registry. It may already be started. " + e.getMessage());
+            log.warn("createRegistry> Problem creating registry. It may already be started.",
+                    e);
         }
         catch (Throwable t)
         {
@@ -130,7 +128,7 @@ public class RemoteUtils
                 is = RemoteUtils.class.getResourceAsStream("/" + propFile);
             }
         }
-        
+
         if (null == is) // not found in class path
         {
             if (new File(propFile).exists())
@@ -149,27 +147,21 @@ public class RemoteUtils
         try
         {
             props.load(is);
-            if (log.isDebugEnabled())
-            {
-                log.debug("props.size=" + props.size());
-            }
+            log.debug("props.size={0}", () -> props.size());
 
-            if (log.isDebugEnabled())
+            if (log.isTraceEnabled())
             {
-                Enumeration<Object> en = props.keys();
                 StringBuilder buf = new StringBuilder();
-                while (en.hasMoreElements())
-                {
-                    String key = (String) en.nextElement();
-                    buf.append("\n" + key + " = " + props.getProperty(key));
-                }
-                log.debug(buf.toString());
+                props.forEach((key, value)
+                        -> buf.append('\n').append(key).append(" = ").append(value));
+                log.trace(buf.toString());
             }
 
         }
-        catch (Exception ex)
+        catch (IOException ex)
         {
-            log.error("Error loading remote properties, for file name [" + propFile + "]", ex);
+            log.error("Error loading remote properties, for file name "
+                    + "[{0}]", propFile, ex);
         }
         finally
         {
@@ -196,11 +188,8 @@ public class RemoteUtils
             // Don't set a socket factory if the setting is -1
             if (timeoutMillis > 0)
             {
-                if (log.isInfoEnabled())
-                {
-                    log.info("RmiSocketFactoryTimeoutMillis [" + timeoutMillis + "]. "
-                            + " Configuring a custom socket factory.");
-                }
+                log.info("RmiSocketFactoryTimeoutMillis [{0}]. "
+                    + " Configuring a custom socket factory.", timeoutMillis);
 
                 // use this socket factory to add a timeout.
                 RMISocketFactory.setSocketFactory(new RMISocketFactory()
@@ -232,8 +221,8 @@ public class RemoteUtils
             RMISocketFactory factoryInUse = RMISocketFactory.getSocketFactory();
             if (factoryInUse != null && !factoryInUse.getClass().getName().startsWith("org.apache.commons.jcs"))
             {
-                log.info("Could not create new custom socket factory. " + e.getMessage() + " Factory in use = "
-                        + RMISocketFactory.getSocketFactory());
+                log.info("Could not create new custom socket factory. {0} Factory in use = {1}",
+                        () -> e.getMessage(), () -> RMISocketFactory.getSocketFactory());
             }
         }
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/AbstractHttpClient.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/AbstractHttpClient.java
index 9862887..5b86fe1 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/AbstractHttpClient.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/AbstractHttpClient.java
@@ -21,8 +21,8 @@ package org.apache.commons.jcs.auxiliary.remote.http.client;
 
 import java.io.IOException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
 import org.apache.http.client.HttpClient;
@@ -49,7 +49,7 @@ public abstract class AbstractHttpClient
     private RemoteHttpCacheAttributes remoteHttpCacheAttributes;
 
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( AbstractHttpClient.class );
+    private static final Log log = LogManager.getLog( AbstractHttpClient.class );
 
     /**
      * Sets the default Properties File and Heading, and creates the HttpClient and connection
@@ -72,7 +72,8 @@ public abstract class AbstractHttpClient
         }
         else
         {
-            log.warn( "Unrecognized value for 'httpVersion': [" + httpVersion + "], defaulting to 1.1" );
+            log.warn( "Unrecognized value for 'httpVersion': [{0}], defaulting to 1.1",
+                    httpVersion );
             this.httpVersion = HttpVersion.HTTP_1_1;
         }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCache.java
index 1622b8f..8f884f8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCache.java
@@ -25,8 +25,8 @@ import org.apache.commons.jcs.auxiliary.remote.AbstractRemoteAuxiliaryCache;
 import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheListener;
 import org.apache.commons.jcs.engine.ZombieCacheServiceNonLocal;
 import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This uses an http client as the service.
@@ -35,7 +35,7 @@ public class RemoteHttpCache<K, V>
     extends AbstractRemoteAuxiliaryCache<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( RemoteHttpCache.class );
+    private static final Log log = LogManager.getLog( RemoteHttpCache.class );
 
     /** for error notifications */
     private RemoteHttpCacheMonitor monitor;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheClient.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheClient.java
index 9a5c9b0..0f870d4 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheClient.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheClient.java
@@ -1,5 +1,11 @@
 package org.apache.commons.jcs.auxiliary.remote.http.client;
 
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -25,21 +31,15 @@ import org.apache.commons.jcs.auxiliary.remote.util.RemoteCacheRequestFactory;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheRequest;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheResponse;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /** This is the service used by the remote http auxiliary cache. */
 public class RemoteHttpCacheClient<K, V>
     implements IRemoteHttpCacheClient<K, V>
 {
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( RemoteHttpCacheClient.class );
+    private static final Log log = LogManager.getLog( RemoteHttpCacheClient.class );
 
     /** The internal client. */
     private IRemoteCacheDispatcher remoteDispatcher;
@@ -78,10 +78,7 @@ public class RemoteHttpCacheClient<K, V>
     {
         setRemoteDispatcher( new RemoteHttpCacheDispatcher( attributes ) );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Created remote Dispatcher." + getRemoteDispatcher() );
-        }
+        log.info( "Created remote Dispatcher. {0}", () -> getRemoteDispatcher() );
         setInitialized( true );
     }
 
@@ -115,7 +112,7 @@ public class RemoteHttpCacheClient<K, V>
     {
         if ( !isInitialized() )
         {
-            String message = "The Remote Http Client is not initialized.  Cannot process request.";
+            String message = "The Remote Http Client is not initialized. Cannot process request.";
             log.warn( message );
             throw new IOException( message );
         }
@@ -125,10 +122,7 @@ public class RemoteHttpCacheClient<K, V>
         RemoteCacheResponse<ICacheElement<K, V>> remoteHttpCacheResponse =
             getRemoteDispatcher().dispatchRequest( remoteHttpCacheRequest );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Get [" + key + "] = " + remoteHttpCacheResponse );
-        }
+        log.debug( "Get [{0}] = {1}", key, remoteHttpCacheResponse );
 
         if ( remoteHttpCacheResponse != null)
         {
@@ -170,7 +164,7 @@ public class RemoteHttpCacheClient<K, V>
     {
         if ( !isInitialized() )
         {
-            String message = "The Remote Http Client is not initialized.  Cannot process request.";
+            String message = "The Remote Http Client is not initialized. Cannot process request.";
             log.warn( message );
             throw new IOException( message );
         }
@@ -181,10 +175,7 @@ public class RemoteHttpCacheClient<K, V>
         RemoteCacheResponse<Map<K, ICacheElement<K, V>>> remoteHttpCacheResponse =
             getRemoteDispatcher().dispatchRequest( remoteHttpCacheRequest );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "GetMatching [" + pattern + "] = " + remoteHttpCacheResponse );
-        }
+        log.debug( "GetMatching [{0}] = {1}", pattern, remoteHttpCacheResponse );
 
         return remoteHttpCacheResponse.getPayload();
     }
@@ -232,10 +223,7 @@ public class RemoteHttpCacheClient<K, V>
         RemoteCacheResponse<Map<K, ICacheElement<K, V>>> remoteHttpCacheResponse =
             getRemoteDispatcher().dispatchRequest( remoteHttpCacheRequest );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "GetMultiple [" + keys + "] = " + remoteHttpCacheResponse );
-        }
+        log.debug( "GetMultiple [{0}] = {1}", keys, remoteHttpCacheResponse );
 
         return remoteHttpCacheResponse.getPayload();
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
index 7b80ef9..b6c9faf 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheDispatcher.java
@@ -27,8 +27,8 @@ import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheDispatcher;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheRequest;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheResponse;
 import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.http.HttpException;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpUriRequest;
@@ -54,7 +54,7 @@ public class RemoteHttpCacheDispatcher
     private static final String PARAMETER_CACHE_NAME = "CacheName";
 
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( RemoteHttpCacheDispatcher.class );
+    private static final Log log = LogManager.getLog( RemoteHttpCacheDispatcher.class );
 
     /** This needs to be standard, since the other side is standard */
     private StandardSerializer serializer = new StandardSerializer();
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheFactory.java
index d8ad200..476d176 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/client/RemoteHttpCacheFactory.java
@@ -29,9 +29,9 @@ import org.apache.commons.jcs.auxiliary.remote.server.behavior.RemoteType;
 import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.behavior.IElementSerializer;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.OptionConverter;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * The RemoteCacheFactory creates remote caches for the cache hub. It returns a no wait facade which
@@ -43,7 +43,7 @@ public class RemoteHttpCacheFactory
     extends AbstractAuxiliaryCacheFactory
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( RemoteHttpCacheFactory.class );
+    private static final Log log = LogManager.getLog( RemoteHttpCacheFactory.class );
 
     /** Monitor thread instance */
     private RemoteHttpCacheMonitor monitor;
@@ -100,11 +100,9 @@ public class RemoteHttpCacheFactory
 
         if ( remoteService == null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Creating the default client for " + cattr.getCacheName());
-            }
-            remoteService = new RemoteHttpCacheClient<>( );
+            log.info( "Creating the default client for {0}",
+                    () -> cattr.getCacheName());
+            remoteService = new RemoteHttpCacheClient<>();
         }
 
         remoteService.initialize( cattr );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java
index 4541986..8a425f4 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/AbstractRemoteCacheService.java
@@ -31,8 +31,8 @@ import org.apache.commons.jcs.engine.control.CompositeCache;
 import org.apache.commons.jcs.engine.logging.CacheEvent;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEvent;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class contains common methods for remote cache services. Eventually I hope to extract out
@@ -57,7 +57,7 @@ public abstract class AbstractRemoteCacheService<K, V>
     private final int logInterval = 100;
 
     /** log instance */
-    private static final Log log = LogFactory.getLog( AbstractRemoteCacheService.class );
+    private static final Log log = LogManager.getLog( AbstractRemoteCacheService.class );
 
     /**
      * Creates the super with the needed items.
@@ -129,14 +129,12 @@ public abstract class AbstractRemoteCacheService<K, V>
             puts++;
             if ( puts % logInterval == 0 )
             {
-                log.info( "puts = " + puts );
+                log.info( "puts = {0}", puts );
             }
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "In update, put [" + item.getKey() + "] in [" + item.getCacheName() + "]" );
-        }
+        log.debug( "In update, put [{0}] in [{1}]", () -> item.getKey(),
+                () -> item.getCacheName() );
     }
 
     /**
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java
index 10f8e1d..50373f1 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/http/server/RemoteHttpCacheServlet.java
@@ -46,10 +46,10 @@ import org.apache.commons.jcs.engine.behavior.ICompositeCacheManager;
 import org.apache.commons.jcs.engine.control.CompositeCacheManager;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
 import org.apache.commons.jcs.io.ObjectInputStreamClassLoaderAware;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.PropertySetter;
 import org.apache.commons.jcs.utils.serialization.StandardSerializer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This servlet simply reads and writes objects. The requests are packaged in a general wrapper. The
@@ -62,7 +62,7 @@ public class RemoteHttpCacheServlet
     private static final long serialVersionUID = 8752849397531933346L;
 
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( RemoteHttpCacheServlet.class );
+    private static final Log log = LogManager.getLog( RemoteHttpCacheServlet.class );
 
     /** The cache manager */
     private static CompositeCacheManager cacheMgr;
@@ -118,10 +118,7 @@ public class RemoteHttpCacheServlet
         throws ServletException, IOException
     {
         incrementServiceCallCount();
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Servicing a request. " + request );
-        }
+        log.debug( "Servicing a request. {0}", request );
 
         RemoteCacheRequest<Serializable, Serializable> remoteRequest = readRequest( request );
         RemoteCacheResponse<Object> cacheResponse = processRequest( remoteRequest );
@@ -141,10 +138,7 @@ public class RemoteHttpCacheServlet
         try
         {
             InputStream inputStream = request.getInputStream();
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "After getting input stream and before reading it" );
-            }
+            log.debug( "After getting input stream and before reading it" );
 
             remoteRequest = readRequestFromStream( inputStream );
         }
@@ -191,10 +185,8 @@ public class RemoteHttpCacheServlet
             response.setContentLength( responseAsByteAray.length );
 
             OutputStream outputStream = response.getOutputStream();
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Opened output stream.  Response size: " + responseAsByteAray.length );
-            }
+            log.debug( "Opened output stream.  Response size: {0}",
+                    () -> responseAsByteAray.length );
             // WRITE
             outputStream.write( responseAsByteAray );
             outputStream.flush();
@@ -202,7 +194,7 @@ public class RemoteHttpCacheServlet
         }
         catch ( IOException e )
         {
-            log.error( "Problem writing response. " + cacheResponse, e );
+            log.error( "Problem writing response. {0}", cacheResponse, e );
         }
     }
 
@@ -305,10 +297,7 @@ public class RemoteHttpCacheServlet
         RemoteHttpCacheServerAttributes attributes = configureRemoteHttpCacheServerAttributes( props );
 
         RemoteHttpCacheService<K, V> service = new RemoteHttpCacheService<>( cacheManager, attributes, cacheEventLogger );
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Created new RemoteHttpCacheService " + service );
-        }
+        log.info( "Created new RemoteHttpCacheService {0}", service );
         return service;
     }
 
@@ -364,7 +353,7 @@ public class RemoteHttpCacheServlet
         {
             if ( serviceCalls % logInterval == 0 )
             {
-                log.info( "serviceCalls = " + serviceCalls );
+                log.info( "serviceCalls = {0}", serviceCalls );
             }
         }
     }
@@ -373,10 +362,7 @@ public class RemoteHttpCacheServlet
     @Override
     public void destroy()
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Servlet Destroyed, shutting down JCS." );
-        }
+        log.info( "Servlet Destroyed, shutting down JCS." );
 
         cacheMgr.shutDown();
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RegistryKeepAliveRunner.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RegistryKeepAliveRunner.java
index 3b8beed..b09c3ab 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RegistryKeepAliveRunner.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RegistryKeepAliveRunner.java
@@ -26,8 +26,8 @@ import java.rmi.registry.Registry;
 
 import org.apache.commons.jcs.auxiliary.remote.RemoteUtils;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class tries to keep the registry alive. If if is able to create a registry, it will also
@@ -37,7 +37,7 @@ public class RegistryKeepAliveRunner
     implements Runnable
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( RegistryKeepAliveRunner.class );
+    private static final Log log = LogManager.getLog( RegistryKeepAliveRunner.class );
 
     /** The URL of the service to look for. */
     private String namingURL;
@@ -83,10 +83,8 @@ public class RegistryKeepAliveRunner
      */
     protected void checkAndRestoreIfNeeded()
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "looking up server " + namingURL );
-        }
+        log.debug( "looking up server {0}", namingURL );
+
         try
         {
             Object obj = Naming.lookup( namingURL );
@@ -97,10 +95,7 @@ public class RegistryKeepAliveRunner
             {
                 cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "Naming.lookup", message );
             }
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( message );
-            }
+            log.debug( message );
         }
         catch ( Exception ex )
         {
@@ -175,10 +170,7 @@ public class RegistryKeepAliveRunner
             {
                 cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "registerServer", message );
             }
-            if ( log.isInfoEnabled() )
-            {
-                log.info( message );
-            }
+            log.info( message );
         }
         catch ( RemoteException e )
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
index 829b4e2..e391786 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServer.java
@@ -48,8 +48,8 @@ import org.apache.commons.jcs.engine.control.CompositeCacheManager;
 import org.apache.commons.jcs.engine.logging.CacheEvent;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEvent;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class provides remote cache services. The remote cache server propagates events from local
@@ -76,7 +76,7 @@ public class RemoteCacheServer<K, V>
     private static final long serialVersionUID = -8072345435941473116L;
 
     /** log instance */
-    private static final Log log = LogFactory.getLog( RemoteCacheServer.class );
+    private static final Log log = LogManager.getLog( RemoteCacheServer.class );
 
     /** timing -- if we should record operation times. */
     private static final boolean timing = true;
@@ -279,10 +279,7 @@ public class RemoteCacheServer<K, V>
 
             boolean fromCluster = isRequestFromCluster( requesterId );
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "In update, requesterId = [" + requesterId + "] fromCluster = " + fromCluster );
-            }
+            log.debug( "In update, requesterId = [{0}] fromCluster = {1}", requesterId, fromCluster );
 
             // ordered cache item update and notification.
             synchronized ( cacheDesc )
@@ -307,31 +304,22 @@ public class RemoteCacheServer<K, V>
                     // RemoteCache.
                     if ( fromCluster )
                     {
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "Put FROM cluster, NOT updating other auxiliaries for region. "
-                                + " requesterId [" + requesterId + "]" );
-                        }
+                        log.debug( "Put FROM cluster, NOT updating other auxiliaries for region. "
+                                + " requesterId [{0}]", requesterId );
                         c.localUpdate( item );
                     }
                     else
                     {
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "Put NOT from cluster, updating other auxiliaries for region. "
-                                + " requesterId [" + requesterId + "]" );
-                        }
+                        log.debug( "Put NOT from cluster, updating other auxiliaries for region. "
+                                + " requesterId [{0}]", requesterId );
                         c.update( item );
                     }
                 }
                 catch ( Exception ce )
                 {
                     // swallow
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( "Exception caught updating item. requesterId [" + requesterId + "] "
-                            + ce.getMessage() );
-                    }
+                    log.info( "Exception caught updating item. requesterId [{0}]: {1}",
+                            requesterId, ce.getMessage() );
                 }
 
                 // UPDATE LOCALS IF A REQUEST COMES FROM A CLUSTER
@@ -339,10 +327,7 @@ public class RemoteCacheServer<K, V>
                 if ( !fromCluster || ( fromCluster && remoteCacheServerAttributes.isLocalClusterConsistency() ) )
                 {
                     ICacheEventQueue<K, V>[] qlist = getEventQList( cacheDesc, requesterId );
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "qlist.length = " + qlist.length );
-                    }
+                    log.debug( "qlist.length = {0}", qlist.length );
                     for ( int i = 0; i < qlist.length; i++ )
                     {
                         qlist[i].addPutEvent( item );
@@ -358,17 +343,14 @@ public class RemoteCacheServer<K, V>
                     + " REGION: " + item.getCacheName() + " ITEM: " + item );
             }
 
-            log.error( "Trouble in Update. requesterId [" + requesterId + "]", e );
+            log.error( "Trouble in Update. requesterId [{0}]", requesterId, e );
         }
 
         // TODO use JAMON for timing
         if ( timing )
         {
             long end = System.currentTimeMillis();
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "put took " + String.valueOf( end - start ) + " ms." );
-            }
+            log.debug( "put took {0} ms.", end - start);
         }
     }
 
@@ -386,14 +368,12 @@ public class RemoteCacheServer<K, V>
         {
             if ( puts % logInterval == 0 )
             {
-                log.info( "puts = " + puts );
+                log.info( "puts = {0}", puts );
             }
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "In update, put [" + item.getKey() + "] in [" + item.getCacheName() + "]" );
-        }
+        log.debug( "In update, put [{0}] in [{1}]",
+                () -> item.getKey(), () -> item.getCacheName() );
     }
 
     /**
@@ -456,27 +436,10 @@ public class RemoteCacheServer<K, V>
     {
         boolean fromCluster = isRequestFromCluster( requesterId );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "get [" + key + "] from cache [" + cacheName + "] requesterId = [" + requesterId
-                + "] fromCluster = " + fromCluster );
-        }
+        log.debug( "get [{0}] from cache [{1}] requesterId = [{2}] fromCluster = {3}",
+                key, cacheName, requesterId, fromCluster );
 
-        CacheListeners<K, V> cacheDesc = null;
-        try
-        {
-            cacheDesc = getCacheListeners( cacheName );
-        }
-        catch ( Exception e )
-        {
-            log.error( "Problem getting listeners.", e );
-
-            if ( cacheEventLogger != null )
-            {
-                cacheEventLogger.logError( "RemoteCacheServer", ICacheEventLogger.GET_EVENT, e.getMessage() + cacheName
-                    + " KEY: " + key );
-            }
-        }
+        CacheListeners<K, V> cacheDesc = getCacheListeners( cacheName );
 
         ICacheElement<K, V> element = getFromCacheListeners( key, fromCluster, cacheDesc, null );
         return element;
@@ -516,11 +479,8 @@ public class RemoteCacheServer<K, V>
 
             if ( !fromCluster && this.remoteCacheServerAttributes.isAllowClusterGet() )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "NonLocalGet. fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "NonLocalGet. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
                 returnElement = c.get( key );
             }
             else
@@ -528,12 +488,8 @@ public class RemoteCacheServer<K, V>
                 // Gets from cluster type remote will end up here.
                 // Gets from all clients will end up here if allow cluster get is
                 // false.
-
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "LocalGet.  fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "LocalGet. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
                 returnElement = c.localGet( key );
             }
         }
@@ -593,11 +549,8 @@ public class RemoteCacheServer<K, V>
     {
         boolean fromCluster = isRequestFromCluster( requesterId );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "getMatching [" + pattern + "] from cache [" + cacheName + "] requesterId = [" + requesterId
-                + "] fromCluster = " + fromCluster );
-        }
+        log.debug( "getMatching [{0}] from cache [{1}] requesterId = [{2}] fromCluster = {3}",
+                pattern, cacheName, requesterId, fromCluster );
 
         CacheListeners<K, V> cacheDesc = null;
         try
@@ -639,11 +592,8 @@ public class RemoteCacheServer<K, V>
 
             if ( !fromCluster && this.remoteCacheServerAttributes.isAllowClusterGet() )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "NonLocalGetMatching. fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "NonLocalGetMatching. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
                 elements = c.getMatching( pattern );
             }
             else
@@ -652,11 +602,8 @@ public class RemoteCacheServer<K, V>
                 // Gets from all clients will end up here if allow cluster get is
                 // false.
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "LocalGetMatching.  fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "LocalGetMatching. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
                 elements = c.localGetMatching( pattern );
             }
         }
@@ -720,11 +667,8 @@ public class RemoteCacheServer<K, V>
     {
         boolean fromCluster = isRequestFromCluster( requesterId );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "getMultiple [" + keys + "] from cache [" + cacheName + "] requesterId = [" + requesterId
-                + "] fromCluster = " + fromCluster );
-        }
+        log.debug( "getMultiple [{0}] from cache [{1}] requesterId = [{2}] fromCluster = {3}",
+                keys, cacheName, requesterId, fromCluster );
 
         CacheListeners<K, V> cacheDesc = getCacheListeners( cacheName );
         Map<K, ICacheElement<K, V>> elements = getMultipleFromCacheListeners( keys, null, fromCluster, cacheDesc );
@@ -778,11 +722,8 @@ public class RemoteCacheServer<K, V>
 
             if ( !fromCluster && this.remoteCacheServerAttributes.isAllowClusterGet() )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "NonLocalGetMultiple. fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "NonLocalGetMultiple. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
 
                 returnElements = c.getMultiple( keys );
             }
@@ -792,11 +733,8 @@ public class RemoteCacheServer<K, V>
                 // Gets from all clients will end up here if allow cluster get is
                 // false.
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "LocalGetMultiple.  fromCluster [" + fromCluster + "] AllowClusterGet ["
-                        + this.remoteCacheServerAttributes.isAllowClusterGet() + "]" );
-                }
+                log.debug( "LocalGetMultiple. fromCluster [{0}] AllowClusterGet [{1}]",
+                        fromCluster, this.remoteCacheServerAttributes.isAllowClusterGet() );
 
                 returnElements = c.localGetMultiple( keys );
             }
@@ -825,15 +763,7 @@ public class RemoteCacheServer<K, V>
      */
     protected Set<K> processGetKeySet( String cacheName )
     {
-        CacheListeners<K, V> cacheDesc = null;
-        try
-        {
-            cacheDesc = getCacheListeners( cacheName );
-        }
-        catch ( Exception e )
-        {
-            log.error( "Problem getting listeners.", e );
-        }
+        CacheListeners<K, V> cacheDesc = getCacheListeners( cacheName );
 
         if ( cacheDesc == null )
         {
@@ -894,10 +824,7 @@ public class RemoteCacheServer<K, V>
     private void processRemove( String cacheName, K key, long requesterId )
         throws IOException
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "remove [" + key + "] from cache [" + cacheName + "]" );
-        }
+        log.debug( "remove [{0}] from cache [{1}]", key, cacheName );
 
         CacheListeners<K, V> cacheDesc = cacheListenersMap.get( cacheName );
 
@@ -916,26 +843,17 @@ public class RemoteCacheServer<K, V>
 
                 if ( fromCluster )
                 {
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Remove FROM cluster, NOT updating other auxiliaries for region" );
-                    }
+                    log.debug( "Remove FROM cluster, NOT updating other auxiliaries for region" );
                     removeSuccess = c.localRemove( key );
                 }
                 else
                 {
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "Remove NOT from cluster, updating other auxiliaries for region" );
-                    }
+                    log.debug( "Remove NOT from cluster, updating other auxiliaries for region" );
                     removeSuccess = c.remove( key );
                 }
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "remove [" + key + "] from cache [" + cacheName + "] success (was it found) = "
-                        + removeSuccess );
-                }
+                log.debug( "remove [{0}] from cache [{1}] success (was it found) = {2}",
+                        key, cacheName, removeSuccess );
 
                 // UPDATE LOCALS IF A REQUEST COMES FROM A CLUSTER
                 // IF LOCAL CLUSTER CONSISTENCY IS CONFIGURED
@@ -1014,18 +932,12 @@ public class RemoteCacheServer<K, V>
 
                 if ( fromCluster )
                 {
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "RemoveALL FROM cluster, NOT updating other auxiliaries for region" );
-                    }
+                    log.debug( "RemoveALL FROM cluster, NOT updating other auxiliaries for region" );
                     c.localRemoveAll();
                 }
                 else
                 {
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "RemoveALL NOT from cluster, updating other auxiliaries for region" );
-                    }
+                    log.debug( "RemoveALL NOT from cluster, updating other auxiliaries for region" );
                     c.removeAll();
                 }
 
@@ -1096,10 +1008,7 @@ public class RemoteCacheServer<K, V>
     private void processDispose( String cacheName, long requesterId )
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Dispose request received from listener [" + requesterId + "]" );
-        }
+        log.info( "Dispose request received from listener [{0}]", requesterId );
 
         CacheListeners<K, V> cacheDesc = cacheListenersMap.get( cacheName );
 
@@ -1270,12 +1179,12 @@ public class RemoteCacheServer<K, V>
         RemoteType remoteType = ircl.getRemoteType();
         if ( remoteType == RemoteType.CLUSTER )
         {
-            log.debug( "adding cluster listener, listenerAddress [" + listenerAddress + "]" );
+            log.debug( "adding cluster listener, listenerAddress [{0}]", listenerAddress );
             cacheListeners = (CacheListeners<KK, VV>)getClusterListeners( cacheName );
         }
         else
         {
-            log.debug( "adding normal listener, listenerAddress [" + listenerAddress + "]" );
+            log.debug( "adding normal listener, listenerAddress [{0}]", listenerAddress );
             cacheListeners = (CacheListeners<KK, VV>)getCacheListeners( cacheName );
         }
         Map<Long, ICacheEventQueue<KK, VV>> eventQMap = cacheListeners.eventQMap;
@@ -1293,11 +1202,8 @@ public class RemoteCacheServer<K, V>
                 {
                     // must start at one so the next gets recognized
                     long listenerIdB = nextListenerId();
-                    if ( log.isDebugEnabled() )
-                    {
-                        log.debug( "listener id=" + ( listenerIdB & 0xff ) + " addded for cache [" + cacheName
-                            + "], listenerAddress [" + listenerAddress + "]" );
-                    }
+                    log.debug( "listener id={0} addded for cache [{1}], listenerAddress [{2}]",
+                            listenerIdB & 0xff, cacheName, listenerAddress );
                     listener.setListenerId( listenerIdB );
                     id = listenerIdB;
 
@@ -1305,20 +1211,14 @@ public class RemoteCacheServer<K, V>
                     String message = "Adding vm listener under new id = [" + listenerIdB + "], listenerAddress ["
                         + listenerAddress + "]";
                     logApplicationEvent( "RemoteCacheServer", "addCacheListener", message );
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( message );
-                    }
+                    log.info( message );
                 }
                 else
                 {
                     String message = "Adding listener under existing id = [" + id + "], listenerAddress ["
                         + listenerAddress + "]";
                     logApplicationEvent( "RemoteCacheServer", "addCacheListener", message );
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( message );
-                    }
+                    log.info( message );
                     // should confirm the the host is the same as we have on
                     // record, just in case a client has made a mistake.
                 }
@@ -1348,10 +1248,7 @@ public class RemoteCacheServer<K, V>
 
             eventQMap.put(Long.valueOf(listener.getListenerId()), q);
 
-            if ( log.isInfoEnabled() )
-            {
-                log.info( cacheListeners );
-            }
+            log.info( cacheListeners );
         }
     }
 
@@ -1369,10 +1266,7 @@ public class RemoteCacheServer<K, V>
         {
             addCacheListener( cacheName, listener );
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Adding listener for cache [" + cacheName + "]" );
-            }
+            log.debug( "Adding listener for cache [{0}]", cacheName );
         }
     }
 
@@ -1402,10 +1296,7 @@ public class RemoteCacheServer<K, V>
     {
         String message = "Removing listener for cache region = [" + cacheName + "] and listenerId [" + listenerId + "]";
         logApplicationEvent( "RemoteCacheServer", "removeCacheListener", message );
-        if ( log.isInfoEnabled() )
-        {
-            log.info( message );
-        }
+        log.info( message );
 
         boolean isClusterListener = isRequestFromCluster( listenerId );
 
@@ -1425,31 +1316,23 @@ public class RemoteCacheServer<K, V>
 
         if ( q != null )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Found queue for cache region = [" + cacheName + "] and listenerId  [" + listenerId + "]" );
-            }
+            log.debug( "Found queue for cache region = [{0}] and listenerId [{1}]",
+                    cacheName, listenerId );
             q.destroy();
             cleanupEventQMap( eventQMap );
         }
         else
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Did not find queue for cache region = [" + cacheName + "] and listenerId [" + listenerId
-                    + "]" );
-            }
+            log.debug( "Did not find queue for cache region = [{0}] and listenerId [{1}]",
+                    cacheName, listenerId );
         }
 
         // cleanup
         idTypeMap.remove( Long.valueOf( listenerId ) );
         idIPMap.remove( Long.valueOf( listenerId ) );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "After removing listener [" + listenerId + "] cache region " + cacheName + "'s listener size ["
-                + cacheDesc.eventQMap.size() + "]" );
-        }
+        log.info( "After removing listener [{0}] cache region {1}'s listener size [{2}]",
+                listenerId, cacheName, cacheDesc.eventQMap.size() );
     }
 
     /**
@@ -1466,10 +1349,7 @@ public class RemoteCacheServer<K, V>
         {
             removeCacheListener( cacheName, listener );
 
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Removing listener for cache [" + cacheName + "]" );
-            }
+            log.info( "Removing listener for cache [{0}]", cacheName );
         }
     }
 
@@ -1497,10 +1377,7 @@ public class RemoteCacheServer<K, V>
     public void shutdown( String host, int port )
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Received shutdown request. Shutting down server." );
-        }
+        log.info( "Received shutdown request. Shutting down server." );
 
         synchronized (listenerId)
         {
@@ -1511,10 +1388,7 @@ public class RemoteCacheServer<K, V>
                     removeCacheListener( cacheName, i );
                 }
 
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Removing listener for cache [" + cacheName + "]" );
-                }
+                log.info( "Removing listener for cache [{0}]", cacheName );
             }
 
             cacheListenersMap.clear();
@@ -1532,10 +1406,7 @@ public class RemoteCacheServer<K, V>
     @Override
     public void unreferenced()
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "*** Server now unreferenced and subject to GC. ***" );
-        }
+        log.info( "*** Server now unreferenced and subject to GC. ***" );
     }
 
     /**
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java
index 63af6d9..1610ad5 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheServerFactory.java
@@ -38,11 +38,11 @@ import org.apache.commons.jcs.auxiliary.remote.RemoteUtils;
 import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheConstants;
 import org.apache.commons.jcs.engine.behavior.ICacheServiceAdmin;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.OptionConverter;
 import org.apache.commons.jcs.utils.config.PropertySetter;
 import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Provides remote cache services. This creates remote cache servers and can proxy command line
@@ -52,7 +52,7 @@ public class RemoteCacheServerFactory
     implements IRemoteCacheConstants
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( RemoteCacheServerFactory.class );
+    private static final Log log = LogManager.getLog( RemoteCacheServerFactory.class );
 
     /** The single instance of the RemoteCacheServer object. */
     private static RemoteCacheServer<?, ?> remoteCacheServer;
@@ -121,10 +121,7 @@ public class RemoteCacheServerFactory
 
             // These should come from the file!
             rcsa.setRemoteLocation( host, port );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Creating server with these attributes: " + rcsa );
-            }
+            log.info( "Creating server with these attributes: {0}", rcsa );
 
             setServiceName( rcsa.getRemoteServiceName() );
 
@@ -204,17 +201,12 @@ public class RemoteCacheServerFactory
         {
             PropertySetter.setProperties( customRMISocketFactory, props, CUSTOM_RMI_SOCKET_FACTORY_PROPERTY_PREFIX
                 + "." );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Will use server specific custom socket factory. " + customRMISocketFactory );
-            }
+            log.info( "Will use server specific custom socket factory. {0}",
+                    customRMISocketFactory );
         }
         else
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "No server specific custom socket factory defined." );
-            }
+            log.info( "No server specific custom socket factory defined." );
         }
         return customRMISocketFactory;
     }
@@ -240,10 +232,7 @@ public class RemoteCacheServerFactory
             throw new RemoteException( "Cannot register the server: Registry is null." );
         }
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Binding server to " + serviceName );
-        }
+        log.info( "Binding server to {0}", serviceName );
 
         registry.rebind( serviceName, server );
     }
@@ -284,12 +273,12 @@ public class RemoteCacheServerFactory
             {
                 int servicePort = Integer.parseInt( servicePortStr );
                 rcsa.setServicePort( servicePort );
-                log.debug( "Remote cache service uses port number " + servicePort + "." );
+                log.debug( "Remote cache service uses port number {0}", servicePort );
             }
             catch ( NumberFormatException ignore )
             {
-                log.debug( "Remote cache service port property " + REMOTE_CACHE_SERVICE_PORT
-                    + " not specified.  An anonymous port will be used." );
+                log.debug( "Remote cache service port property {0}" +
+                    " not specified. An anonymous port will be used.", REMOTE_CACHE_SERVICE_PORT );
             }
         }
 
@@ -300,12 +289,12 @@ public class RemoteCacheServerFactory
             {
                 int rmiSocketFactoryTimeoutMillis = Integer.parseInt( socketTimeoutMillisStr );
                 rcsa.setRmiSocketFactoryTimeoutMillis( rmiSocketFactoryTimeoutMillis );
-                log.debug( "Remote cache socket timeout " + rmiSocketFactoryTimeoutMillis + "ms." );
+                log.debug( "Remote cache socket timeout {0} ms.", rmiSocketFactoryTimeoutMillis );
             }
             catch ( NumberFormatException ignore )
             {
-                log.debug( "Remote cache socket timeout property " + SOCKET_TIMEOUT_MILLIS
-                    + " not specified.  The default will be used." );
+                log.debug( "Remote cache socket timeout property {0}" +
+                    " not specified. The default will be used.", SOCKET_TIMEOUT_MILLIS );
             }
         }
 
@@ -324,7 +313,8 @@ public class RemoteCacheServerFactory
         }
 
         // Register the RemoteCacheServer remote object in the registry.
-        rcsa.setRemoteServiceName( prop.getProperty( REMOTE_CACHE_SERVICE_NAME, REMOTE_CACHE_SERVICE_VAL ).trim() );
+        rcsa.setRemoteServiceName(
+                prop.getProperty( REMOTE_CACHE_SERVICE_NAME, REMOTE_CACHE_SERVICE_VAL ).trim() );
     }
 
     /**
@@ -343,7 +333,8 @@ public class RemoteCacheServerFactory
             {
                 return;
             }
-            log.info( "Unbinding host=" + host + ", port=" + port + ", serviceName=" + getServiceName() );
+            log.info( "Unbinding host={0}, port={1}, serviceName={2}",
+                    host, port, getServiceName() );
             try
             {
                 Naming.unbind( RemoteUtils.getNamingURL(host, port, getServiceName()) );
@@ -471,15 +462,9 @@ public class RemoteCacheServerFactory
         String remoteServiceName = config.getProperty( REMOTE_CACHE_SERVICE_NAME, REMOTE_CACHE_SERVICE_VAL ).trim();
         String registry = RemoteUtils.getNamingURL("", port, remoteServiceName);
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "looking up server " + registry );
-        }
+        log.debug( "looking up server {0}", registry );
         Object obj = Naming.lookup( registry );
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "server found" );
-        }
+        log.debug( "server found" );
 
         return (ICacheServiceAdmin) obj;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheStartupServlet.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheStartupServlet.java
index 538f64f..5bc7431 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheStartupServlet.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/server/RemoteCacheStartupServlet.java
@@ -34,9 +34,9 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.commons.jcs.access.exception.CacheException;
 import org.apache.commons.jcs.auxiliary.remote.RemoteUtils;
 import org.apache.commons.jcs.engine.control.CompositeCacheManager;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.net.HostNameUtil;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This servlet can be used to startup the JCS remote cache. It is easy to
@@ -68,7 +68,7 @@ public class RemoteCacheStartupServlet
     private static final long serialVersionUID = 1L;
 
     /** The logger */
-    private static final Log log = LogFactory.getLog(RemoteCacheStartupServlet.class);
+    private static final Log log = LogManager.getLog(RemoteCacheStartupServlet.class);
 
     /** The default port to start the registry on. */
     private static final int DEFAULT_REGISTRY_PORT = 1101;
@@ -117,15 +117,12 @@ public class RemoteCacheStartupServlet
             }
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("registryHost = [" + registryHost + "]");
-        }
+        log.debug("registryHost = [{0}]", registryHost);
 
         if ("localhost".equals(registryHost) || "127.0.0.1".equals(registryHost))
         {
-            log.warn("The local address [" + registryHost
-                    + "] is INVALID.  Other machines must be able to use the address to reach this server.");
+            log.warn("The local address [{0}] is INVALID. Other machines must "
+                    + "be able to use the address to reach this server.", registryHost);
         }
 
         try
@@ -136,10 +133,7 @@ public class RemoteCacheStartupServlet
             }
 
             RemoteCacheServerFactory.startup(registryHost, registryPort, props);
-            if (log.isInfoEnabled())
-            {
-                log.info("Remote JCS Server started with properties from " + propsFileName);
-            }
+            log.info("Remote JCS Server started with properties from {0}", propsFileName);
         }
         catch (IOException e)
         {
@@ -171,10 +165,7 @@ public class RemoteCacheStartupServlet
             throw new ServletException(e);
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info(stats);
-        }
+        log.info(stats);
 
         try
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/util/RemoteCacheRequestFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/util/RemoteCacheRequestFactory.java
index 4c09a95..b2c1bc8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/util/RemoteCacheRequestFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/remote/util/RemoteCacheRequestFactory.java
@@ -24,8 +24,8 @@ import java.util.Set;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheRequest;
 import org.apache.commons.jcs.auxiliary.remote.value.RemoteRequestType;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This creates request objects. You could write your own client and use the objects from this
@@ -34,7 +34,7 @@ import org.apache.commons.logging.LogFactory;
 public class RemoteCacheRequestFactory
 {
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( RemoteCacheRequestFactory.class );
+    private static final Log log = LogManager.getLog( RemoteCacheRequestFactory.class );
 
     /**
      * Create generic request
@@ -50,10 +50,7 @@ public class RemoteCacheRequestFactory
         request.setRequestType( requestType );
         request.setRequesterId( requesterId );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Created: " + request );
-        }
+        log.debug( "Created: {0}", request );
 
         return request;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/AbstractCacheEventQueue.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/AbstractCacheEventQueue.java
index 55b0af8..18588a5 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/AbstractCacheEventQueue.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/AbstractCacheEventQueue.java
@@ -25,8 +25,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheEventQueue;
 import org.apache.commons.jcs.engine.behavior.ICacheListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * An abstract base class to the different implementations
@@ -35,7 +35,7 @@ public abstract class AbstractCacheEventQueue<K, V>
     implements ICacheEventQueue<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( AbstractCacheEventQueue.class );
+    private static final Log log = LogManager.getLog( AbstractCacheEventQueue.class );
 
     /** default */
     protected static final int DEFAULT_WAIT_TO_DIE_MILLIS = 10000;
@@ -141,10 +141,7 @@ public abstract class AbstractCacheEventQueue<K, V>
         this.maxFailure = maxFailure <= 0 ? 3 : maxFailure;
         this.waitBeforeRetry = waitBeforeRetry <= 0 ? 500 : waitBeforeRetry;
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Constructed: " + this );
-        }
+        log.debug( "Constructed: {0}", this );
     }
 
     /**
@@ -224,24 +221,17 @@ public abstract class AbstractCacheEventQueue<K, V>
             }
             catch ( IOException e )
             {
-                if ( log.isWarnEnabled() )
-                {
-                    log.warn( e );
-                }
+                log.warn( e );
                 if ( ++failures >= maxFailure )
                 {
-                    if ( log.isWarnEnabled() )
-                    {
-                        log.warn( "Error while running event from Queue: " + this
-                            + ". Dropping Event and marking Event Queue as non-functional." );
-                    }
+                    log.warn( "Error while running event from Queue: {0}. "
+                            + "Dropping Event and marking Event Queue as "
+                            + "non-functional.", this );
                     destroy();
                     return;
                 }
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Error while running event from Queue: " + this + ". Retrying..." );
-                }
+                log.info( "Error while running event from Queue: {0}. "
+                        + "Retrying...", this );
                 try
                 {
                     Thread.sleep( waitBeforeRetry );
@@ -249,10 +239,8 @@ public abstract class AbstractCacheEventQueue<K, V>
                 }
                 catch ( InterruptedException ie )
                 {
-                    if ( log.isErrorEnabled() )
-                    {
-                        log.warn( "Interrupted while sleeping for retry on event " + this + "." );
-                    }
+                    log.warn( "Interrupted while sleeping for retry on event "
+                            + "{0}.", this );
                     destroy();
                 }
             }
@@ -306,8 +294,11 @@ public abstract class AbstractCacheEventQueue<K, V>
         @Override
         public String toString()
         {
-            return new StringBuilder( "PutEvent for key: " ).append( ice.getKey() ).append( " value: " )
-                .append( ice.getVal() ).toString();
+            return new StringBuilder( "PutEvent for key: " )
+                    .append( ice.getKey() )
+                    .append( " value: " )
+                    .append( ice.getVal() )
+                    .toString();
         }
 
     }
@@ -353,7 +344,9 @@ public abstract class AbstractCacheEventQueue<K, V>
         @Override
         public String toString()
         {
-            return new StringBuilder( "RemoveEvent for " ).append( key ).toString();
+            return new StringBuilder( "RemoveEvent for " )
+                    .append( key )
+                    .toString();
         }
 
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheAdaptor.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheAdaptor.java
index 7554a31..28ea819 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheAdaptor.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheAdaptor.java
@@ -1,5 +1,7 @@
 package org.apache.commons.jcs.engine;
 
+import java.io.IOException;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -22,10 +24,6 @@ package org.apache.commons.jcs.engine;
 import org.apache.commons.jcs.engine.behavior.ICache;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.IOException;
 
 /**
  * Used for Cache-to-Cache messaging purposes. These are used in the balking
@@ -34,9 +32,6 @@ import java.io.IOException;
 public class CacheAdaptor<K, V>
     implements ICacheListener<K, V>
 {
-    /** The logger */
-    private static final Log log = LogFactory.getLog( CacheAdaptor.class );
-
     /** The cache we are adapting. */
     private final ICache<K, V> cache;
 
@@ -55,7 +50,6 @@ public class CacheAdaptor<K, V>
         throws IOException
     {
         this.listenerId = id;
-        log.debug( "listenerId = " + id );
     }
 
     /**
@@ -95,7 +89,7 @@ public class CacheAdaptor<K, V>
         {
             cache.update( item );
         }
-        catch ( Exception e )
+        catch ( IOException e )
         {
             // swallow
         }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheEventQueueFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheEventQueueFactory.java
index 12201ec..afeb798 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheEventQueueFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheEventQueueFactory.java
@@ -21,8 +21,8 @@ package org.apache.commons.jcs.engine;
 
 import org.apache.commons.jcs.engine.behavior.ICacheEventQueue;
 import org.apache.commons.jcs.engine.behavior.ICacheListener;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This class hands out event Queues. This allows us to change the implementation more easily. You
@@ -33,7 +33,7 @@ import org.apache.commons.logging.LogFactory;
 public class CacheEventQueueFactory<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( CacheEventQueueFactory.class );
+    private static final Log log = LogManager.getLog( CacheEventQueueFactory.class );
 
     /**
      * The most commonly used factory method.
@@ -67,10 +67,7 @@ public class CacheEventQueueFactory<K, V>
                                                    int maxFailure, int waitBeforeRetry, String threadPoolName,
                                                    ICacheEventQueue.QueueType poolType )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "threadPoolName = [" + threadPoolName + "] poolType = " + poolType + " " );
-        }
+        log.debug( "threadPoolName = [{0}] poolType = {1}", threadPoolName, poolType );
 
         ICacheEventQueue<K, V> eventQueue = null;
         if ( poolType == null || ICacheEventQueue.QueueType.SINGLE == poolType )
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheWatchRepairable.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheWatchRepairable.java
index 649edf2..97b5a2b 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheWatchRepairable.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/CacheWatchRepairable.java
@@ -28,8 +28,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.apache.commons.jcs.engine.behavior.ICacheListener;
 import org.apache.commons.jcs.engine.behavior.ICacheObserver;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Intercepts the requests to the underlying ICacheObserver object so that the listeners can be
@@ -40,7 +40,7 @@ public class CacheWatchRepairable
     implements ICacheObserver
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( CacheWatchRepairable.class );
+    private static final Log log = LogManager.getLog( CacheWatchRepairable.class );
 
     /** the underlying ICacheObserver. */
     private ICacheObserver cacheWatch;
@@ -65,17 +65,14 @@ public class CacheWatchRepairable
             {
                 try
                 {
-                    if ( log.isInfoEnabled() )
-                    {
-                        log.info( "Adding listener to cache watch. ICacheListener = " + listener
-                            + " | ICacheObserver = " + cacheWatch );
-                    }
+                    log.info( "Adding listener to cache watch. ICacheListener = "
+                            + "{0} | ICacheObserver = {1}", listener, cacheWatch );
                     cacheWatch.addCacheListener( cacheName, listener );
                 }
                 catch ( IOException ex )
                 {
-                    log.error( "Problem adding listener. ICacheListener = " + listener + " | ICacheObserver = "
-                        + cacheWatch, ex );
+                    log.error( "Problem adding listener. ICacheListener = {0} | "
+                            + "ICacheObserver = {1}", listener, cacheWatch, ex );
                 }
             }
         }
@@ -100,11 +97,9 @@ public class CacheWatchRepairable
 
         listenerSet.add( obj );
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Adding listener to cache watch. ICacheListener = " + obj
-                + " | ICacheObserver = " + cacheWatch + " | cacheName = " + cacheName );
-        }
+        log.info( "Adding listener to cache watch. ICacheListener = {0} | "
+                + "ICacheObserver = {1} | cacheName = {2}", obj, cacheWatch,
+                cacheName );
         cacheWatch.addCacheListener( cacheName, obj );
     }
 
@@ -125,11 +120,8 @@ public class CacheWatchRepairable
             listenerSet.add( obj );
         }
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Adding listener to cache watch. ICacheListener = " + obj
-                + " | ICacheObserver = " + cacheWatch );
-        }
+        log.info( "Adding listener to cache watch. ICacheListener = {0} | "
+                + "ICacheObserver = {1}", obj, cacheWatch );
         cacheWatch.addCacheListener( obj );
     }
 
@@ -144,10 +136,7 @@ public class CacheWatchRepairable
     public <K, V> void removeCacheListener( String cacheName, ICacheListener<K, V> obj )
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "removeCacheListener, cacheName [" + cacheName + "]" );
-        }
+        log.info( "removeCacheListener, cacheName [{0}]", cacheName );
         // Record the removal locally, regardless of whether the remote
         // remove-listener operation succeeds or fails.
         Set<ICacheListener<?, ?>> listenerSet = cacheMap.get( cacheName );
@@ -166,19 +155,14 @@ public class CacheWatchRepairable
     public <K, V> void removeCacheListener( ICacheListener<K, V> obj )
         throws IOException
     {
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "removeCacheListener, ICacheListener [" + obj + "]" );
-        }
+        log.info( "removeCacheListener, ICacheListener [{0}]", obj );
 
         // Record the removal locally, regardless of whether the remote
         // remove-listener operation succeeds or fails.
         for (Set<ICacheListener<?, ?>> listenerSet : cacheMap.values())
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Before removing [" + obj + "] the listenerSet = " + listenerSet );
-            }
+            log.debug( "Before removing [{0}] the listenerSet = {1}", obj,
+                    listenerSet );
             listenerSet.remove( obj );
         }
         cacheWatch.removeCacheListener( obj );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/PooledCacheEventQueue.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/PooledCacheEventQueue.java
index a602cfa..cd94f7d 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/PooledCacheEventQueue.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/PooledCacheEventQueue.java
@@ -29,9 +29,9 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * An event queue is used to propagate ordered cache events to one and only one target listener.
@@ -47,7 +47,7 @@ public class PooledCacheEventQueue<K, V>
     extends AbstractCacheEventQueue<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( PooledCacheEventQueue.class );
+    private static final Log log = LogManager.getLog( PooledCacheEventQueue.class );
 
     /** The type of event queue */
     private static final QueueType queueType = QueueType.POOLED;
@@ -92,7 +92,7 @@ public class PooledCacheEventQueue<K, V>
         // this will share the same pool with other event queues by default.
         pool = ThreadPoolManager.getInstance().getExecutorService(
                 (threadPoolName == null) ? "cache_event_queue" : threadPoolName );
-        
+
         if (pool instanceof ThreadPoolExecutor)
         {
         	queue = ((ThreadPoolExecutor) pool).getQueue();
@@ -118,10 +118,7 @@ public class PooledCacheEventQueue<K, V>
         {
             setWorking(false);
             pool.shutdownNow();
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Cache event queue destroyed: " + this );
-            }
+            log.info( "Cache event queue destroyed: {0}", this );
         }
     }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheService.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheService.java
index dfa47fe..061da02 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheService.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheService.java
@@ -1,5 +1,10 @@
 package org.apache.commons.jcs.engine;
 
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -22,13 +27,8 @@ package org.apache.commons.jcs.engine;
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheService;
 import org.apache.commons.jcs.engine.behavior.IZombie;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * Zombie adapter for any cache service. Balks at every call.
@@ -37,17 +37,14 @@ public class ZombieCacheService<K, V>
     implements ICacheService<K, V>, IZombie
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog( ZombieCacheService.class );
+    private static final Log log = LogManager.getLog( ZombieCacheService.class );
 
     /**
      * @param item
      */
     public void put( ICacheElement<K, V> item )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Zombie put for item " + item );
-        }
+        log.debug( "Zombie put for item {0}", item );
         // zombies have no inner life
     }
 
@@ -109,10 +106,8 @@ public class ZombieCacheService<K, V>
      */
     public Serializable get( String cacheName, K key, boolean container )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Zombie get for key [" + key + "] cacheName [" + cacheName + "] container [" + container + "]" );
-        }
+        log.debug( "Zombie get for key [{0}] cacheName [{1}] container [{2}]",
+                key, cacheName, container);
         // zombies have no inner life
         return null;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheServiceNonLocal.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheServiceNonLocal.java
index 313c534..8aa5630 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheServiceNonLocal.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/ZombieCacheServiceNonLocal.java
@@ -28,9 +28,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.apache.commons.jcs.engine.behavior.ICacheServiceNonLocal;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.timing.ElapsedTimer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Zombie adapter for the non local cache services. It just balks if there is no queue configured.
@@ -46,7 +46,7 @@ public class ZombieCacheServiceNonLocal<K, V>
     implements ICacheServiceNonLocal<K, V>
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( ZombieCacheServiceNonLocal.class );
+    private static final Log log = LogManager.getLog( ZombieCacheServiceNonLocal.class );
 
     /** How big can the queue grow. */
     private int maxQueueSize = 0;
@@ -211,10 +211,7 @@ public class ZombieCacheServiceNonLocal<K, V>
         throws Exception
     {
         int cnt = 0;
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Propagating events to the new ICacheServiceNonLocal." );
-        }
+        log.info( "Propagating events to the new ICacheServiceNonLocal." );
         ElapsedTimer timer = new ElapsedTimer();
         while ( !queue.isEmpty() )
         {
@@ -240,11 +237,8 @@ public class ZombieCacheServiceNonLocal<K, V>
                 service.removeAll( event.cacheName, event.requesterId );
             }
         }
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Propagated " + cnt + " events to the new ICacheServiceNonLocal in "
-                + timer.getElapsedTimeString() );
-        }
+        log.info( "Propagated {0} events to the new ICacheServiceNonLocal in {1}",
+                cnt, timer.getElapsedTimeString() );
     }
 
     /**
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
index 3447a73..f3a5c40 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCache.java
@@ -60,8 +60,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.behavior.ICacheStats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This is the primary hub for a single cache/region. It controls the flow of items through the
@@ -73,7 +73,7 @@ public class CompositeCache<K, V>
     implements ICache<K, V>, IRequireScheduler
 {
     /** log instance */
-    private static final Log log = LogFactory.getLog(CompositeCache.class);
+    private static final Log log = LogManager.getLog(CompositeCache.class);
 
     /**
      * EventQueue for handling element events. Lazy initialized. One for each region. To be more efficient, the manager
@@ -146,10 +146,8 @@ public class CompositeCache<K, V>
 
         createMemoryCache(cattr);
 
-        if (log.isInfoEnabled())
-        {
-            log.info("Constructed cache with name [" + cacheAttr.getCacheName() + "] and cache attributes " + cattr);
-        }
+        log.info("Constructed cache with name [{0}] and cache attributes {1}",
+                cacheAttr.getCacheName(), cattr);
     }
 
     /**
@@ -254,10 +252,7 @@ public class CompositeCache<K, V>
             throw new IllegalArgumentException("key cannot be a GroupId " + " for a put operation");
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("Updating memory cache " + cacheElement.getKey());
-        }
+        log.debug("Updating memory cache {0}", () -> cacheElement.getKey());
 
         updateCount.incrementAndGet();
         memCache.update(cacheElement);
@@ -291,16 +286,13 @@ public class CompositeCache<K, V>
         // more can be added if future auxiliary caches don't fit the model
         // You could run a database cache as either a remote or a local disk.
         // The types would describe the purpose.
-        if (log.isDebugEnabled())
+        if (auxCaches.length > 0)
         {
-            if (auxCaches.length > 0)
-            {
-                log.debug("Updating auxiliary caches");
-            }
-            else
-            {
-                log.debug("No auxiliary cache to update");
-            }
+            log.debug("Updating auxiliary caches");
+        }
+        else
+        {
+            log.debug("No auxiliary cache to update");
         }
 
         for (ICache<K, V> aux : auxCaches)
@@ -310,20 +302,14 @@ public class CompositeCache<K, V>
                 continue;
             }
 
-            if (log.isDebugEnabled())
-            {
-                log.debug("Auxiliary cache type: " + aux.getCacheType());
-            }
+            log.debug("Auxiliary cache type: {0}", aux.getCacheType());
 
             switch (aux.getCacheType())
             {
                 // SEND TO REMOTE STORE
                 case REMOTE_CACHE:
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("ce.getElementAttributes().getIsRemote() = "
-                            + cacheElement.getElementAttributes().getIsRemote());
-                    }
+                    log.debug("ce.getElementAttributes().getIsRemote() = {0}",
+                        () -> cacheElement.getElementAttributes().getIsRemote());
 
                     if (cacheElement.getElementAttributes().getIsRemote() && !localOnly)
                     {
@@ -332,10 +318,8 @@ public class CompositeCache<K, V>
                             // need to make sure the group cache understands that
                             // the key is a group attribute on update
                             aux.update(cacheElement);
-                            if (log.isDebugEnabled())
-                            {
-                                log.debug("Updated remote store for " + cacheElement.getKey() + cacheElement);
-                            }
+                            log.debug("Updated remote store for {0} {1}",
+                                    cacheElement.getKey(), cacheElement);
                         }
                         catch (IOException ex)
                         {
@@ -348,38 +332,26 @@ public class CompositeCache<K, V>
                 case LATERAL_CACHE:
                     // lateral can't do the checking since it is dependent on the
                     // cache region restrictions
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("lateralcache in aux list: cattr " + cacheAttr.isUseLateral());
-                    }
+                    log.debug("lateralcache in aux list: cattr {0}", () -> cacheAttr.isUseLateral());
                     if (cacheAttr.isUseLateral() && cacheElement.getElementAttributes().getIsLateral() && !localOnly)
                     {
                         // DISTRIBUTE LATERALLY
                         // Currently always multicast even if the value is
                         // unchanged, to cause the cache item to move to the front.
                         aux.update(cacheElement);
-                        if (log.isDebugEnabled())
-                        {
-                            log.debug("updated lateral cache for " + cacheElement.getKey());
-                        }
+                        log.debug("updated lateral cache for {0}", () -> cacheElement.getKey());
                     }
                     break;
 
                 // update disk if the usage pattern permits
                 case DISK_CACHE:
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("diskcache in aux list: cattr " + cacheAttr.isUseDisk());
-                    }
+                    log.debug("diskcache in aux list: cattr {0}", () -> cacheAttr.isUseDisk());
                     if (cacheAttr.isUseDisk()
                         && cacheAttr.getDiskUsagePattern() == DiskUsagePattern.UPDATE
                         && cacheElement.getElementAttributes().getIsSpool())
                     {
                         aux.update(cacheElement);
-                        if (log.isDebugEnabled())
-                        {
-                            log.debug("updated disk cache for " + cacheElement.getKey());
-                        }
+                        log.debug("updated disk cache for {0}", () -> cacheElement.getKey());
                     }
                     break;
 
@@ -432,31 +404,20 @@ public class CompositeCache<K, V>
                         throw new IllegalStateException(ex.getMessage());
                     }
 
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("spoolToDisk done for: " + ce.getKey() + " on disk cache[" + aux.getCacheName() + "]");
-                    }
+                    log.debug("spoolToDisk done for: {0} on disk cache[{1}]",
+                            () -> ce.getKey(), () -> aux.getCacheName());
                 }
                 else
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("DiskCache available, but JCS is not configured to use the DiskCache as a swap.");
-                    }
+                    log.debug("DiskCache available, but JCS is not configured "
+                            + "to use the DiskCache as a swap.");
                 }
             }
         }
 
         if (!diskAvailable)
         {
-            try
-            {
-                handleElementEvent(ce, ElementEventType.SPOOLED_DISK_NOT_AVAILABLE);
-            }
-            catch (Exception e)
-            {
-                log.error("Trouble handling the ELEMENT_EVENT_SPOOLED_DISK_NOT_AVAILABLE  element event", e);
-            }
+            handleElementEvent(ce, ElementEventType.SPOOLED_DISK_NOT_AVAILABLE);
         }
     }
 
@@ -501,10 +462,7 @@ public class CompositeCache<K, V>
 
         boolean found = false;
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("get: key = " + key + ", localOnly = " + localOnly);
-        }
+        log.debug("get: key = {0}, localOnly = {1}", key, localOnly);
 
         try
         {
@@ -516,20 +474,15 @@ public class CompositeCache<K, V>
                 // Found in memory cache
                 if (isExpired(element))
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug(cacheAttr.getCacheName() + " - Memory cache hit, but element expired");
-                    }
+                    log.debug("{0} - Memory cache hit, but element expired",
+                            () -> cacheAttr.getCacheName());
 
                     doExpires(element);
                     element = null;
                 }
                 else
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug(cacheAttr.getCacheName() + " - Memory cache hit");
-                    }
+                    log.debug("{0} - Memory cache hit", () -> cacheAttr.getCacheName());
 
                     // Update counters
                     hitCountRam.incrementAndGet();
@@ -549,11 +502,8 @@ public class CompositeCache<K, V>
 
                         if (!localOnly || cacheType == CacheType.DISK_CACHE)
                         {
-                            if (log.isDebugEnabled())
-                            {
-                                log.debug("Attempting to get from aux [" + aux.getCacheName() + "] which is of type: "
-                                    + cacheType);
-                            }
+                            log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+                                    () -> aux.getCacheName(), () -> cacheType);
 
                             try
                             {
@@ -565,20 +515,15 @@ public class CompositeCache<K, V>
                             }
                         }
 
-                        if (log.isDebugEnabled())
-                        {
-                            log.debug("Got CacheElement: " + element);
-                        }
+                        log.debug("Got CacheElement: {0}", element);
 
                         // Item found in one of the auxiliary caches.
                         if (element != null)
                         {
                             if (isExpired(element))
                             {
-                                if (log.isDebugEnabled())
-                                {
-                                    log.debug(cacheAttr.getCacheName() + " - Aux cache[" + aux.getCacheName() + "] hit, but element expired.");
-                                }
+                                log.debug("{0} - Aux cache[{1}] hit, but element expired.",
+                                        () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
 
                                 // This will tell the remotes to remove the item
                                 // based on the element's expiration policy. The elements attributes
@@ -589,10 +534,8 @@ public class CompositeCache<K, V>
                             }
                             else
                             {
-                                if (log.isDebugEnabled())
-                                {
-                                    log.debug(cacheAttr.getCacheName() + " - Aux cache[" + aux.getCacheName() + "] hit");
-                                }
+                                log.debug("{0} - Aux cache[{1}] hit.",
+                                        () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
 
                                 // Update counters
                                 hitCountAux.incrementAndGet();
@@ -616,10 +559,7 @@ public class CompositeCache<K, V>
         {
             missCountNotFound.incrementAndGet();
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(cacheAttr.getCacheName() + " - Miss");
-            }
+            log.debug("{0} - Miss", () -> cacheAttr.getCacheName());
         }
 
         if (element != null)
@@ -630,7 +570,8 @@ public class CompositeCache<K, V>
         return element;
     }
 
-    protected void doExpires(ICacheElement<K, V> element) {
+    protected void doExpires(ICacheElement<K, V> element)
+    {
         missCountExpired.incrementAndGet();
         remove(element.getKey());
     }
@@ -677,10 +618,7 @@ public class CompositeCache<K, V>
     {
         Map<K, ICacheElement<K, V>> elements = new HashMap<>();
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("get: key = " + keys + ", localOnly = " + localOnly);
-        }
+        log.debug("get: key = {0}, localOnly = {1}", keys, localOnly);
 
         try
         {
@@ -704,10 +642,8 @@ public class CompositeCache<K, V>
         {
             missCountNotFound.addAndGet(keys.size() - elements.size());
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(cacheAttr.getCacheName() + " - " + (keys.size() - elements.size()) + " Misses");
-            }
+            log.debug("{0} - {1} Misses", () -> cacheAttr.getCacheName(),
+                    () -> keys.size() - elements.size());
         }
 
         return elements;
@@ -728,20 +664,15 @@ public class CompositeCache<K, V>
             ICacheElement<K, V> element = entry.getValue();
             if (isExpired(element))
             {
-                if (log.isDebugEnabled())
-                {
-                    log.debug(cacheAttr.getCacheName() + " - Memory cache hit, but element expired");
-                }
+                log.debug("{0} - Memory cache hit, but element expired",
+                        () -> cacheAttr.getCacheName());
 
                 doExpires(element);
                 return true;
             }
             else
             {
-                if (log.isDebugEnabled())
-                {
-                    log.debug(cacheAttr.getCacheName() + " - Memory cache hit");
-                }
+                log.debug("{0} - Memory cache hit", () -> cacheAttr.getCacheName());
 
                 // Update counters
                 hitCountRam.incrementAndGet();
@@ -777,11 +708,8 @@ public class CompositeCache<K, V>
 
                 if (!localOnly || cacheType == CacheType.DISK_CACHE)
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Attempting to get from aux [" + aux.getCacheName() + "] which is of type: "
-                            + cacheType);
-                    }
+                    log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+                            () -> aux.getCacheName(), () -> cacheType);
 
                     try
                     {
@@ -793,10 +721,7 @@ public class CompositeCache<K, V>
                     }
                 }
 
-                if (log.isDebugEnabled())
-                {
-                    log.debug("Got CacheElements: " + elementsFromAuxiliary);
-                }
+                log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
 
                 processRetrievedElements(aux, elementsFromAuxiliary);
                 elements.putAll(elementsFromAuxiliary);
@@ -856,10 +781,7 @@ public class CompositeCache<K, V>
      */
     protected Map<K, ICacheElement<K, V>> getMatching(String pattern, boolean localOnly)
     {
-        if (log.isDebugEnabled())
-        {
-            log.debug("get: pattern [" + pattern + "], localOnly = " + localOnly);
-        }
+        log.debug("get: pattern [{0}], localOnly = {1}", pattern, localOnly);
 
         try
         {
@@ -931,11 +853,8 @@ public class CompositeCache<K, V>
 
                 if (!localOnly || cacheType == CacheType.DISK_CACHE)
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Attempting to get from aux [" + aux.getCacheName() + "] which is of type: "
-                            + cacheType);
-                    }
+                    log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+                            () -> aux.getCacheName(), () -> cacheType);
 
                     try
                     {
@@ -946,10 +865,7 @@ public class CompositeCache<K, V>
                         log.error("Error getting from aux", e);
                     }
 
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Got CacheElements: " + elementsFromAuxiliary);
-                    }
+                    log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
 
                     processRetrievedElements(aux, elementsFromAuxiliary);
                     elements.putAll(elementsFromAuxiliary);
@@ -978,10 +894,8 @@ public class CompositeCache<K, V>
             {
                 if (isExpired(element))
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug(cacheAttr.getCacheName() + " - Aux cache[" + aux.getCacheName() + "] hit, but element expired.");
-                    }
+                    log.debug("{0} - Aux cache[{1}] hit, but element expired.",
+                            () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
 
                     // This will tell the remote caches to remove the item
                     // based on the element's expiration policy. The elements attributes
@@ -992,10 +906,8 @@ public class CompositeCache<K, V>
                 }
                 else
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug(cacheAttr.getCacheName() + " - Aux cache[" + aux.getCacheName() + "] hit");
-                    }
+                    log.debug("{0} - Aux cache[{1}] hit.",
+                            () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
 
                     // Update counters
                     hitCountAux.incrementAndGet();
@@ -1005,8 +917,8 @@ public class CompositeCache<K, V>
                     }
                     catch (IOException e)
                     {
-                        log.error(cacheAttr.getCacheName()
-                                + " failed to copy element to memory " + element, e);
+                        log.error("{0} failed to copy element to memory {1}",
+                                cacheAttr.getCacheName(), element, e);
                     }
                 }
             }
@@ -1031,10 +943,7 @@ public class CompositeCache<K, V>
         }
         else
         {
-            if (log.isDebugEnabled())
-            {
-                log.debug("Skipping memory update since no items are allowed in memory");
-            }
+            log.debug("Skipping memory update since no items are allowed in memory");
         }
     }
 
@@ -1169,10 +1078,7 @@ public class CompositeCache<K, V>
             }
             try
             {
-                if (log.isDebugEnabled())
-                {
-                    log.debug("Removing " + key + " from cacheType" + cacheType);
-                }
+                log.debug("Removing {0} from cacheType {1}", key, cacheType);
 
                 boolean b = aux.remove(key);
 
@@ -1229,10 +1135,7 @@ public class CompositeCache<K, V>
         {
             memCache.removeAll();
 
-            if (log.isDebugEnabled())
-            {
-                log.debug("Removed All keys from the memory cache.");
-            }
+            log.debug("Removed All keys from the memory cache.");
         }
         catch (IOException ex)
         {
@@ -1246,10 +1149,8 @@ public class CompositeCache<K, V>
             {
                 try
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Removing All keys from cacheType" + aux.getCacheType());
-                    }
+                    log.debug("Removing All keys from cacheType {0}",
+                            () -> aux.getCacheType());
 
                     aux.removeAll();
                 }
@@ -1285,10 +1186,8 @@ public class CompositeCache<K, V>
             return;
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info("In DISPOSE, [" + this.cacheAttr.getCacheName() + "] fromRemote [" + fromRemote + "]");
-        }
+        log.info("In DISPOSE, [{0}] fromRemote [{1}]",
+                () -> this.cacheAttr.getCacheName(), () -> fromRemote);
 
         // Remove us from the cache managers list
         // This will call us back but exit immediately
@@ -1323,18 +1222,14 @@ public class CompositeCache<K, V>
                 if (aux == null || aux.getStatus() != CacheStatus.ALIVE
                     || (fromRemote && aux.getCacheType() == CacheType.REMOTE_CACHE))
                 {
-                    if (log.isInfoEnabled())
-                    {
-                        log.info("In DISPOSE, [" + this.cacheAttr.getCacheName() + "] SKIPPING auxiliary [" + aux.getCacheName() + "] fromRemote ["
-                            + fromRemote + "]");
-                    }
+                    log.info("In DISPOSE, [{0}] SKIPPING auxiliary [{1}] fromRemote [{2}]",
+                            () -> this.cacheAttr.getCacheName(), () -> aux.getCacheName(),
+                            () -> fromRemote);
                     continue;
                 }
 
-                if (log.isInfoEnabled())
-                {
-                    log.info("In DISPOSE, [" + this.cacheAttr.getCacheName() + "] auxiliary [" + aux.getCacheName() + "]");
-                }
+                log.info("In DISPOSE, [{0}] auxiliary [{1}]",
+                        () -> this.cacheAttr.getCacheName(), () -> aux.getCacheName());
 
                 // IT USED TO BE THE CASE THAT (If the auxiliary is not a lateral, or the cache
                 // attributes
@@ -1347,10 +1242,9 @@ public class CompositeCache<K, V>
                     int numToFree = memCache.getSize();
                     memCache.freeElements(numToFree);
 
-                    if (log.isInfoEnabled())
-                    {
-                        log.info("In DISPOSE, [" + this.cacheAttr.getCacheName() + "] put " + numToFree + " into auxiliary " + aux.getCacheName());
-                    }
+                    log.info("In DISPOSE, [{0}] put {1} into auxiliary [{2}]",
+                            () -> this.cacheAttr.getCacheName(), () -> numToFree,
+                            () -> aux.getCacheName());
                 }
 
                 // Dispose of the auxiliary
@@ -1362,10 +1256,8 @@ public class CompositeCache<K, V>
             }
         }
 
-        if (log.isInfoEnabled())
-        {
-            log.info("In DISPOSE, [" + this.cacheAttr.getCacheName() + "] disposing of memory cache.");
-        }
+        log.info("In DISPOSE, [{0}] disposing of memory cache.",
+                () -> this.cacheAttr.getCacheName());
         try
         {
             memCache.dispose();
@@ -1411,10 +1303,7 @@ public class CompositeCache<K, V>
             }
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("Called save for [" + cacheAttr.getCacheName() + "]");
-        }
+        log.debug("Called save for [{0}]", () -> cacheAttr.getCacheName());
     }
 
     /**
@@ -1615,10 +1504,7 @@ public class CompositeCache<K, V>
 
                 if (maxLifeSeconds != -1 && (timestamp - createTime) > (maxLifeSeconds * timeFactorForMilliseconds))
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Exceeded maxLife: " + element.getKey());
-                    }
+                    log.debug("Exceeded maxLife: {0}", () -> element.getKey());
 
                     handleElementEvent(element, eventMaxlife);
                     return true;
@@ -1632,10 +1518,7 @@ public class CompositeCache<K, V>
                 // you will need to set the idle time to -1.
                 if ((idleTime != -1) && (timestamp - lastAccessTime) > idleTime * timeFactorForMilliseconds)
                 {
-                    if (log.isDebugEnabled())
-                    {
-                        log.debug("Exceeded maxIdle: " + element.getKey());
-                    }
+                    log.debug("Exceeded maxIdle: {0}", () -> element.getKey());
 
                     handleElementEvent(element, eventIdle);
                     return true;
@@ -1665,13 +1548,10 @@ public class CompositeCache<K, V>
         ArrayList<IElementEventHandler> eventHandlers = element.getElementAttributes().getElementEventHandlers();
         if (eventHandlers != null)
         {
-            if (log.isDebugEnabled())
-            {
-                log.debug("Element Handlers are registered.  Create event type " + eventType);
-            }
+            log.debug("Element Handlers are registered.  Create event type {0}", eventType);
             if (elementEventQ == null)
             {
-                log.warn("No element event queue available for cache " + getCacheName());
+                log.warn("No element event queue available for cache {0}", getCacheName());
                 return;
             }
             IElementEvent<ICacheElement<K, V>> event = new ElementEvent<>(element, eventType);
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java
index 0a0444c..938eb35 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheConfigurator.java
@@ -36,10 +36,10 @@ import org.apache.commons.jcs.engine.behavior.IRequireScheduler;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
 import org.apache.commons.jcs.engine.match.KeyMatcherPatternImpl;
 import org.apache.commons.jcs.engine.match.behavior.IKeyMatcher;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.OptionConverter;
 import org.apache.commons.jcs.utils.config.PropertySetter;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This class configures JCS based on a properties object.
@@ -51,7 +51,7 @@ import org.apache.commons.logging.LogFactory;
 public class CompositeCacheConfigurator
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( CompositeCacheConfigurator.class );
+    private static final Log log = LogManager.getLog( CompositeCacheConfigurator.class );
 
     /** The prefix of relevant system properties */
     protected static final String SYSTEM_PROPERTY_KEY_PREFIX = "jcs";
@@ -139,10 +139,7 @@ public class CompositeCacheConfigurator
             }
         }
 
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Parsed regions " + regionNames );
-        }
+        log.info( "Parsed regions {0}", regionNames );
     }
 
     /**
@@ -227,10 +224,7 @@ public class CompositeCacheConfigurator
             // Next, create the auxiliaries for the new cache
             List<AuxiliaryCache<K, V>> auxList = new ArrayList<>();
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Parsing region name '" + regName + "', value '" + auxiliaries + "'" );
-            }
+            log.debug( "Parsing region name \"{0}\", value \"{1}\"", regName, auxiliaries );
 
             // We must skip over ',' but not white space
             StringTokenizer st = new StringTokenizer( auxiliaries, "," );
@@ -256,7 +250,7 @@ public class CompositeCacheConfigurator
                 {
                     continue;
                 }
-                log.debug( "Parsing auxiliary named \"" + auxName + "\"." );
+                log.debug( "Parsing auxiliary named \"{0}\".", auxName );
 
                 auxCache = parseAuxiliary( props, ccm, auxName, regName );
 
@@ -326,27 +320,18 @@ public class CompositeCacheConfigurator
 
         if ( ccAttr == null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "No special CompositeCacheAttributes class defined for key [" + attrName
-                    + "], using default class." );
-            }
+            log.info( "No special CompositeCacheAttributes class defined for "
+                    + "key [{0}], using default class.", attrName );
 
             ccAttr = defaultCCAttr;
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Parsing options for '" + attrName + "'" );
-        }
+        log.debug( "Parsing options for \"{0}\"", attrName );
 
         PropertySetter.setProperties( ccAttr, props, attrName + "." );
         ccAttr.setCacheName( regName );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "End of parsing for \"" + attrName + "\"." );
-        }
+        log.debug( "End of parsing for \"{0}\"", attrName );
 
         // GET CACHE FROM FACTORY WITH ATTRIBUTES
         ccAttr.setCacheName( regName );
@@ -375,26 +360,18 @@ public class CompositeCacheConfigurator
         eAttr = OptionConverter.instantiateByKey( props, attrName, null );
         if ( eAttr == null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "No special ElementAttribute class defined for key [" + attrName + "], using default class." );
-            }
+            log.info( "No special ElementAttribute class defined for key [{0}], "
+                    + "using default class.", attrName );
 
             eAttr = defaultEAttr;
         }
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Parsing options for '" + attrName + "'" );
-        }
+        log.debug( "Parsing options for \"{0}\"", attrName );
 
         PropertySetter.setProperties( eAttr, props, attrName + "." );
         // eAttr.setCacheName( regName );
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "End of parsing for \"" + attrName + "\"." );
-        }
+        log.debug( "End of parsing for \"{0}\"", attrName );
 
         // GET CACHE FROM FACTORY WITH ATTRIBUTES
         // eAttr.setCacheName( regName );
@@ -413,10 +390,7 @@ public class CompositeCacheConfigurator
     protected <K, V> AuxiliaryCache<K, V> parseAuxiliary( Properties props, CompositeCacheManager ccm,
             String auxName, String regName )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "parseAuxiliary " + auxName );
-        }
+        log.debug( "parseAuxiliary {0}", auxName );
 
         // GET CACHE
         @SuppressWarnings("unchecked") // Common map for all caches
@@ -433,7 +407,7 @@ public class CompositeCacheConfigurator
                 auxFac = OptionConverter.instantiateByKey( props, prefix, null );
                 if ( auxFac == null )
                 {
-                    log.error( "Could not instantiate auxFactory named \"" + auxName + "\"." );
+                    log.error( "Could not instantiate auxFactory named \"{0}\"", auxName );
                     return null;
                 }
 
@@ -458,7 +432,7 @@ public class CompositeCacheConfigurator
                 auxAttr = OptionConverter.instantiateByKey( props, prefix, null );
                 if ( auxAttr == null )
                 {
-                    log.error( "Could not instantiate auxAttr named '" + attrName + "'" );
+                    log.error( "Could not instantiate auxAttr named \"{0}\"", attrName );
                     return null;
                 }
                 auxAttr.setName( auxName );
@@ -467,18 +441,12 @@ public class CompositeCacheConfigurator
 
             auxAttr = auxAttr.clone();
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Parsing options for '" + attrName + "'" );
-            }
+            log.debug( "Parsing options for \"{0}\"", attrName );
 
             PropertySetter.setProperties( auxAttr, props, attrName + "." );
             auxAttr.setCacheName( regName );
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "End of parsing for '" + attrName + "'" );
-            }
+            log.debug( "End of parsing for \"{0}\"", attrName );
 
             // GET CACHE FROM FACTORY WITH ATTRIBUTES
             auxAttr.setCacheName( regName );
@@ -507,7 +475,7 @@ public class CompositeCacheConfigurator
             }
             catch (Exception e)
             {
-                log.error( "Could not instantiate auxiliary cache named \"" + regName + "\"." );
+                log.error( "Could not instantiate auxiliary cache named \"{0}\"", regName );
                 return null;
             }
 
@@ -530,10 +498,8 @@ public class CompositeCacheConfigurator
         {
             if ( key.startsWith( SYSTEM_PROPERTY_KEY_PREFIX ) )
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Using system property [[" + key + "] [" + sysProps.getProperty( key ) + "]]" );
-                }
+                log.info( "Using system property [[{0}] [{1}]]", () -> key,
+                        () -> sysProps.getProperty( key ) );
                 props.setProperty( key, sysProps.getProperty( key ) );
             }
         }
@@ -556,20 +522,13 @@ public class CompositeCacheConfigurator
         {
             String attributePrefix = auxPrefix + KEY_MATCHER_PREFIX + ATTRIBUTE_PREFIX;
             PropertySetter.setProperties( keyMatcher, props, attributePrefix + "." );
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Using custom key matcher [" + keyMatcher + "] for auxiliary [" + auxPrefix
-                    + "]" );
-            }
+            log.info( "Using custom key matcher [{0}] for auxiliary [{1}]", keyMatcher, auxPrefix );
         }
         else
         {
             // use the default standard serializer
             keyMatcher = new KeyMatcherPatternImpl<>();
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Using standard key matcher [" + keyMatcher + "] for auxiliary [" + auxPrefix + "]" );
-            }
+            log.info( "Using standard key matcher [{0}] for auxiliary [{1}]", keyMatcher, auxPrefix );
         }
         return keyMatcher;
     }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java
index 4013082..6ae964e 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/CompositeCacheManager.java
@@ -55,11 +55,11 @@ import org.apache.commons.jcs.engine.control.event.ElementEventQueue;
 import org.apache.commons.jcs.engine.control.event.behavior.IElementEventQueue;
 import org.apache.commons.jcs.engine.stats.CacheStats;
 import org.apache.commons.jcs.engine.stats.behavior.ICacheStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.config.OptionConverter;
 import org.apache.commons.jcs.utils.threadpool.DaemonThreadFactory;
 import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * Manages a composite cache. This provides access to caches and is the primary way to shutdown the
@@ -73,7 +73,7 @@ public class CompositeCacheManager
     implements IRemoteCacheConstants, ICompositeCacheManager, IProvideScheduler
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( CompositeCacheManager.class );
+    private static final Log log = LogManager.getLog( CompositeCacheManager.class );
 
     /** JMX object name */
     public static final String JMX_OBJECT_NAME = "org.apache.commons.jcs:type=JCSAdminBean";
@@ -131,7 +131,7 @@ public class CompositeCacheManager
     private IElementEventQueue elementEventQueue;
 
     /** Shutdown hook thread instance */
-    private ShutdownHook shutdownHook;
+    private Thread shutdownHook;
 
     /** Indicates whether the instance has been initialized. */
     private boolean isInitialized = false;
@@ -168,11 +168,7 @@ public class CompositeCacheManager
     {
         if ( instance == null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Instance is null, creating with config [" + propsFilename + "]" );
-            }
-
+            log.info( "Instance is null, creating with config [{0}]", propsFilename );
             instance = createInstance();
         }
 
@@ -201,11 +197,7 @@ public class CompositeCacheManager
     {
         if ( instance == null )
         {
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Instance is null, returning unconfigured instance" );
-            }
-
+            log.info( "Instance is null, returning unconfigured instance" );
             instance = createInstance();
         }
 
@@ -243,7 +235,13 @@ public class CompositeCacheManager
     {
         if (!isInitialized)
         {
-            this.shutdownHook = new ShutdownHook();
+            this.shutdownHook = new Thread(() -> {
+                if ( isInitialized() )
+                {
+                    log.info("Shutdown hook activated. Shutdown was not called. Shutting down JCS.");
+                    shutDown();
+                }
+            });
             try
             {
                 Runtime.getRuntime().addShutdownHook( shutdownHook );
@@ -317,18 +315,14 @@ public class CompositeCacheManager
      */
     public void configure( String propFile ) throws CacheException
     {
-        log.info( "Creating cache manager from config file: " + propFile );
+        log.info( "Creating cache manager from config file: {0}", propFile );
 
         Properties props = new Properties();
 
         try (InputStream is = getClass().getResourceAsStream( propFile ))
         {
             props.load( is );
-
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "File [" + propFile + "] contained " + props.size() + " properties" );
-            }
+            log.debug( "File [{0}] contained {1} properties", () -> propFile, () -> props.size());
         }
         catch ( IOException ex )
         {
@@ -386,7 +380,7 @@ public class CompositeCacheManager
     {
         if ( props == null )
         {
-            log.error( "No properties found.  Please configure the cache correctly." );
+            log.error( "No properties found. Please configure the cache correctly." );
             return;
         }
 
@@ -394,20 +388,14 @@ public class CompositeCacheManager
         {
             if ( !forceReconfiguration )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Configure called after the manager has been configured.  "
-                        + "Force reconfiguration is false.  Doing nothing" );
-                }
+                log.debug( "Configure called after the manager has been configured.  "
+                         + "Force reconfiguration is false. Doing nothing" );
                 return;
             }
             else
             {
-                if ( log.isInfoEnabled() )
-                {
-                    log.info( "Configure called after the manager has been configured.  "
-                        + "Force reconfiguration is true.  Reconfiguring as best we can." );
-                }
+                log.info( "Configure called after the manager has been configured.  "
+                        + "Force reconfiguration is true. Reconfiguring as best we can." );
             }
         }
         if ( useSystemProperties )
@@ -430,10 +418,7 @@ public class CompositeCacheManager
         // set the props value and then configure the ThreadPoolManager
         ThreadPoolManager.setProps( properties );
         ThreadPoolManager poolMgr = ThreadPoolManager.getInstance();
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "ThreadPoolManager = " + poolMgr );
-        }
+        log.debug( "ThreadPoolManager = {0}", poolMgr);
 
         // configure the cache
         CompositeCacheConfigurator configurator = newConfigurator();
@@ -444,19 +429,19 @@ public class CompositeCacheManager
         this.defaultAuxValues = OptionConverter.findAndSubst( CompositeCacheManager.DEFAULT_REGION,
                 properties );
 
-        log.info( "Setting default auxiliaries to " + this.defaultAuxValues );
+        log.info( "Setting default auxiliaries to \"{0}\"", this.defaultAuxValues );
 
         // set default cache attr
         this.defaultCacheAttr = configurator.parseCompositeCacheAttributes( properties, "",
                 new CompositeCacheAttributes(), DEFAULT_REGION );
 
-        log.info( "setting defaultCompositeCacheAttributes to " + this.defaultCacheAttr );
+        log.info( "setting defaultCompositeCacheAttributes to {0}", this.defaultCacheAttr );
 
         // set default element attr
         this.defaultElementAttr = configurator.parseElementAttributes( properties, "",
                 new ElementAttributes(), DEFAULT_REGION );
 
-        log.info( "setting defaultElementAttributes to " + this.defaultElementAttr );
+        log.info( "setting defaultElementAttributes to {0}", this.defaultElementAttr );
 
         // set up system caches to be used by non system caches
         // need to make sure there is no circularity of reference
@@ -466,10 +451,7 @@ public class CompositeCacheManager
         configurator.parseRegions( properties, this );
 
         long end = System.currentTimeMillis();
-        if ( log.isInfoEnabled() )
-        {
-            log.info( "Finished configuration in " + ( end - start ) + " ms." );
-        }
+        log.info( "Finished configuration in {0} ms.", end - start);
 
         isConfigured = true;
     }
@@ -560,10 +542,7 @@ public class CompositeCacheManager
     @SuppressWarnings("unchecked") // Need to cast because of common map for all caches
     public <K, V> CompositeCache<K, V>  getCache( ICompositeCacheAttributes cattr, IElementAttributes attr )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "attr = " + attr );
-        }
+        log.debug( "attr = {0}", attr );
 
         CompositeCache<K, V> cache = (CompositeCache<K, V>) caches.computeIfAbsent(cattr.getCacheName(),
                 cacheName -> {
@@ -691,17 +670,12 @@ public class CompositeCacheManager
             // Wait until called by the last client
             if ( clients.decrementAndGet() > 0 )
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "Release called, but " + clients + " remain" );
-                }
+                log.debug( "Release called, but {0} remain", clients);
                 return;
             }
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Last client called release. There are " + caches.size() + " caches which will be disposed" );
-            }
+            log.debug( "Last client called release. There are {0} caches which will be disposed",
+                    () -> caches.size());
 
             for (ICache<?, ?> c : caches.values() )
             {
@@ -869,7 +843,7 @@ public class CompositeCacheManager
     	}
     	else
     	{
-    		log.warn("Shutdown observer added twice " + observer);
+    		log.warn("Shutdown observer added twice {0}", observer);
     	}
     }
 
@@ -917,28 +891,4 @@ public class CompositeCacheManager
         }
         jmxName = name;
     }
-
-    /**
-     * Called on shutdown. This gives use a chance to store the keys and to optimize even if the
-     * cache manager's shutdown method was not called manually.
-     */
-    class ShutdownHook
-        extends Thread
-    {
-        /**
-         * This will persist the keys on shutdown.
-         * <p>
-         * @see java.lang.Thread#run()
-         */
-        @SuppressWarnings("synthetic-access")
-        @Override
-        public void run()
-        {
-            if ( isInitialized() )
-            {
-                log.info( "Shutdown hook activated.  Shutdown was not called.  Shutting down JCS." );
-                shutDown();
-            }
-        }
-    }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/event/ElementEventQueue.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/event/ElementEventQueue.java
index 44ab573..d86843f 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/event/ElementEventQueue.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/control/event/ElementEventQueue.java
@@ -25,11 +25,11 @@ import java.util.concurrent.ExecutorService;
 import org.apache.commons.jcs.engine.control.event.behavior.IElementEvent;
 import org.apache.commons.jcs.engine.control.event.behavior.IElementEventHandler;
 import org.apache.commons.jcs.engine.control.event.behavior.IElementEventQueue;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.threadpool.PoolConfiguration;
 import org.apache.commons.jcs.utils.threadpool.PoolConfiguration.WhenBlockedPolicy;
 import org.apache.commons.jcs.utils.threadpool.ThreadPoolManager;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * An event queue is used to propagate ordered cache events to one and only one target listener.
@@ -40,7 +40,7 @@ public class ElementEventQueue
     private static final String THREAD_PREFIX = "JCS-ElementEventQueue-";
 
     /** The logger */
-    private static final Log log = LogFactory.getLog( ElementEventQueue.class );
+    private static final Log log = LogManager.getLog( ElementEventQueue.class );
 
     /** shutdown or not */
     private boolean destroyed = false;
@@ -56,10 +56,7 @@ public class ElementEventQueue
         queueProcessor = ThreadPoolManager.getInstance().createPool(
         		new PoolConfiguration(false, 0, 1, 1, 0, WhenBlockedPolicy.RUN, 1), THREAD_PREFIX);
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Constructed: " + this );
-        }
+        log.debug( "Constructed: {0}", this );
     }
 
     /**
@@ -77,10 +74,7 @@ public class ElementEventQueue
             queueProcessor.shutdownNow();
             queueProcessor = null;
 
-            if ( log.isInfoEnabled() )
-            {
-                log.info( "Element event queue destroyed: " + this );
-            }
+            log.info( "Element event queue destroyed: {0}", this );
         }
     }
 
@@ -95,23 +89,17 @@ public class ElementEventQueue
         throws IOException
     {
 
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Adding Event Handler to QUEUE, !destroyed = " + !destroyed );
-        }
+        log.debug( "Adding Event Handler to QUEUE, !destroyed = {0}", !destroyed );
 
         if (destroyed)
         {
-            log.warn("Event submitted to disposed element event queue " + event);
+            log.warn("Event submitted to disposed element event queue {0}", event);
         }
         else
         {
             ElementEventRunner runner = new ElementEventRunner( hand, event );
 
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "runner = " + runner );
-            }
+            log.debug( "runner = {0}", runner );
 
             queueProcessor.execute(runner);
         }
@@ -140,7 +128,7 @@ public class ElementEventQueue
             catch ( IOException e )
             {
                 // Too bad. The handler has problems.
-                log.warn( "Giving up element event handling " + ElementEventQueue.this, e );
+                log.warn( "Giving up element event handling {0}", ElementEventQueue.this, e );
             }
         }
 
@@ -176,10 +164,7 @@ public class ElementEventQueue
         ElementEventRunner( IElementEventHandler hand, IElementEvent<?> event )
             throws IOException
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Constructing " + this );
-            }
+            log.debug( "Constructing {0}", this );
             this.hand = hand;
             this.event = event;
         }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/logging/CacheEventLoggerDebugLogger.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/logging/CacheEventLoggerDebugLogger.java
index 4f67cb0..4a2d56b 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/logging/CacheEventLoggerDebugLogger.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/logging/CacheEventLoggerDebugLogger.java
@@ -21,11 +21,11 @@ package org.apache.commons.jcs.engine.logging;
 
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEvent;
 import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
- * This implementation simple logs to a commons logger at debug level, for all events. It's mainly
+ * This implementation simple logs to a logger at debug level, for all events. It's mainly
  * for testing. It isn't very useful otherwise.
  */
 public class CacheEventLoggerDebugLogger
@@ -35,7 +35,7 @@ public class CacheEventLoggerDebugLogger
     private String logCategoryName = CacheEventLoggerDebugLogger.class.getName();
 
     /** The logger. This is recreated on set logCategoryName */
-    private Log log = LogFactory.getLog( logCategoryName );
+    private Log log = LogManager.getLog( logCategoryName );
 
     /**
      * @param source
@@ -67,10 +67,7 @@ public class CacheEventLoggerDebugLogger
     @Override
     public void logApplicationEvent( String source, String eventName, String optionalDetails )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( source + " | " + eventName + " | " + optionalDetails );
-        }
+        log.debug( "{0} | {1} | {2}", source, eventName, optionalDetails );
     }
 
     /**
@@ -81,10 +78,7 @@ public class CacheEventLoggerDebugLogger
     @Override
     public void logError( String source, String eventName, String errorMessage )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( source + " | " + eventName + " | " + errorMessage );
-        }
+        log.debug( "{0} | {1} | {2}", source, eventName, errorMessage );
     }
 
     /**
@@ -93,10 +87,7 @@ public class CacheEventLoggerDebugLogger
     @Override
     public <T> void logICacheEvent( ICacheEvent<T> event )
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( event );
-        }
+        log.debug( event );
     }
 
     /**
@@ -107,7 +98,7 @@ public class CacheEventLoggerDebugLogger
         if ( logCategoryName != null && !logCategoryName.equals( this.logCategoryName ) )
         {
             this.logCategoryName = logCategoryName;
-            log = LogFactory.getLog( logCategoryName );
+            log = LogManager.getLog( logCategoryName );
         }
     }
 }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java
index 222f504..c28103b 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractDoubleLinkedListMemoryCache.java
@@ -31,9 +31,9 @@ import org.apache.commons.jcs.engine.memory.util.MemoryElementDescriptor;
 import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 import org.apache.commons.jcs.utils.struct.DoubleLinkedList;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * This class contains methods that are common to memory caches using the double linked list, such
@@ -46,7 +46,7 @@ import org.apache.commons.logging.LogFactory;
 public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends AbstractMemoryCache<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog(AbstractDoubleLinkedListMemoryCache.class);
+    private static final Log log = LogManager.getLog(AbstractDoubleLinkedListMemoryCache.class);
 
     /** thread-safe double linked list for lru */
     protected DoubleLinkedList<MemoryElementDescriptor<K, V>> list; // TODO privatise
@@ -62,7 +62,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
     {
         super.initialize(hub);
         list = new DoubleLinkedList<>();
-        log.info("initialized MemoryCache for " + getCacheName());
+        log.info("initialized MemoryCache for {0}", () -> getCacheName());
     }
 
     /**
@@ -145,19 +145,15 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
             return;
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("In memory limit reached, spooling");
-        }
+        log.debug("In memory limit reached, spooling");
 
         // Write the last 'chunkSize' items to disk.
         int chunkSizeCorrected = Math.min(size, chunkSize);
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("About to spool to disk cache, map size: " + size + ", max objects: "
-                + this.getCacheAttributes().getMaxObjects() + ", maximum items to spool: " + chunkSizeCorrected);
-        }
+        log.debug("About to spool to disk cache, map size: {0}, max objects: {1}, "
+                + "maximum items to spool: {2}", () -> size,
+                () -> this.getCacheAttributes().getMaxObjects(),
+                () -> chunkSizeCorrected);
 
         // The spool will put them in a disk event queue, so there is no
         // need to pre-queue the queuing. This would be a bit wasteful
@@ -179,7 +175,8 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
             // where there is none.
             if (log.isDebugEnabled() && map.size() != list.size())
             {
-                log.debug("update: After spool, size mismatch: map.size() = " + map.size() + ", linked list size = " + list.size());
+                log.debug("update: After spool, size mismatch: map.size() = {0}, "
+                        + "linked list size = {1}", map.size(), list.size());
             }
         }
         finally
@@ -187,10 +184,8 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
             lock.unlock();
         }
 
-        if (log.isDebugEnabled())
-        {
-            log.debug("update: After spool map size: " + map.size() + " linked list size = " + list.size());
-        }
+        log.debug("update: After spool map size: {0} linked list size = {1}",
+                () -> map.size(), () -> list.size());
     }
 
     /**
@@ -250,9 +245,9 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
                 getCompositeCache().spoolToDisk(toSpool);
                 if (map.remove(toSpool.getKey()) == null)
                 {
-                    log.warn("update: remove failed for key: " + toSpool.getKey());
+                    log.warn("update: remove failed for key: {0}", toSpool.getKey());
 
-                    if (log.isDebugEnabled())
+                    if (log.isTraceEnabled())
                     {
                         verifyCache();
                     }
@@ -277,7 +272,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
     {
         ICacheElement<K, V> ce = super.get(key);
 
-        if (log.isDebugEnabled())
+        if (log.isTraceEnabled())
         {
             verifyCache();
         }
@@ -343,7 +338,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
         {
             MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<>(ce);
             list.addFirst(me);
-            if ( log.isDebugEnabled() )
+            if ( log.isTraceEnabled() )
             {
                 verifyCache(ce.getKey());
             }
@@ -370,7 +365,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
         {
             MemoryElementDescriptor<K, V> me = new MemoryElementDescriptor<>(ce);
             list.addLast(me);
-            if ( log.isDebugEnabled() )
+            if ( log.isTraceEnabled() )
             {
                 verifyCache(ce.getKey());
             }
@@ -391,10 +386,11 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
     // No generics for public fields
     private void dumpCacheEntries()
     {
-        log.debug("dumpingCacheEntries");
+        log.trace("dumpingCacheEntries");
         for (MemoryElementDescriptor<K, V> me = list.getFirst(); me != null; me = (MemoryElementDescriptor<K, V>) me.next)
         {
-            log.debug("dumpCacheEntries> key=" + me.getCacheElement().getKey() + ", val=" + me.getCacheElement().getVal());
+            log.trace("dumpCacheEntries> key={0}, val={1}",
+                    me.getCacheElement().getKey(), me.getCacheElement().getVal());
         }
     }
 
@@ -407,52 +403,56 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
     private void verifyCache()
     {
         boolean found = false;
-        log.debug("verifycache[" + getCacheName() + "]: mapContains " + map.size() + " elements, linked list contains "
-            + list.size() + " elements");
-        log.debug("verifycache: checking linked list by key ");
+        log.trace("verifycache[{0}]: map contains {1} elements, linked list "
+                + "contains {2} elements", getCacheName(), map.size(),
+                list.size());
+        log.trace("verifycache: checking linked list by key ");
         for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next)
         {
             K key = li.getCacheElement().getKey();
             if (!map.containsKey(key))
             {
-                log.error("verifycache[" + getCacheName() + "]: map does not contain key : " + key);
-                log.error("key class=" + key.getClass());
-                log.error("key hashcode=" + key.hashCode());
-                log.error("key toString=" + key.toString());
+                log.error("verifycache[{0}]: map does not contain key : {1}",
+                        getCacheName(), key);
+                log.error("key class={0}", key.getClass());
+                log.error("key hashcode={0}", key.hashCode());
+                log.error("key toString={0}", key.toString());
                 if (key instanceof GroupAttrName)
                 {
                     GroupAttrName<?> name = (GroupAttrName<?>) key;
-                    log.error("GroupID hashcode=" + name.groupId.hashCode());
-                    log.error("GroupID.class=" + name.groupId.getClass());
-                    log.error("AttrName hashcode=" + name.attrName.hashCode());
-                    log.error("AttrName.class=" + name.attrName.getClass());
+                    log.error("GroupID hashcode={0}", name.groupId.hashCode());
+                    log.error("GroupID.class={0}", name.groupId.getClass());
+                    log.error("AttrName hashcode={0}", name.attrName.hashCode());
+                    log.error("AttrName.class={0}", name.attrName.getClass());
                 }
                 dumpMap();
             }
             else if (map.get(key) == null)
             {
-                log.error("verifycache[" + getCacheName() + "]: linked list retrieval returned null for key: " + key);
+                log.error("verifycache[{0}]: linked list retrieval returned "
+                        + "null for key: {1}", getCacheName(), key);
             }
         }
 
-        log.debug("verifycache: checking linked list by value ");
-        for (MemoryElementDescriptor<K, V> li3 = list.getFirst(); li3 != null; li3 = (MemoryElementDescriptor<K, V>) li3.next)
+        log.trace("verifycache: checking linked list by value ");
+        for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next)
         {
-            if (map.containsValue(li3) == false)
+            if (!map.containsValue(li))
             {
-                log.error("verifycache[" + getCacheName() + "]: map does not contain value : " + li3);
+                log.error("verifycache[{0}]: map does not contain value: {1}",
+                        getCacheName(), li);
                 dumpMap();
             }
         }
 
-        log.debug("verifycache: checking via keysets!");
+        log.trace("verifycache: checking via keysets!");
         for (Object val : map.keySet())
         {
             found = false;
 
-            for (MemoryElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (MemoryElementDescriptor<K, V>) li2.next)
+            for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next)
             {
-                if (val.equals(li2.getCacheElement().getKey()))
+                if (val.equals(li.getCacheElement().getKey()))
                 {
                     found = true;
                     break;
@@ -460,7 +460,8 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
             }
             if (!found)
             {
-                log.error("verifycache[" + getCacheName() + "]: key not found in list : " + val);
+                log.error("verifycache[{0}]: key not found in list : {1}",
+                        getCacheName(), val);
                 dumpCacheEntries();
                 if (map.containsKey(val))
                 {
@@ -492,13 +493,14 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
             if (li.getCacheElement().getKey() == key)
             {
                 found = true;
-                log.debug("verifycache(key) key match: " + key);
+                log.trace("verifycache(key) key match: {0}", key);
                 break;
             }
         }
         if (!found)
         {
-            log.error("verifycache(key)[" + getCacheName() + "], couldn't find key! : " + key);
+            log.error("verifycache(key)[{0}], couldn't find key! : {1}",
+                    getCacheName(), key);
         }
     }
 
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java
index b984756..0c63fd0 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/AbstractMemoryCache.java
@@ -42,8 +42,8 @@ import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.Stats;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This base includes some common code for memory caches.
@@ -52,7 +52,7 @@ public abstract class AbstractMemoryCache<K, V>
     implements IMemoryCache<K, V>
 {
     /** Log instance */
-    private static final Log log = LogFactory.getLog( AbstractMemoryCache.class );
+    private static final Log log = LogManager.getLog( AbstractMemoryCache.class );
 
     /** Cache Attributes.  Regions settings. */
     private ICompositeCacheAttributes cacheAttributes;
@@ -155,16 +155,15 @@ public abstract class AbstractMemoryCache<K, V>
         MemoryElementDescriptor<K, V> me = map.get( key );
         if ( me != null )
         {
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( getCacheName() + ": MemoryCache quiet hit for " + key );
-            }
+            log.debug( "{0}: MemoryCache quiet hit for {1}",
+                    () -> getCacheName(), () -> key );
 
             ce = me.getCacheElement();
         }
-        else if ( log.isDebugEnabled() )
+        else
         {
-            log.debug( getCacheName() + ": MemoryCache quiet miss for " + key );
+            log.debug( "{0}: MemoryCache quiet miss for {1}",
+                    () -> getCacheName(), () -> key );
         }
 
         return ce;
@@ -285,11 +284,11 @@ public abstract class AbstractMemoryCache<K, V>
      */
     public void dumpMap()
     {
-        if (log.isDebugEnabled())
+        if (log.isTraceEnabled())
         {
-            log.debug("dumpingMap");
+            log.trace("dumpingMap");
             map.entrySet().forEach(e ->
-                log.debug("dumpMap> key=" + e.getKey() + ", val=" +
+                log.trace("dumpMap> key={0}, val={1}", e.getKey(),
                         e.getValue().getCacheElement().getVal()));
         }
     }
@@ -411,10 +410,7 @@ public abstract class AbstractMemoryCache<K, V>
     @Override
     public boolean remove(K key) throws IOException
     {
-        if (log.isDebugEnabled())
-        {
-            log.debug("removing item for key: " + key);
-        }
+        log.debug("removing item for key: {0}", key);
 
         boolean removed = false;
 
@@ -473,10 +469,8 @@ public abstract class AbstractMemoryCache<K, V>
     {
         ICacheElement<K, V> ce = null;
 
-        if (log.isDebugEnabled())
-        {
-            log.debug(getCacheName() + ": getting item for key " + key);
-        }
+        log.debug("{0}: getting item for key {1}", () -> getCacheName(),
+                () -> key);
 
         MemoryElementDescriptor<K, V> me = map.get(key);
 
@@ -495,19 +489,15 @@ public abstract class AbstractMemoryCache<K, V>
                 lock.unlock();
             }
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(getCacheName() + ": MemoryCache hit for " + key);
-            }
+            log.debug("{0}: MemoryCache hit for {1}", () -> getCacheName(),
+                    () -> key);
         }
         else
         {
             missCnt.incrementAndGet();
 
-            if (log.isDebugEnabled())
-            {
-                log.debug(getCacheName() + ": MemoryCache miss for " + key);
-            }
+            log.debug("{0}: MemoryCache miss for {1}", () -> getCacheName(),
+                    () -> key);
         }
 
         return ce;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java
index 4221b99..51f8df5 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/lru/LHMLRUMemoryCache.java
@@ -28,8 +28,8 @@ import org.apache.commons.jcs.engine.control.CompositeCache;
 import org.apache.commons.jcs.engine.memory.AbstractMemoryCache;
 import org.apache.commons.jcs.engine.memory.util.MemoryElementDescriptor;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * This is a test memory manager using the jdk1.4 LinkedHashMap.
@@ -38,7 +38,7 @@ public class LHMLRUMemoryCache<K, V>
     extends AbstractMemoryCache<K, V>
 {
     /** The Logger. */
-    private static final Log log = LogFactory.getLog( LRUMemoryCache.class );
+    private static final Log log = LogManager.getLog( LRUMemoryCache.class );
 
     /**
      * For post reflection creation initialization
@@ -49,7 +49,7 @@ public class LHMLRUMemoryCache<K, V>
     public void initialize( CompositeCache<K, V> hub )
     {
         super.initialize( hub );
-        log.info( "initialized LHMLRUMemoryCache for " + getCacheName() );
+        log.info( "initialized LHMLRUMemoryCache for {0}", () -> getCacheName() );
     }
 
     /**
@@ -189,18 +189,12 @@ public class LHMLRUMemoryCache<K, V>
             }
             else
             {
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "LHMLRU max size: " + getCacheAttributes().getMaxObjects()
-                        + ".  Spooling element, key: " + element.getKey() );
-                }
+                log.debug( "LHMLRU max size: {0}. Spooling element, key: {1}",
+                        () -> getCacheAttributes().getMaxObjects(), () -> element.getKey() );
 
                 waterfal( element );
 
-                if ( log.isDebugEnabled() )
-                {
-                    log.debug( "LHMLRU size: " + map.size() );
-                }
+                log.debug( "LHMLRU size: {0}", () -> map.size() );
             }
             return true;
         }
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/shrinking/ShrinkerThread.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/shrinking/ShrinkerThread.java
index 70829a5..0cbe492 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/shrinking/ShrinkerThread.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/shrinking/ShrinkerThread.java
@@ -26,8 +26,8 @@ import org.apache.commons.jcs.engine.behavior.IElementAttributes;
 import org.apache.commons.jcs.engine.control.CompositeCache;
 import org.apache.commons.jcs.engine.control.event.behavior.ElementEventType;
 import org.apache.commons.jcs.engine.memory.behavior.IMemoryCache;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * A background memory shrinker. Memory problems and concurrent modification exception caused by
@@ -38,7 +38,7 @@ public class ShrinkerThread<K, V>
     implements Runnable
 {
     /** The logger */
-    private static final Log log = LogFactory.getLog( ShrinkerThread.class );
+    private static final Log log = LogManager.getLog( ShrinkerThread.class );
 
     /** The CompositeCache instance which this shrinker is watching */
     private final CompositeCache<K, V> cache;
@@ -108,10 +108,7 @@ public class ShrinkerThread<K, V>
      */
     protected void shrink()
     {
-        if ( log.isDebugEnabled() )
-        {
-            log.debug( "Shrinking memory cache for: " + this.cache.getCacheName() );
-        }
+        log.debug( "Shrinking memory cache for: {0}", () -> this.cache.getCacheName() );
 
         IMemoryCache<K, V> memCache = cache.getMemoryCache();
 
@@ -119,26 +116,20 @@ public class ShrinkerThread<K, V>
         {
             Set<K> keys = memCache.getKeySet();
             int size = keys.size();
-            if ( log.isDebugEnabled() )
-            {
-                log.debug( "Keys size: " + size );
-            }
-
-            ICacheElement<K, V> cacheElement;
-            IElementAttributes attributes;
+            log.debug( "Keys size: {0}", size );
 
             int spoolCount = 0;
 
             for (K key : keys)
             {
-                cacheElement = memCache.getQuiet( key );
+                final ICacheElement<K, V> cacheElement = memCache.getQuiet( key );
 
                 if ( cacheElement == null )
                 {
                     continue;
                 }
 
-                attributes = cacheElement.getElementAttributes();
+                IElementAttributes attributes = cacheElement.getElementAttributes();
 
                 boolean remove = false;
 
@@ -146,7 +137,7 @@ public class ShrinkerThread<K, V>
 
                 // If the element is not eternal, check if it should be
                 // removed and remove it if so.
-                if ( !cacheElement.getElementAttributes().getIsEternal() )
+                if ( !attributes.getIsEternal() )
                 {
                     remove = cache.isExpired( cacheElement, now,
                             ElementEventType.EXCEEDED_MAXLIFE_BACKGROUND,
@@ -154,7 +145,7 @@ public class ShrinkerThread<K, V>
 
                     if ( remove )
                     {
-                        memCache.remove( cacheElement.getKey() );
+                        memCache.remove( key );
                     }
                 }
 
@@ -169,10 +160,7 @@ public class ShrinkerThread<K, V>
 
                         if ( lastAccessTime + maxMemoryIdleTime < now )
                         {
-                            if ( log.isDebugEnabled() )
-                            {
-                                log.debug( "Exceeded memory idle time: " + cacheElement.getKey() );
-                            }
+                            log.debug( "Exceeded memory idle time: {0}", key );
 
                             // Shouldn't we ensure that the element is
                             // spooled before removing it from memory?
@@ -182,21 +170,14 @@ public class ShrinkerThread<K, V>
 
                             spoolCount++;
 
-                            memCache.remove( cacheElement.getKey() );
-
+                            memCache.remove( key );
                             memCache.waterfal( cacheElement );
-
-                            key = null;
-                            cacheElement = null;
                         }
                     }
                     else
                     {
-                        if ( log.isDebugEnabled() )
-                        {
-                            log.debug( "spoolCount = '" + spoolCount + "'; " + "maxSpoolPerRun = '" + maxSpoolPerRun
-                                + "'" );
-                        }
+                        log.debug( "spoolCount = \"{0}\"; maxSpoolPerRun = \"{1}\"",
+                                spoolCount, maxSpoolPerRun );
 
                         // stop processing if limit has been reached.
                         if ( spoolLimit && spoolCount >= this.maxSpoolPerRun )
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/soft/SoftReferenceMemoryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/soft/SoftReferenceMemoryCache.java
index f471995..6dbb0b3 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/soft/SoftReferenceMemoryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/engine/memory/soft/SoftReferenceMemoryCache.java
@@ -38,8 +38,8 @@ import org.apache.commons.jcs.engine.memory.util.SoftReferenceElementDescriptor;
 import org.apache.commons.jcs.engine.stats.StatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
 import org.apache.commons.jcs.engine.stats.behavior.IStats;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.commons.jcs.log.Log;
+import org.apache.commons.jcs.log.LogManager;
 
 /**
  * A JCS IMemoryCache that has {@link SoftReference} to all its values.
@@ -54,7 +54,7 @@ import org.apache.commons.logging.LogFactory;
 public class SoftReferenceMemoryCache<K, V> extends AbstractMemoryCache<K, V>
 {
     /** The logger. */
-    private static final Log log = LogFactory.getLog(SoftReferenceMemoryCache.class);
+    private static final Log log = LogManager.getLog(SoftReferenceMemoryCache.class);
 
     /**
      * Strong references to the maxObjects number of newest objects.
@@ -75,7 +75,8 @@ public class SoftReferenceMemoryCache<K, V> extends AbstractMemoryCache<K, V>
     {
         super.initialize( hub );
         strongReferences = new LinkedBlockingQueue<>();
-        log.info( "initialized Soft Reference Memory Cache for " + getCacheName() );
+        log.info( "initialized Soft Reference Memory Cache for {0}",
+                () -> getCacheName() );
     }
 
     /**
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogAdapter.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogAdapter.java
new file mode 100644
index 0000000..fba069f
--- /dev/null
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogAdapter.java
@@ -0,0 +1,574 @@
+package org.apache.commons.jcs.log;
+
+import java.util.function.Supplier;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/*
+ * 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.
+ */
+
+/**
+ * This is a wrapper around the <code>java.util.logging.Logger</code> implementing our own
+ * <code>Log</code> interface.
+ * <p>
+ * This is the mapping of the log levels
+ * </p>
+ * <pre>
+ * Java Level   Log Level
+ * SEVERE       FATAL
+ * SEVERE       ERROR
+ * WARNING      WARN
+ * INFO         INFO
+ * FINE         DEBUG
+ * FINER        TRACE
+ * </pre>
+ */
+public class JulLogAdapter implements Log
+{
+    private Logger logger;
+
+    /**
+     * Construct a JUL Logger wrapper
+     *
+     * @param logger the JUL Logger
+     */
+    public JulLogAdapter(Logger logger)
+    {
+        super();
+        this.logger = logger;
+    }
+
+    private void log(Level level, String message)
+    {
+        if (logger.isLoggable(level))
+        {
+            logger.logp(level, logger.getName(), "", message);
+        }
+    }
+
+    private void log(Level level, Object message)
+    {
+        if (logger.isLoggable(level))
+        {
+            if (message instanceof Throwable)
+            {
+                logger.logp(level, logger.getName(), "", "Exception:", (Throwable) message);
+            }
+            else
+            {
+                logger.logp(level, logger.getName(), "",
+                        message == null ? null : message.toString());
+            }
+        }
+    }
+
+    private void log(Level level, String message, Throwable t)
+    {
+        if (logger.isLoggable(level))
+        {
+            logger.logp(level, logger.getName(), "", message, t);
+        }
+    }
+
+    private void log(Level level, String message, Object... params)
+    {
+        if (logger.isLoggable(level))
+        {
+            MessageFormatter formatter = new MessageFormatter(message, params);
+            if (formatter.hasThrowable())
+            {
+                logger.logp(level, logger.getName(), "",
+                        formatter.getFormattedMessage(), formatter.getThrowable());
+            }
+            else
+            {
+                logger.logp(level, logger.getName(), "",
+                        formatter.getFormattedMessage());
+            }
+        }
+    }
+
+    private void log(Level level, String message, Supplier<?>... paramSuppliers)
+    {
+        if (logger.isLoggable(level))
+        {
+            MessageFormatter formatter = new MessageFormatter(message, paramSuppliers);
+            if (formatter.hasThrowable())
+            {
+                logger.logp(level, logger.getName(), "",
+                        formatter.getFormattedMessage(), formatter.getThrowable());
+            }
+            else
+            {
+                logger.logp(level, logger.getName(), "",
+                        formatter.getFormattedMessage());
+            }
+        }
+    }
+
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void debug(String message)
+    {
+        log(Level.FINE, message);
+    }
+
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void debug(Object message)
+    {
+        log(Level.FINE, message);
+    }
+
+    /**
+     * Logs a message with parameters at the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     * @see #getMessageFactory()
+     */
+    @Override
+    public void debug(String message, Object... params)
+    {
+        log(Level.FINE, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called,
+     *        produce the desired log message parameters.
+     */
+    @Override
+    public void debug(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.FINE, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the DEBUG level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void debug(String message, Throwable t)
+    {
+        log(Level.FINE, message, t);
+    }
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void error(String message)
+    {
+        log(Level.SEVERE, message);
+    }
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void error(Object message)
+    {
+        log(Level.SEVERE, message);
+    }
+
+    /**
+     * Logs a message with parameters at the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void error(String message, Object... params)
+    {
+        log(Level.SEVERE, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     * @since 2.4
+     */
+    @Override
+    public void error(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.SEVERE, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the ERROR level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void error(String message, Throwable t)
+    {
+        log(Level.SEVERE, message, t);
+    }
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void fatal(String message)
+    {
+        log(Level.SEVERE, message);
+    }
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void fatal(Object message)
+    {
+        log(Level.SEVERE, message);
+    }
+
+    /**
+     * Logs a message with parameters at the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void fatal(String message, Object... params)
+    {
+        log(Level.SEVERE, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce the
+     *        desired log message parameters.
+     */
+    @Override
+    public void fatal(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.SEVERE, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the FATAL level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void fatal(String message, Throwable t)
+    {
+        log(Level.SEVERE, message, t);
+    }
+
+    /**
+     * Gets the logger name.
+     *
+     * @return the logger name.
+     */
+    @Override
+    public String getName()
+    {
+        return logger.getName();
+    }
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void info(String message)
+    {
+        log(Level.INFO, message);
+    }
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void info(Object message)
+    {
+        log(Level.INFO, message);
+    }
+
+    /**
+     * Logs a message with parameters at the INFO level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void info(String message, Object... params)
+    {
+        log(Level.INFO, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the INFO level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void info(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.INFO, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the INFO level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void info(String message, Throwable t)
+    {
+        log(Level.INFO, message, t);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the DEBUG Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level DEBUG, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isDebugEnabled()
+    {
+        return logger.isLoggable(Level.FINE);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the ERROR Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level ERROR, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isErrorEnabled()
+    {
+        return logger.isLoggable(Level.SEVERE);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the FATAL Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level FATAL, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isFatalEnabled()
+    {
+        return logger.isLoggable(Level.SEVERE);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the INFO Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level INFO, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isInfoEnabled()
+    {
+        return logger.isLoggable(Level.INFO);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the TRACE level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level TRACE, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isTraceEnabled()
+    {
+        return logger.isLoggable(Level.FINER);
+    }
+
+    /**
+     * Checks whether this Logger is enabled for the WARN Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level WARN, {@code false}
+     *         otherwise.
+     */
+    @Override
+    public boolean isWarnEnabled()
+    {
+        return logger.isLoggable(Level.WARNING);
+    }
+
+    /**
+     * Logs a message object with the TRACE level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void trace(String message)
+    {
+        log(Level.FINER, message);
+    }
+
+    /**
+     * Logs a message object with the TRACE level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void trace(Object message)
+    {
+        log(Level.FINER, message);
+    }
+
+    /**
+     * Logs a message with parameters at the TRACE level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void trace(String message, Object... params)
+    {
+        log(Level.FINER, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the TRACE level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void trace(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.FINER, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the TRACE level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     * @see #debug(String)
+     */
+    @Override
+    public void trace(String message, Throwable t)
+    {
+        log(Level.FINER, message, t);
+    }
+
+    /**
+     * Logs a message object with the WARN level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void warn(String message)
+    {
+        log(Level.WARNING, message);
+    }
+
+    /**
+     * Logs a message object with the WARN level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void warn(Object message)
+    {
+        log(Level.WARNING, message);
+    }
+
+    /**
+     * Logs a message with parameters at the WARN level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void warn(String message, Object... params)
+    {
+        log(Level.WARNING, message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the WARN level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void warn(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.WARNING, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the WARN level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void warn(String message, Throwable t)
+    {
+        log(Level.WARNING, message, t);
+    }
+}
\ No newline at end of file
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogFactory.java
new file mode 100644
index 0000000..c1e21eb
--- /dev/null
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/JulLogFactory.java
@@ -0,0 +1,76 @@
+package org.apache.commons.jcs.log;
+
+import java.util.logging.Logger;
+
+/*
+ * 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.
+ */
+
+/**
+ * This is a SPI factory implementation for java.util.logging
+ */
+public class JulLogFactory implements LogFactory
+{
+    /**
+     * Return the name of the Log subsystem managed by this factory
+     *
+     * @return the name of the log subsystem
+     */
+    @Override
+    public String getName()
+    {
+        return "jul";
+    }
+
+    /**
+     * Shutdown the logging system if the logging system supports it.
+     */
+    @Override
+    public void shutdown()
+    {
+        // do nothing
+    }
+
+    /**
+     * Returns a Log using the fully qualified name of the Class as the Log
+     * name.
+     *
+     * @param clazz
+     *            The Class whose name should be used as the Log name.
+     *
+     * @return The Log.
+     */
+    @Override
+    public Log getLog(final Class<?> clazz)
+    {
+        Logger logger = Logger.getLogger(clazz.getName());
+        return new JulLogAdapter(logger);
+    }
+
+    /**
+     * Returns a Log with the specified name.
+     *
+     * @param name
+     *            The logger name.
+     * @return The Log.
+     */
+    @Override
+    public Log getLog(final String name)
+    {
+        Logger logger = Logger.getLogger(name);
+        return new JulLogAdapter(logger);
+    }
+}
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log.java
new file mode 100644
index 0000000..b548db4
--- /dev/null
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log.java
@@ -0,0 +1,343 @@
+package org.apache.commons.jcs.log;
+
+/*
+ * 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.
+ */
+
+import java.util.function.Supplier;
+
+/**
+ * This is a borrowed and stripped-down version of the log4j2 Logger interface.
+ * All logging operations, except configuration, are done through this interface.
+ *
+ * <p>
+ * The canonical way to obtain a Logger for a class is through {@link LogManager#getLog()}.
+ * Typically, each class should get its own Log named after its fully qualified class name
+ * </p>
+ *
+ * <pre>
+ * public class MyClass {
+ *     private static final Log log = LogManager.getLog(MyClass.class);
+ *     // ...
+ * }
+ * </pre>
+ */
+public interface Log
+{
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message string to log.
+     */
+    void debug(String message);
+
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message object to log.
+     */
+    void debug(Object message);
+
+    /**
+     * Logs a message with parameters at the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    void debug(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void debug(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the DEBUG level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    void debug(String message, Throwable t);
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message string to log.
+     */
+    void error(String message);
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message object to log.
+     */
+    void error(Object message);
+
+    /**
+     * Logs a message with parameters at the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    void error(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void error(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the ERROR level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    void error(String message, Throwable t);
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message string to log.
+     */
+    void fatal(String message);
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message object to log.
+     */
+    void fatal(Object message);
+
+    /**
+     * Logs a message with parameters at the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    void fatal(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void fatal(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the FATAL level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    void fatal(String message, Throwable t);
+
+    /**
+     * Gets the logger name.
+     *
+     * @return the logger name.
+     */
+    String getName();
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message string to log.
+     */
+    void info(String message);
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message object to log.
+     */
+    void info(Object message);
+
+    /**
+     * Logs a message with parameters at the INFO level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    void info(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the INFO level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void info(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the INFO level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    void info(String message, Throwable t);
+
+    /**
+     * Checks whether this Logger is enabled for the DEBUG Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level DEBUG, {@code false}
+     *         otherwise.
+     */
+    boolean isDebugEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the ERROR Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level ERROR, {@code false}
+     *         otherwise.
+     */
+    boolean isErrorEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the FATAL Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level FATAL, {@code false}
+     *         otherwise.
+     */
+    boolean isFatalEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the INFO Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level INFO, {@code false}
+     *         otherwise.
+     */
+    boolean isInfoEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the TRACE level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level TRACE, {@code false}
+     *         otherwise.
+     */
+    boolean isTraceEnabled();
+
+    /**
+     * Checks whether this Logger is enabled for the WARN Level.
+     *
+     * @return boolean - {@code true} if this Logger is enabled for level WARN, {@code false}
+     *         otherwise.
+     */
+    boolean isWarnEnabled();
+
+    /**
+     * Logs a message object with the TRACE level.
+     *
+     * @param message the message string to log.
+     */
+    void trace(String message);
+
+    /**
+     * Logs a message object with the TRACE level.
+     *
+     * @param message the message object to log.
+     */
+    void trace(Object message);
+
+    /**
+     * Logs a message with parameters at the TRACE level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     * @see #getMessageFactory()
+     */
+    void trace(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the TRACE level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void trace(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the TRACE level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     * @see #debug(String)
+     */
+    void trace(String message, Throwable t);
+
+    /**
+     * Logs a message object with the WARN level.
+     *
+     * @param message the message string to log.
+     */
+    void warn(String message);
+
+    /**
+     * Logs a message object with the WARN level.
+     *
+     * @param message the message object to log.
+     */
+    void warn(Object message);
+
+    /**
+     * Logs a message with parameters at the WARN level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     * @see #getMessageFactory()
+     */
+    void warn(String message, Object... params);
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the WARN level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    void warn(String message, Supplier<?>... paramSuppliers);
+
+    /**
+     * Logs a message at the WARN level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    void warn(String message, Throwable t);
+}
\ No newline at end of file
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2Factory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2Factory.java
new file mode 100644
index 0000000..7c1ab3d
--- /dev/null
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2Factory.java
@@ -0,0 +1,83 @@
+package org.apache.commons.jcs.log;
+
+import org.apache.logging.log4j.Logger;
+
+/*
+ * 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.
+ */
+
+/**
+ * This is a SPI factory implementation for log4j2
+ */
+public class Log4j2Factory implements LogFactory
+{
+    /**
+     * Return the name of the Log subsystem managed by this factory
+     *
+     * @return the name of the log subsystem
+     */
+    @Override
+    public String getName()
+    {
+        return "log4j2";
+    }
+
+    /**
+     * Shutdown the logging system if the logging system supports it.
+     */
+    @Override
+    public void shutdown()
+    {
+        org.apache.logging.log4j.LogManager.shutdown();
+    }
+
+    /**
+     * Returns a Log using the fully qualified name of the Class as the Log
+     * name.
+     *
+     * @param clazz
+     *            The Class whose name should be used as the Log name. If null
+     *            it will default to the calling class.
+     * @return The Log.
+     * @throws UnsupportedOperationException
+     *             if {@code clazz} is {@code null} and the calling class cannot
+     *             be determined.
+     */
+    @Override
+    public Log getLog(final Class<?> clazz)
+    {
+        Logger logger = org.apache.logging.log4j.LogManager.getLogger(clazz);
+        return new Log4j2LogAdapter(logger);
+    }
+
+    /**
+     * Returns a Log with the specified name.
+     *
+     * @param name
+     *            The logger name. If null the name of the calling class will be
+     *            used.
+     * @return The Log.
+     * @throws UnsupportedOperationException
+     *             if {@code name} is {@code null} and the calling class cannot
+     *             be determined.
+     */
+    @Override
+    public Log getLog(final String name)
+    {
+        Logger logger = org.apache.logging.log4j.LogManager.getLogger(name);
+        return new Log4j2LogAdapter(logger);
+    }
+}
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2LogAdapter.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2LogAdapter.java
new file mode 100644
index 0000000..4c3fae2
--- /dev/null
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/log/Log4j2LogAdapter.java
@@ -0,0 +1,521 @@
+package org.apache.commons.jcs.log;
+
+/*
+ * 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.
+ */
+
+import java.util.function.Supplier;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * This is a wrapper around the <code>org.apache.logging.log4j.Logger</code> implementing our own
+ * <code>Log</code> interface.
+ */
+public class Log4j2LogAdapter implements Log
+{
+    private Logger logger;
+
+    /**
+     * Construct a Log4j Logger wrapper
+     *
+     * @param logger the log4j Logger
+     */
+    public Log4j2LogAdapter(Logger logger)
+    {
+        super();
+        this.logger = logger;
+    }
+
+    private void log(Level level, String message, Supplier<?>... paramSuppliers)
+    {
+        if (logger.isEnabled(level))
+        {
+            if (paramSuppliers == null)
+            {
+                logger.log(level, message);
+            }
+            else
+            {
+                switch (paramSuppliers.length)
+                {
+                    case 1: logger.log(level, message, paramSuppliers[0]);
+                            break;
+                    case 2: logger.log(level, message, paramSuppliers[0],
+                            paramSuppliers[1]);
+                            break;
+                    case 3: logger.log(level, message, paramSuppliers[0],
+                            paramSuppliers[1], paramSuppliers[2]);
+                            break;
+                    default: logger.log(level, message, paramSuppliers[0],
+                            paramSuppliers[1], paramSuppliers[2], paramSuppliers[3]);
+                            break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void debug(String message)
+    {
+        logger.debug(message);
+    }
+
+    /**
+     * Logs a message object with the DEBUG level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void debug(Object message)
+    {
+        logger.debug(message);
+    }
+
+    /**
+     * Logs a message with parameters at the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void debug(String message, Object... params)
+    {
+        logger.debug(message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the DEBUG level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void debug(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.DEBUG, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the DEBUG level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void debug(String message, Throwable t)
+    {
+        logger.debug(message, t);
+    }
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void error(String message)
+    {
+        logger.error(message);
+    }
+
+    /**
+     * Logs a message object with the ERROR level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void error(Object message)
+    {
+        logger.error(message);
+    }
+
+    /**
+     * Logs a message with parameters at the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void error(String message, Object... params)
+    {
+        logger.error(message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the ERROR level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void error(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.ERROR, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the ERROR level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void error(String message, Throwable t)
+    {
+        logger.error(message, t);
+    }
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void fatal(String message)
+    {
+        logger.fatal(message);
+    }
+
+    /**
+     * Logs a message object with the FATAL level.
+     *
+     * @param message the message object to log.
+     */
+    @Override
+    public void fatal(Object message)
+    {
+        logger.fatal(message);
+    }
+
+    /**
+     * Logs a message with parameters at the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param params parameters to the message.
+     */
+    @Override
+    public void fatal(String message, Object... params)
+    {
+        logger.fatal(message, params);
+    }
+
+    /**
+     * Logs a message with parameters which are only to be constructed if the
+     * logging level is the FATAL level.
+     *
+     * @param message the message to log; the format depends on the message factory.
+     * @param paramSuppliers An array of functions, which when called, produce
+     *        the desired log message parameters.
+     */
+    @Override
+    public void fatal(String message, Supplier<?>... paramSuppliers)
+    {
+        log(Level.FATAL, message, paramSuppliers);
+    }
+
+    /**
+     * Logs a message at the FATAL level including the stack trace of the {@link Throwable}
+     * <code>t</code> passed as parameter.
+     *
+     * @param message the message object to log.
+     * @param t the exception to log, including its stack trace.
+     */
+    @Override
+    public void fatal(String message, Throwable t)
+    {
+        logger.fatal(message, t);
+    }
+
+    /**
+     * Gets the logger name.
+     *
+     * @return the logger name.
+     */
+    @Override
+    public String getName()
+    {
+        return logger.getName();
+    }
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message string to log.
+     */
+    @Override
+    public void info(String message)
+    {
+        logger.info(message);
+    }
+
+    /**
+     * Logs a message object with the INFO level.
+     *
+     * @param message the message object to log.
+     */
... 3574 lines suppressed ...