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:46 UTC

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

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 ...