You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/03/27 16:34:12 UTC

[1/4] logging-log4j2 git commit: LOG4J2-1318 create new datastructure that does not allocate temporary objects for the hot path methods

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 0f750ebb8 -> f0d57be55


LOG4J2-1318 create new datastructure that does not allocate temporary objects for the hot path methods


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b1e0b76d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b1e0b76d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b1e0b76d

Branch: refs/heads/master
Commit: b1e0b76da0461ebd68b7c032e05c373eced28968
Parents: 0f750eb
Author: rpopma <rp...@apache.org>
Authored: Sun Mar 27 23:28:57 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Mar 27 23:28:57 2016 +0900

----------------------------------------------------------------------
 .../logging/log4j/spi/LoggerRegistry.java       | 182 +++++++++++++++++++
 1 file changed, 182 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b1e0b76d/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
new file mode 100644
index 0000000..dbc8c0b
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.spi;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.logging.log4j.message.MessageFactory;
+
+/**
+ * Convenience class to be used by {@code LoggerContext} implementations.
+ */
+public class LoggerRegistry<T extends ExtendedLogger> {
+    private static final String DEFAULT_FACTORY_KEY = AbstractLogger.DEFAULT_MESSAGE_FACTORY_CLASS.getName();
+    private final MapFactory<T> factory;
+    private final Map<String, Map<String, T>> map;
+
+    /**
+     * Interface to control the data structure used by the registry to store the Loggers.
+     * @param <T> subtype of {@code ExtendedLogger}
+     */
+    public interface MapFactory<T extends ExtendedLogger> {
+        Map<String, T> createInnerMap();
+
+        Map<String, Map<String, T>> createOuterMap();
+
+        void putIfAbsent(Map<String, T> innerMap, String name, T logger);
+    }
+
+    /**
+     * Generates ConcurrentHashMaps for use by the registry to store the Loggers.
+     * @param <T> subtype of {@code ExtendedLogger}
+     */
+    public static class ConcurrentMapFactory<T extends ExtendedLogger> implements MapFactory<T> {
+        @Override
+        public Map<String, T> createInnerMap() {
+            return new ConcurrentHashMap<>();
+        }
+
+        @Override
+        public Map<String, Map<String, T>> createOuterMap() {
+            return new ConcurrentHashMap<>();
+        }
+
+        @Override
+        public void putIfAbsent(final Map<String, T> innerMap, final String name, final T logger) {
+            ((ConcurrentMap<String, T>) innerMap).putIfAbsent(name, logger);
+        }
+    }
+
+    /**
+     * Generates WeakHashMaps for use by the registry to store the Loggers.
+     * @param <T> subtype of {@code ExtendedLogger}
+     */
+    public static class WeakMapFactory<T extends ExtendedLogger> implements MapFactory<T> {
+        @Override
+        public Map<String, T> createInnerMap() {
+            return new WeakHashMap<>();
+        }
+
+        @Override
+        public Map<String, Map<String, T>> createOuterMap() {
+            return new WeakHashMap<>();
+        }
+
+        @Override
+        public void putIfAbsent(final Map<String, T> innerMap, final String name, final T logger) {
+            innerMap.put(name, logger);
+        }
+    }
+
+    public LoggerRegistry() {
+        this(new ConcurrentMapFactory<T>());
+    }
+
+    public LoggerRegistry(final MapFactory<T> factory) {
+        this.factory = Objects.requireNonNull(factory, "factory");
+        this.map = factory.createOuterMap();
+    }
+
+    private static String factoryClassKey(final Class<? extends MessageFactory> messageFactoryClass) {
+        return messageFactoryClass == null ? DEFAULT_FACTORY_KEY : messageFactoryClass.getName();
+    }
+
+    private static String factoryKey(final MessageFactory messageFactory) {
+        return messageFactory == null ? DEFAULT_FACTORY_KEY : messageFactory.getClass().getName();
+    }
+
+    /**
+     * Returns an ExtendedLogger.
+     * @param name The name of the Logger to return.
+     * @return The logger with the specified name.
+     */
+    public T getLogger(final String name) {
+        return getOrCreateInnerMap(DEFAULT_FACTORY_KEY).get(name);
+    }
+
+    /**
+     * Returns an ExtendedLogger.
+     * @param name The name of the Logger to return.
+     * @param messageFactory The message factory is used only when creating a logger, subsequent use does not change
+     *                       the logger but will log a warning if mismatched.
+     * @return The logger with the specified name.
+     */
+    public T getLogger(final String name, final MessageFactory messageFactory) {
+        return getOrCreateInnerMap(factoryKey(messageFactory)).get(name);
+    }
+
+    public Collection<T> getLoggers() {
+        return getLoggers(new ArrayList<T>());
+    }
+
+    public Collection<T> getLoggers(final Collection<T> destination) {
+        for (Map<String, T> inner : map.values()) {
+            destination.addAll(inner.values());
+        }
+        return destination;
+    }
+
+    private Map<String, T> getOrCreateInnerMap(final String factoryName) {
+        Map<String, T> inner = map.get(factoryName);
+        if (inner == null) {
+            inner = factory.createInnerMap();
+            map.put(factoryName, inner);
+        }
+        return inner;
+    }
+
+    /**
+     * Detects if a Logger with the specified name exists.
+     * @param name The Logger name to search for.
+     * @return true if the Logger exists, false otherwise.
+     */
+    public boolean hasLogger(final String name) {
+        return getOrCreateInnerMap(DEFAULT_FACTORY_KEY).containsKey(name);
+    }
+
+    /**
+     * Detects if a Logger with the specified name and MessageFactory exists.
+     * @param name The Logger name to search for.
+     * @param messageFactory The message factory to search for.
+     * @return true if the Logger exists, false otherwise.
+     * @since 2.5
+     */
+    public boolean hasLogger(final String name, final MessageFactory messageFactory) {
+        return getOrCreateInnerMap(factoryKey(messageFactory)).containsKey(name);
+    }
+
+    /**
+     * Detects if a Logger with the specified name and MessageFactory type exists.
+     * @param name The Logger name to search for.
+     * @param messageFactoryClass The message factory class to search for.
+     * @return true if the Logger exists, false otherwise.
+     * @since 2.5
+     */
+    public boolean hasLogger(final String name, final Class<? extends MessageFactory> messageFactoryClass) {
+        return getOrCreateInnerMap(factoryClassKey(messageFactoryClass)).containsKey(name);
+    }
+
+    public void putIfAbsent(final String name, final MessageFactory messageFactory, final T logger) {
+        factory.putIfAbsent(getOrCreateInnerMap(factoryKey(messageFactory)), name, logger);
+    }
+}


[4/4] logging-log4j2 git commit: LOG4J2-1318 update change log

Posted by rp...@apache.org.
LOG4J2-1318 update change log


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/f0d57be5
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/f0d57be5
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/f0d57be5

Branch: refs/heads/master
Commit: f0d57be550ee2e62acd7180b9d086872ce904310
Parents: 4ecc963
Author: rpopma <rp...@apache.org>
Authored: Sun Mar 27 23:34:04 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Mar 27 23:34:04 2016 +0900

----------------------------------------------------------------------
 src/changes/changes.xml | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f0d57be5/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 46661a5..2279cbe 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -27,6 +27,9 @@
       <action issue="LOG4J2-1324" dev="rpopma" type="fix">
         Improve error handling in the Async Logger background thread: the new default exception handler no longer rethrows the error.
       </action>
+      <action issue="LOG4J2-1318" dev="rpopma" type="update">
+        Avoid allocating unnecessary temporary objects in LoggerContext's getLogger methods.
+      </action>
       <action issue="LOG4J2-1333" dev="rpopma" type="update">
         Avoid allocating unnecessary temporary objects in MarkerManager's getMarker methods.
       </action>


[3/4] logging-log4j2 git commit: LOG4J2-1318 refactor LoggerContext implementations to use new LoggerRegistry data structure to avoid allocating temp objects. (No functional changes.)

Posted by rp...@apache.org.
LOG4J2-1318 refactor LoggerContext implementations to use new LoggerRegistry data structure to avoid allocating temp objects. (No functional changes.)


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4ecc9637
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4ecc9637
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4ecc9637

Branch: refs/heads/master
Commit: 4ecc9637ca69b7e7e1e1ee175850cfead428780a
Parents: b22e7a0
Author: rpopma <rp...@apache.org>
Authored: Sun Mar 27 23:33:23 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Mar 27 23:33:23 2016 +0900

----------------------------------------------------------------------
 .../log4j/simple/SimpleLoggerContext.java       | 24 ++++++---------
 .../logging/log4j/core/LoggerContext.java       | 27 +++++++----------
 .../log4j/taglib/Log4jTaglibLoggerContext.java  | 28 ++++++++---------
 .../logging/slf4j/SLF4JLoggerContext.java       | 32 +++++++++++---------
 4 files changed, 50 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4ecc9637/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
index 41d9629..4f71a10 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
@@ -19,15 +19,13 @@ package org.apache.logging.log4j.simple;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
-import org.apache.logging.log4j.spi.LoggerContextKey;
+import org.apache.logging.log4j.spi.LoggerRegistry;
 import org.apache.logging.log4j.util.PropertiesUtil;
 
 /**
@@ -45,7 +43,7 @@ public class SimpleLoggerContext implements LoggerContext {
 
     /** Include the instance name in the log message? */
     private final boolean showLogName;
-    
+
     /**
      * Include the short name (last component) of the logger in the log message. Defaults to true - otherwise we'll be
      * lost in a flood of messages without knowing who sends them.
@@ -62,7 +60,7 @@ public class SimpleLoggerContext implements LoggerContext {
 
     private final PrintStream stream;
 
-    private final ConcurrentMap<String, ExtendedLogger> loggers = new ConcurrentHashMap<>();
+    private final LoggerRegistry<ExtendedLogger> loggerRegistry = new LoggerRegistry<>();
 
     public SimpleLoggerContext() {
         props = new PropertiesUtil("log4j2.simplelog.properties");
@@ -101,20 +99,16 @@ public class SimpleLoggerContext implements LoggerContext {
 
     @Override
     public ExtendedLogger getLogger(final String name, final MessageFactory messageFactory) {
-        // Note: This is the only method where we add entries to the 'loggers' ivar.
-        // The loggers map key is the logger name plus the messageFactory FQCN.
-        String key = LoggerContextKey.create(name, messageFactory);
-        final ExtendedLogger extendedLogger = loggers.get(key);
+        // Note: This is the only method where we add entries to the 'loggerRegistry' ivar.
+        final ExtendedLogger extendedLogger = loggerRegistry.getLogger(name, messageFactory);
         if (extendedLogger != null) {
             AbstractLogger.checkMessageFactory(extendedLogger, messageFactory);
             return extendedLogger;
         }
         final SimpleLogger simpleLogger = new SimpleLogger(name, defaultLevel, showLogName, showShortName, showDateTime,
                 showContextMap, dateTimeFormat, messageFactory, props, stream);
-        // If messageFactory was null then we need to pull it out of the logger now
-        key = LoggerContextKey.create(name, simpleLogger.getMessageFactory());
-        loggers.putIfAbsent(key, simpleLogger);
-        return loggers.get(key);
+        loggerRegistry.putIfAbsent(name, messageFactory, simpleLogger);
+        return loggerRegistry.getLogger(name, messageFactory);
     }
 
     @Override
@@ -126,12 +120,12 @@ public class SimpleLoggerContext implements LoggerContext {
     public boolean hasLogger(String name, MessageFactory messageFactory) {
         return false;
     }
-    
+
     @Override
     public boolean hasLogger(String name, Class<? extends MessageFactory> messageFactoryClass) {
         return false;
     }
-    
+
     @Override
     public Object getExternalContext() {
         return null;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4ecc9637/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index 3937805..82a6de8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -22,7 +22,6 @@ import java.io.File;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.locks.Lock;
@@ -44,7 +43,7 @@ import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
-import org.apache.logging.log4j.spi.LoggerContextKey;
+import org.apache.logging.log4j.spi.LoggerRegistry;
 import org.apache.logging.log4j.spi.Terminable;
 
 import static org.apache.logging.log4j.core.util.ShutdownCallbackRegistry.*;
@@ -64,7 +63,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
 
     private static final Configuration NULL_CONFIGURATION = new NullConfiguration();
 
-    private final ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<>();
+    private final LoggerRegistry<Logger> loggerRegistry = new LoggerRegistry<>();
     private final CopyOnWriteArrayList<PropertyChangeListener> propertyChangeListeners = new CopyOnWriteArrayList<>();
 
     /**
@@ -382,7 +381,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      * @return a collection of the current loggers.
      */
     public Collection<Logger> getLoggers() {
-        return loggers.values();
+        return loggerRegistry.getLoggers();
     }
 
     /**
@@ -395,20 +394,16 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      */
     @Override
     public Logger getLogger(final String name, final MessageFactory messageFactory) {
-        // Note: This is the only method where we add entries to the 'loggers' ivar.
-        // The loggers map key is the logger name plus the messageFactory FQCN.
-        String key = LoggerContextKey.create(name, messageFactory);
-        Logger logger = loggers.get(key);
+        // Note: This is the only method where we add entries to the 'loggerRegistry' ivar.
+        Logger logger = loggerRegistry.getLogger(name, messageFactory);
         if (logger != null) {
             AbstractLogger.checkMessageFactory(logger, messageFactory);
             return logger;
         }
 
         logger = newInstance(this, name, messageFactory);
-        // If messageFactory was null then we need to pull it out of the logger now
-        key = LoggerContextKey.create(name, logger.getMessageFactory());
-        final Logger prev = loggers.putIfAbsent(key, logger);
-        return prev == null ? logger : prev;
+        loggerRegistry.putIfAbsent(name, messageFactory, logger);
+        return loggerRegistry.getLogger(name, messageFactory);
     }
 
     /**
@@ -419,7 +414,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      */
     @Override
     public boolean hasLogger(final String name) {
-        return loggers.containsKey(LoggerContextKey.create(name));
+        return loggerRegistry.hasLogger(name);
     }
 
     /**
@@ -430,7 +425,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      */
     @Override
     public boolean hasLogger(final String name, MessageFactory messageFactory) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactory));
+        return loggerRegistry.hasLogger(name, messageFactory);
     }
 
     /**
@@ -441,7 +436,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      */
     @Override
     public boolean hasLogger(final String name, Class<? extends MessageFactory> messageFactoryClass) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactoryClass));
+        return loggerRegistry.hasLogger(name, messageFactoryClass);
     }
 
     /**
@@ -596,7 +591,7 @@ public class LoggerContext extends AbstractLifeCycle implements org.apache.loggi
      */
     public void updateLoggers(final Configuration config) {
         final Configuration old = this.configuration;
-        for (final Logger logger : loggers.values()) {
+        for (final Logger logger : loggerRegistry.getLoggers()) {
             logger.updateConfiguration(config);
         }
         firePropertyChangeEvent(new PropertyChangeEvent(this, PROPERTY_CONFIG, old, config));

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4ecc9637/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
index 2c7b0a3..fb95d97 100644
--- a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
+++ b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
@@ -25,7 +25,7 @@ import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
-import org.apache.logging.log4j.spi.LoggerContextKey;
+import org.apache.logging.log4j.spi.LoggerRegistry;
 
 /**
  * This bridge between the tag library and the Log4j API ensures that instances of {@link Log4jTaglibLogger} are
@@ -36,11 +36,10 @@ import org.apache.logging.log4j.spi.LoggerContextKey;
 final class Log4jTaglibLoggerContext implements LoggerContext {
     // These were change to WeakHashMaps to avoid ClassLoader (memory) leak, something that's particularly
     // important in Servlet containers.
-    private static final WeakHashMap<ServletContext, Log4jTaglibLoggerContext> CONTEXTS =
-            new WeakHashMap<>();
+    private static final WeakHashMap<ServletContext, Log4jTaglibLoggerContext> CONTEXTS = new WeakHashMap<>();
 
-    private final WeakHashMap<String, Log4jTaglibLogger> loggers =
-            new WeakHashMap<>();
+    private final LoggerRegistry<Log4jTaglibLogger> loggerRegistry = new LoggerRegistry<>(
+            new LoggerRegistry.WeakMapFactory<Log4jTaglibLogger>());
 
     private final ServletContext servletContext;
 
@@ -60,25 +59,22 @@ final class Log4jTaglibLoggerContext implements LoggerContext {
 
     @Override
     public Log4jTaglibLogger getLogger(final String name, final MessageFactory messageFactory) {
-        // Note: This is the only method where we add entries to the 'loggers' ivar. 
-        // The loggers map key is the logger name plus the messageFactory FQCN.
-        String key = LoggerContextKey.create(name, messageFactory);
-        Log4jTaglibLogger logger = this.loggers.get(key);
+        // Note: This is the only method where we add entries to the 'loggerRegistry' ivar.
+        Log4jTaglibLogger logger = this.loggerRegistry.getLogger(name, messageFactory);
         if (logger != null) {
             AbstractLogger.checkMessageFactory(logger, messageFactory);
             return logger;
         }
 
-        synchronized (this.loggers) {
-            logger = this.loggers.get(key);
+        synchronized (this.loggerRegistry) {
+            logger = this.loggerRegistry.getLogger(name, messageFactory);
             if (logger == null) {
                 final LoggerContext context = LogManager.getContext(false);
                 final ExtendedLogger original = messageFactory == null ?
                         context.getLogger(name) : context.getLogger(name, messageFactory);
                 // wrap a logger from an underlying implementation
                 logger = new Log4jTaglibLogger(original, name, original.getMessageFactory());
-                key = LoggerContextKey.create(name, original.getMessageFactory());
-                this.loggers.put(key, logger);
+                this.loggerRegistry.putIfAbsent(name, messageFactory, logger);
             }
         }
 
@@ -87,17 +83,17 @@ final class Log4jTaglibLoggerContext implements LoggerContext {
 
     @Override
     public boolean hasLogger(final String name) {
-        return loggers.containsKey(LoggerContextKey.create(name));
+        return loggerRegistry.hasLogger(name);
     }
 
     @Override
     public boolean hasLogger(String name, MessageFactory messageFactory) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactory));
+        return loggerRegistry.hasLogger(name, messageFactory);
     }
 
     @Override
     public boolean hasLogger(String name, Class<? extends MessageFactory> messageFactoryClass) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactoryClass));
+        return loggerRegistry.hasLogger(name, messageFactoryClass);
     }
 
     static synchronized Log4jTaglibLoggerContext getInstance(final ServletContext servletContext) {

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4ecc9637/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
----------------------------------------------------------------------
diff --git a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
index c4e6a99..7923b2b 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
@@ -16,20 +16,17 @@
  */
 package org.apache.logging.slf4j;
 
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
-import org.apache.logging.log4j.spi.LoggerContextKey;
+import org.apache.logging.log4j.spi.LoggerRegistry;
 import org.slf4j.LoggerFactory;
 
 /**
  *
  */
 public class SLF4JLoggerContext implements LoggerContext {
-    private final ConcurrentMap<String, SLF4JLogger> loggers = new ConcurrentHashMap<>();
+    private final LoggerRegistry<ExtendedLogger> loggerRegistry = new LoggerRegistry<>();
 
     @Override
     public Object getExternalContext() {
@@ -38,32 +35,39 @@ public class SLF4JLoggerContext implements LoggerContext {
 
     @Override
     public ExtendedLogger getLogger(final String name) {
-        if (!loggers.containsKey(name)) {
-            loggers.putIfAbsent(name, new SLF4JLogger(name, LoggerFactory.getLogger(name)));
+        if (!loggerRegistry.hasLogger(name)) {
+            loggerRegistry.putIfAbsent(name, null, new SLF4JLogger(name, LoggerFactory.getLogger(name)));
         }
-        return loggers.get(name);
+        return loggerRegistry.getLogger(name);
     }
 
     @Override
     public ExtendedLogger getLogger(final String name, final MessageFactory messageFactory) {
-        if (!loggers.containsKey(name)) {
-            loggers.putIfAbsent(name, new SLF4JLogger(name, messageFactory, LoggerFactory.getLogger(name)));
+        // FIXME according to LOG4J2-1180, the below line should be:
+        // FIXME if (!loggerRegistry.hasLogger(name, messageFactory)) {
+        if (!loggerRegistry.hasLogger(name)) {
+            // FIXME: should be loggerRegistry.putIfAbsent(name, messageFactory,
+            loggerRegistry.putIfAbsent(name, null,
+                    new SLF4JLogger(name, messageFactory, LoggerFactory.getLogger(name)));
         }
-        return loggers.get(name);
+        // FIXME should be return loggerRegistry.getLogger(name, messageFactory);
+        return loggerRegistry.getLogger(name);
+
+        // TODO applying the above fixes causes (log4j-to-slf4j) LoggerTest to fail
     }
 
     @Override
     public boolean hasLogger(final String name) {
-        return loggers.containsKey(LoggerContextKey.create(name));
+        return loggerRegistry.hasLogger(name);
     }
 
     @Override
     public boolean hasLogger(String name, MessageFactory messageFactory) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactory));
+        return loggerRegistry.hasLogger(name, messageFactory);
     }
 
     @Override
     public boolean hasLogger(String name, Class<? extends MessageFactory> messageFactoryClass) {
-        return loggers.containsKey(LoggerContextKey.create(name, messageFactoryClass));
+        return loggerRegistry.hasLogger(name, messageFactoryClass);
     }
 }


[2/4] logging-log4j2 git commit: LOG4J2-1318 deprecate LoggerContextKey: it is not used anywhere any more

Posted by rp...@apache.org.
LOG4J2-1318 deprecate LoggerContextKey: it is not used anywhere any more


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b22e7a00
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b22e7a00
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b22e7a00

Branch: refs/heads/master
Commit: b22e7a000d82a30ac3f2f88d29b118b68fe9057b
Parents: b1e0b76
Author: rpopma <rp...@apache.org>
Authored: Sun Mar 27 23:29:30 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Mar 27 23:29:30 2016 +0900

----------------------------------------------------------------------
 .../main/java/org/apache/logging/log4j/spi/LoggerContextKey.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b22e7a00/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContextKey.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContextKey.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContextKey.java
index 95859bd..113bc45 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContextKey.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContextKey.java
@@ -21,9 +21,11 @@ import org.apache.logging.log4j.message.MessageFactory;
 
 /**
  * Creates keys used in maps for use in LoggerContext implementations.
- * 
+ *
+ * @deprecated with no replacement - no longer used
  * @since 2.5
  */
+@Deprecated
 public class LoggerContextKey {
 
     public static String create(final String name) {