You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apex.apache.org by th...@apache.org on 2016/08/27 18:42:27 UTC

[1/2] apex-core git commit: APEXCORE-169 - instantiating DTLoggerFactory during test causes incorrect logging behavior

Repository: apex-core
Updated Branches:
  refs/heads/master d651edc60 -> 9c48c41e9


APEXCORE-169 - instantiating DTLoggerFactory during test causes incorrect logging behavior


Project: http://git-wip-us.apache.org/repos/asf/apex-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/apex-core/commit/80461746
Tree: http://git-wip-us.apache.org/repos/asf/apex-core/tree/80461746
Diff: http://git-wip-us.apache.org/repos/asf/apex-core/diff/80461746

Branch: refs/heads/master
Commit: 80461746d9bbe8ee1070d455e2b32f8ef2b907c3
Parents: d651edc
Author: Vlad Rozov <v....@datatorrent.com>
Authored: Thu Aug 25 13:33:19 2016 -0700
Committer: Vlad Rozov <v....@datatorrent.com>
Committed: Thu Aug 25 13:33:19 2016 -0700

----------------------------------------------------------------------
 .../stram/LaunchContainerRunnable.java          |   5 +-
 .../java/com/datatorrent/stram/StramClient.java |   5 +-
 .../java/com/datatorrent/stram/StramUtils.java  |  19 +-
 .../stram/client/StramClientUtils.java          |   4 +-
 .../stram/engine/StreamingContainer.java        |   4 +-
 .../com/datatorrent/stram/util/LoggerUtil.java  | 252 +++++++++++++++++++
 .../stram/webapp/StramWebServices.java          |   8 +-
 .../java/org/apache/log4j/DTLoggerFactory.java  | 252 -------------------
 .../datatorrent/stram/util/LoggerUtilTest.java  | 101 ++++++++
 .../org/apache/log4j/DTLoggerFactoryTest.java   | 101 --------
 10 files changed, 382 insertions(+), 369 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/LaunchContainerRunnable.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/LaunchContainerRunnable.java b/engine/src/main/java/com/datatorrent/stram/LaunchContainerRunnable.java
index e9dd72b..76c1407 100644
--- a/engine/src/main/java/com/datatorrent/stram/LaunchContainerRunnable.java
+++ b/engine/src/main/java/com/datatorrent/stram/LaunchContainerRunnable.java
@@ -53,7 +53,6 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.security.AMRMTokenIdentifier;
 import org.apache.hadoop.yarn.util.ConverterUtils;
 import org.apache.hadoop.yarn.util.Records;
-import org.apache.log4j.DTLoggerFactory;
 
 import com.google.common.collect.Lists;
 
@@ -250,9 +249,9 @@ public class LaunchContainerRunnable implements Runnable
     vargs.add("-Dhadoop.root.logger=" + (dag.isDebug() ? "DEBUG" : "INFO") + ",RFA");
     vargs.add("-Dhadoop.log.dir=" + ApplicationConstants.LOG_DIR_EXPANSION_VAR);
 
-    String loggersLevel = System.getProperty(DTLoggerFactory.DT_LOGGERS_LEVEL);
+    String loggersLevel = System.getProperty(StramUtils.DT_LOGGERS_LEVEL);
     if (loggersLevel != null) {
-      vargs.add(String.format("-D%s=%s", DTLoggerFactory.DT_LOGGERS_LEVEL, loggersLevel));
+      vargs.add(String.format("-D%s=%s", StramUtils.DT_LOGGERS_LEVEL, loggersLevel));
     }
     // Add main class and its arguments
     vargs.add(StreamingContainer.class.getName());  // main of Child

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/StramClient.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/StramClient.java b/engine/src/main/java/com/datatorrent/stram/StramClient.java
index b95770f..5854ec8 100644
--- a/engine/src/main/java/com/datatorrent/stram/StramClient.java
+++ b/engine/src/main/java/com/datatorrent/stram/StramClient.java
@@ -69,7 +69,6 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration;
 import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.util.ConverterUtils;
 import org.apache.hadoop.yarn.util.Records;
-import org.apache.log4j.DTLoggerFactory;
 
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
@@ -570,9 +569,9 @@ public class StramClient
         vargs.add("-Dlog4j.debug=true");
       }
 
-      String loggersLevel = conf.get(DTLoggerFactory.DT_LOGGERS_LEVEL);
+      String loggersLevel = conf.get(StramUtils.DT_LOGGERS_LEVEL);
       if (loggersLevel != null) {
-        vargs.add(String.format("-D%s=%s", DTLoggerFactory.DT_LOGGERS_LEVEL, loggersLevel));
+        vargs.add(String.format("-D%s=%s", StramUtils.DT_LOGGERS_LEVEL, loggersLevel));
       }
       vargs.add(StreamingAppMaster.class.getName());
       vargs.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/AppMaster.stdout");

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/StramUtils.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/StramUtils.java b/engine/src/main/java/com/datatorrent/stram/StramUtils.java
index a931253..2b2baa6 100644
--- a/engine/src/main/java/com/datatorrent/stram/StramUtils.java
+++ b/engine/src/main/java/com/datatorrent/stram/StramUtils.java
@@ -28,9 +28,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.hadoop.yarn.api.ApplicationConstants.Environment;
-import org.apache.log4j.DTLoggerFactory;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
 
 import com.datatorrent.api.StreamingApplication;
+import com.datatorrent.stram.util.LoggerUtil;
 
 /**
  *
@@ -42,6 +45,7 @@ import com.datatorrent.api.StreamingApplication;
 public abstract class StramUtils
 {
   private static final Logger LOG = LoggerFactory.getLogger(StramUtils.class);
+  public static final String DT_LOGGERS_LEVEL = "dt.loggers.level";
 
   public static <T> Class<? extends T> classForName(String className, Class<T> superClass)
   {
@@ -85,7 +89,18 @@ public abstract class StramUtils
           }
         }
       }
-      DTLoggerFactory.getInstance().initialize();
+
+      String loggersLevel = System.getProperty(DT_LOGGERS_LEVEL);
+      if (!Strings.isNullOrEmpty(loggersLevel)) {
+        Map<String, String> targetChanges = Maps.newHashMap();
+        String[] targets = loggersLevel.split(",");
+        for (String target : targets) {
+          String[] parts = target.split(":");
+          targetChanges.put(parts[0], parts[1]);
+        }
+        LoggerUtil.changeLoggersLevel(targetChanges);
+      }
+
     }
   }
 

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/client/StramClientUtils.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/client/StramClientUtils.java b/engine/src/main/java/com/datatorrent/stram/client/StramClientUtils.java
index fc60961..02f2629 100644
--- a/engine/src/main/java/com/datatorrent/stram/client/StramClientUtils.java
+++ b/engine/src/main/java/com/datatorrent/stram/client/StramClientUtils.java
@@ -75,7 +75,6 @@ import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.hadoop.yarn.ipc.YarnRPC;
 import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
 import org.apache.hadoop.yarn.util.ConverterUtils;
-import org.apache.log4j.DTLoggerFactory;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
@@ -83,6 +82,7 @@ import com.google.common.collect.Sets;
 
 import com.datatorrent.api.StreamingApplication;
 import com.datatorrent.stram.StramClient;
+import com.datatorrent.stram.StramUtils;
 import com.datatorrent.stram.security.StramUserLogin;
 import com.datatorrent.stram.util.ConfigUtils;
 import com.datatorrent.stram.util.ConfigValidator;
@@ -414,7 +414,7 @@ public class StramClientUtils
     }
 
     //Validate loggers-level settings
-    String loggersLevel = conf.get(DTLoggerFactory.DT_LOGGERS_LEVEL);
+    String loggersLevel = conf.get(StramUtils.DT_LOGGERS_LEVEL);
     if (loggersLevel != null) {
       String[] targets = loggersLevel.split(",");
       Preconditions.checkArgument(targets.length > 0, "zero loggers level");

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/engine/StreamingContainer.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/engine/StreamingContainer.java b/engine/src/main/java/com/datatorrent/stram/engine/StreamingContainer.java
index 27688e3..756fec2 100644
--- a/engine/src/main/java/com/datatorrent/stram/engine/StreamingContainer.java
+++ b/engine/src/main/java/com/datatorrent/stram/engine/StreamingContainer.java
@@ -53,7 +53,6 @@ import org.apache.hadoop.security.Credentials;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.yarn.conf.YarnConfiguration;
-import org.apache.log4j.DTLoggerFactory;
 import org.apache.log4j.LogManager;
 
 import com.datatorrent.api.Attribute;
@@ -118,6 +117,7 @@ import com.datatorrent.stram.stream.MuxStream;
 import com.datatorrent.stram.stream.OiOStream;
 import com.datatorrent.stram.stream.PartitionAwareSink;
 import com.datatorrent.stram.stream.PartitionAwareSinkForPersistence;
+import com.datatorrent.stram.util.LoggerUtil;
 
 import net.engio.mbassy.bus.MBassador;
 import net.engio.mbassy.bus.config.BusConfiguration;
@@ -1623,7 +1623,7 @@ public class StreamingContainer extends YarnContainerMain
   private void handleChangeLoggersRequest(StramToNodeChangeLoggersRequest request)
   {
     logger.debug("handle change logger request");
-    DTLoggerFactory.getInstance().changeLoggersLevel(request.getTargetChanges());
+    LoggerUtil.changeLoggersLevel(request.getTargetChanges());
   }
 
   private final StreamCodec<Object> nonSerializingStreamCodec = new StreamCodec<Object>()

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java b/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
new file mode 100644
index 0000000..04e6856
--- /dev/null
+++ b/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
@@ -0,0 +1,252 @@
+/**
+ * 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.log4j;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+import org.apache.log4j.spi.LoggerFactory;
+import org.apache.log4j.spi.LoggerRepository;
+import org.apache.log4j.spi.RepositorySelector;
+
+import com.google.common.base.Function;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+/**
+ * An implementation of {@link LoggerFactory}
+ *
+ * @since 1.0.2
+ */
+public class DTLoggerFactory implements LoggerFactory
+{
+  public static final String DT_LOGGERS_LEVEL = "dt.loggers.level";
+
+  private static DTLoggerFactory SINGLETON;
+
+  public static synchronized DTLoggerFactory getInstance()
+  {
+    if (SINGLETON == null) {
+      SINGLETON = new DTLoggerFactory();
+    }
+    return SINGLETON;
+  }
+
+  private final ConcurrentMap<String, Logger> loggerMap;
+  private final Map<String, Level> patternLevel;
+
+  public ImmutableMap<String, String> getPatternLevels()
+  {
+    return ImmutableMap.copyOf(Maps.transformValues(patternLevel, new Function<Level, String>()
+    {
+      @Override
+      public String apply(Level input)
+      {
+        return input == null ? "" : input.toString();
+      }
+    }));
+  }
+
+  private final Map<String, Pattern> patterns;
+  private boolean initialized = false;
+
+  private DTLoggerFactory()
+  {
+    loggerMap = Maps.newConcurrentMap();
+    patternLevel = Maps.newHashMap();
+    patterns = Maps.newHashMap();
+  }
+
+  public synchronized void initialize()
+  {
+    if (!initialized) {
+      LOG.debug("initializing DT Logger Factory");
+      new RepositorySelectorImpl().initialize();
+      String loggersLevel = System.getProperty(DT_LOGGERS_LEVEL);
+      if (!Strings.isNullOrEmpty(loggersLevel)) {
+        Map<String, String> targetChanges = Maps.newHashMap();
+        String[] targets = loggersLevel.split(",");
+        for (String target : targets) {
+          String[] parts = target.split(":");
+          targetChanges.put(parts[0], parts[1]);
+        }
+        changeLoggersLevel(targetChanges);
+      }
+      initialized = true;
+    } else {
+      LOG.warn("DT Logger Factory already initialized.");
+    }
+  }
+
+  public synchronized void changeLoggersLevel(@Nonnull Map<String, String> targetChanges)
+  {
+    /*remove existing patterns which are subsets of new patterns. for eg. if x.y.z.* will be removed if
+    there is x.y.* in the target changes.
+    */
+    for (Map.Entry<String, String> changeEntry : targetChanges.entrySet()) {
+      Iterator<Map.Entry<String, Pattern>> patternsIterator = patterns.entrySet().iterator();
+      while ((patternsIterator.hasNext())) {
+        Map.Entry<String, Pattern> entry = patternsIterator.next();
+        String finer = entry.getKey();
+        String wider = changeEntry.getKey();
+        if (finer.length() < wider.length()) {
+          continue;
+        }
+        boolean remove = false;
+        for (int i = 0; i < wider.length(); i++) {
+          if (wider.charAt(i) == '*') {
+            remove = true;
+            break;
+          }
+          if (wider.charAt(i) != finer.charAt(i)) {
+            break;
+          } else if (i == wider.length() - 1) {
+            remove = true;
+          }
+        }
+        if (remove) {
+          patternsIterator.remove();
+          patternLevel.remove(finer);
+        }
+      }
+    }
+    for (Map.Entry<String, String> loggerEntry : targetChanges.entrySet()) {
+      String target = loggerEntry.getKey();
+      patternLevel.put(target, Level.toLevel(loggerEntry.getValue()));
+      patterns.put(target, Pattern.compile(target));
+    }
+
+    if (!patternLevel.isEmpty()) {
+      @SuppressWarnings("unchecked")
+      Enumeration<Logger> loggerEnumeration = LogManager.getCurrentLoggers();
+      while (loggerEnumeration.hasMoreElements()) {
+        Logger classLogger = loggerEnumeration.nextElement();
+        Level oldLevel = classLogger.getLevel();
+        Level newLevel = getLevelFor(classLogger.getName());
+        if (newLevel != null && (oldLevel == null || !newLevel.equals(oldLevel))) {
+          LOG.info("changing level of " + classLogger.getName() + " to " + newLevel);
+          classLogger.setLevel(newLevel);
+        }
+      }
+    }
+  }
+
+  @Override
+  public Logger makeNewLoggerInstance(String name)
+  {
+    Logger newInstance = new Logger(name);
+    Level level = getLevelFor(name);
+    if (level != null) {
+      newInstance.setLevel(level);
+    }
+    loggerMap.put(name, newInstance);
+    return newInstance;
+  }
+
+  private synchronized Level getLevelFor(String name)
+  {
+    if (patternLevel.isEmpty()) {
+      return null;
+    }
+    String longestPatternKey = null;
+    for (String partternKey : patternLevel.keySet()) {
+      Pattern pattern = patterns.get(partternKey);
+      if (pattern.matcher(name).matches() && (longestPatternKey == null || longestPatternKey.length() < partternKey.length())) {
+        longestPatternKey = partternKey;
+      }
+    }
+    if (longestPatternKey != null) {
+      return patternLevel.get(longestPatternKey);
+    }
+    return null;
+  }
+
+  public synchronized ImmutableMap<String, String> getClassesMatching(@Nonnull String searchKey)
+  {
+    Pattern searchPattern = Pattern.compile(searchKey);
+    Map<String, String> matchedClasses = Maps.newHashMap();
+    @SuppressWarnings("unchecked")
+    Enumeration<Logger> loggerEnumeration = LogManager.getCurrentLoggers();
+    while (loggerEnumeration.hasMoreElements()) {
+      Logger logger = loggerEnumeration.nextElement();
+      if (searchPattern.matcher(logger.getName()).matches()) {
+        Level level = logger.getLevel();
+        matchedClasses.put(logger.getName(), level == null ? "" : level.toString());
+      }
+    }
+    return ImmutableMap.copyOf(matchedClasses);
+  }
+
+  private static class RepositorySelectorImpl implements RepositorySelector
+  {
+
+    private boolean initialized;
+    private Logger guard;
+    private Hierarchy hierarchy;
+
+    private RepositorySelectorImpl()
+    {
+      initialized = false;
+    }
+
+    private void initialize()
+    {
+      if (!initialized) {
+        LOG.debug("initializing logger repository selector impl");
+        guard = LogManager.getRootLogger();
+        LogManager.setRepositorySelector(this, guard);
+        hierarchy = new LoggerRepositoryImpl(guard);
+        initialized = true;
+      }
+    }
+
+    @Override
+    public LoggerRepository getLoggerRepository()
+    {
+      return hierarchy;
+    }
+  }
+
+  private static class LoggerRepositoryImpl extends Hierarchy
+  {
+    /**
+     * Create a new logger hierarchy.
+     *
+     * @param root The root of the new hierarchy.
+     */
+    private LoggerRepositoryImpl(Logger root)
+    {
+      super(root);
+    }
+
+    @Override
+    public Logger getLogger(String name)
+    {
+      return super.getLogger(name, DTLoggerFactory.getInstance());
+    }
+  }
+
+  private static final Logger LOG = LogManager.getLogger(DTLoggerFactory.class);
+}

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java b/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java
index f09a53e..16b7ed7 100644
--- a/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java
+++ b/engine/src/main/java/com/datatorrent/stram/webapp/StramWebServices.java
@@ -70,7 +70,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.yarn.api.ApplicationConstants;
 import org.apache.hadoop.yarn.webapp.NotFoundException;
-import org.apache.log4j.DTLoggerFactory;
 
 import com.google.common.collect.Maps;
 import com.google.inject.Inject;
@@ -93,6 +92,7 @@ import com.datatorrent.stram.plan.logical.LogicalPlanConfiguration;
 import com.datatorrent.stram.plan.logical.requests.LogicalPlanRequest;
 import com.datatorrent.stram.util.ConfigValidator;
 import com.datatorrent.stram.util.JSONSerializationProvider;
+import com.datatorrent.stram.util.LoggerUtil;
 
 /**
  *
@@ -966,7 +966,7 @@ public class StramWebServices
       if (!targetChanges.isEmpty()) {
         dagManager.setLoggersLevel(Collections.unmodifiableMap(targetChanges));
         //Changing the levels on Stram after sending the message to all containers.
-        DTLoggerFactory.getInstance().changeLoggersLevel(targetChanges);
+        LoggerUtil.changeLoggersLevel(targetChanges);
       }
     } catch (JSONException ex) {
       throw new RuntimeException(ex);
@@ -984,7 +984,7 @@ public class StramWebServices
     JSONArray loggersArray = new JSONArray();
     try {
       if (pattern != null) {
-        Map<String, String> matches = DTLoggerFactory.getInstance().getClassesMatching(pattern);
+        Map<String, String> matches = LoggerUtil.getClassesMatching(pattern);
         for (Map.Entry<String, String> match : matches.entrySet()) {
           JSONObject node = new JSONObject();
           node.put("name", match.getKey());
@@ -1007,7 +1007,7 @@ public class StramWebServices
     init();
     JSONObject response = new JSONObject();
     JSONArray levelsArray = new JSONArray();
-    Map<String, String> currentLevels = DTLoggerFactory.getInstance().getPatternLevels();
+    Map<String, String> currentLevels = LoggerUtil.getPatternLevels();
     for (Map.Entry<String, String> lvl : currentLevels.entrySet()) {
       JSONObject node = new JSONObject();
       node.put("target", lvl.getKey());

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/main/java/org/apache/log4j/DTLoggerFactory.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/org/apache/log4j/DTLoggerFactory.java b/engine/src/main/java/org/apache/log4j/DTLoggerFactory.java
deleted file mode 100644
index 04e6856..0000000
--- a/engine/src/main/java/org/apache/log4j/DTLoggerFactory.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.log4j;
-
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nonnull;
-
-import org.apache.log4j.spi.LoggerFactory;
-import org.apache.log4j.spi.LoggerRepository;
-import org.apache.log4j.spi.RepositorySelector;
-
-import com.google.common.base.Function;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-/**
- * An implementation of {@link LoggerFactory}
- *
- * @since 1.0.2
- */
-public class DTLoggerFactory implements LoggerFactory
-{
-  public static final String DT_LOGGERS_LEVEL = "dt.loggers.level";
-
-  private static DTLoggerFactory SINGLETON;
-
-  public static synchronized DTLoggerFactory getInstance()
-  {
-    if (SINGLETON == null) {
-      SINGLETON = new DTLoggerFactory();
-    }
-    return SINGLETON;
-  }
-
-  private final ConcurrentMap<String, Logger> loggerMap;
-  private final Map<String, Level> patternLevel;
-
-  public ImmutableMap<String, String> getPatternLevels()
-  {
-    return ImmutableMap.copyOf(Maps.transformValues(patternLevel, new Function<Level, String>()
-    {
-      @Override
-      public String apply(Level input)
-      {
-        return input == null ? "" : input.toString();
-      }
-    }));
-  }
-
-  private final Map<String, Pattern> patterns;
-  private boolean initialized = false;
-
-  private DTLoggerFactory()
-  {
-    loggerMap = Maps.newConcurrentMap();
-    patternLevel = Maps.newHashMap();
-    patterns = Maps.newHashMap();
-  }
-
-  public synchronized void initialize()
-  {
-    if (!initialized) {
-      LOG.debug("initializing DT Logger Factory");
-      new RepositorySelectorImpl().initialize();
-      String loggersLevel = System.getProperty(DT_LOGGERS_LEVEL);
-      if (!Strings.isNullOrEmpty(loggersLevel)) {
-        Map<String, String> targetChanges = Maps.newHashMap();
-        String[] targets = loggersLevel.split(",");
-        for (String target : targets) {
-          String[] parts = target.split(":");
-          targetChanges.put(parts[0], parts[1]);
-        }
-        changeLoggersLevel(targetChanges);
-      }
-      initialized = true;
-    } else {
-      LOG.warn("DT Logger Factory already initialized.");
-    }
-  }
-
-  public synchronized void changeLoggersLevel(@Nonnull Map<String, String> targetChanges)
-  {
-    /*remove existing patterns which are subsets of new patterns. for eg. if x.y.z.* will be removed if
-    there is x.y.* in the target changes.
-    */
-    for (Map.Entry<String, String> changeEntry : targetChanges.entrySet()) {
-      Iterator<Map.Entry<String, Pattern>> patternsIterator = patterns.entrySet().iterator();
-      while ((patternsIterator.hasNext())) {
-        Map.Entry<String, Pattern> entry = patternsIterator.next();
-        String finer = entry.getKey();
-        String wider = changeEntry.getKey();
-        if (finer.length() < wider.length()) {
-          continue;
-        }
-        boolean remove = false;
-        for (int i = 0; i < wider.length(); i++) {
-          if (wider.charAt(i) == '*') {
-            remove = true;
-            break;
-          }
-          if (wider.charAt(i) != finer.charAt(i)) {
-            break;
-          } else if (i == wider.length() - 1) {
-            remove = true;
-          }
-        }
-        if (remove) {
-          patternsIterator.remove();
-          patternLevel.remove(finer);
-        }
-      }
-    }
-    for (Map.Entry<String, String> loggerEntry : targetChanges.entrySet()) {
-      String target = loggerEntry.getKey();
-      patternLevel.put(target, Level.toLevel(loggerEntry.getValue()));
-      patterns.put(target, Pattern.compile(target));
-    }
-
-    if (!patternLevel.isEmpty()) {
-      @SuppressWarnings("unchecked")
-      Enumeration<Logger> loggerEnumeration = LogManager.getCurrentLoggers();
-      while (loggerEnumeration.hasMoreElements()) {
-        Logger classLogger = loggerEnumeration.nextElement();
-        Level oldLevel = classLogger.getLevel();
-        Level newLevel = getLevelFor(classLogger.getName());
-        if (newLevel != null && (oldLevel == null || !newLevel.equals(oldLevel))) {
-          LOG.info("changing level of " + classLogger.getName() + " to " + newLevel);
-          classLogger.setLevel(newLevel);
-        }
-      }
-    }
-  }
-
-  @Override
-  public Logger makeNewLoggerInstance(String name)
-  {
-    Logger newInstance = new Logger(name);
-    Level level = getLevelFor(name);
-    if (level != null) {
-      newInstance.setLevel(level);
-    }
-    loggerMap.put(name, newInstance);
-    return newInstance;
-  }
-
-  private synchronized Level getLevelFor(String name)
-  {
-    if (patternLevel.isEmpty()) {
-      return null;
-    }
-    String longestPatternKey = null;
-    for (String partternKey : patternLevel.keySet()) {
-      Pattern pattern = patterns.get(partternKey);
-      if (pattern.matcher(name).matches() && (longestPatternKey == null || longestPatternKey.length() < partternKey.length())) {
-        longestPatternKey = partternKey;
-      }
-    }
-    if (longestPatternKey != null) {
-      return patternLevel.get(longestPatternKey);
-    }
-    return null;
-  }
-
-  public synchronized ImmutableMap<String, String> getClassesMatching(@Nonnull String searchKey)
-  {
-    Pattern searchPattern = Pattern.compile(searchKey);
-    Map<String, String> matchedClasses = Maps.newHashMap();
-    @SuppressWarnings("unchecked")
-    Enumeration<Logger> loggerEnumeration = LogManager.getCurrentLoggers();
-    while (loggerEnumeration.hasMoreElements()) {
-      Logger logger = loggerEnumeration.nextElement();
-      if (searchPattern.matcher(logger.getName()).matches()) {
-        Level level = logger.getLevel();
-        matchedClasses.put(logger.getName(), level == null ? "" : level.toString());
-      }
-    }
-    return ImmutableMap.copyOf(matchedClasses);
-  }
-
-  private static class RepositorySelectorImpl implements RepositorySelector
-  {
-
-    private boolean initialized;
-    private Logger guard;
-    private Hierarchy hierarchy;
-
-    private RepositorySelectorImpl()
-    {
-      initialized = false;
-    }
-
-    private void initialize()
-    {
-      if (!initialized) {
-        LOG.debug("initializing logger repository selector impl");
-        guard = LogManager.getRootLogger();
-        LogManager.setRepositorySelector(this, guard);
-        hierarchy = new LoggerRepositoryImpl(guard);
-        initialized = true;
-      }
-    }
-
-    @Override
-    public LoggerRepository getLoggerRepository()
-    {
-      return hierarchy;
-    }
-  }
-
-  private static class LoggerRepositoryImpl extends Hierarchy
-  {
-    /**
-     * Create a new logger hierarchy.
-     *
-     * @param root The root of the new hierarchy.
-     */
-    private LoggerRepositoryImpl(Logger root)
-    {
-      super(root);
-    }
-
-    @Override
-    public Logger getLogger(String name)
-    {
-      return super.getLogger(name, DTLoggerFactory.getInstance());
-    }
-  }
-
-  private static final Logger LOG = LogManager.getLogger(DTLoggerFactory.class);
-}

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
----------------------------------------------------------------------
diff --git a/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java b/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
new file mode 100644
index 0000000..5ec5af8
--- /dev/null
+++ b/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
@@ -0,0 +1,101 @@
+/**
+ * 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.log4j;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+import com.datatorrent.stram.StreamingAppMaster;
+import com.datatorrent.stram.api.StramEvent;
+import com.datatorrent.stram.client.DTConfiguration;
+import com.datatorrent.stram.engine.StreamingContainer;
+
+public class DTLoggerFactoryTest
+{
+
+  @BeforeClass
+  public static void setup() throws Exception
+  {
+    System.setProperty(DTLoggerFactory.DT_LOGGERS_LEVEL, "com.datatorrent.stram.client.*:INFO,com.datatorrent.stram.api.*:DEBUG");
+    Field f = DTLoggerFactory.class.getDeclaredField("initialized");
+    f.setAccessible(true);
+    f.set(DTLoggerFactory.getInstance(), false);
+    DTLoggerFactory.getInstance().initialize();
+  }
+
+  @Test
+  public void test()
+  {
+    LoggerFactory.getLogger(DTConfiguration.class);
+    LoggerFactory.getLogger(StramEvent.class);
+    LoggerFactory.getLogger(StreamingAppMaster.class);
+
+    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
+    Assert.assertEquals(dtConfigLogger.getLevel(), Level.INFO);
+
+    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
+    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
+
+    org.apache.log4j.Logger streamingAppMasterLogger = LogManager.getLogger(StreamingAppMaster.class);
+    Assert.assertNull(streamingAppMasterLogger.getLevel());
+  }
+
+  @Test
+  public void test1()
+  {
+    Map<String, String> changes = Maps.newHashMap();
+    changes.put("com.datatorrent.*", "DEBUG");
+    changes.put("com.datatorrent.stram.engine.*", "ERROR");
+    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
+
+    LoggerFactory.getLogger(DTConfiguration.class);
+    LoggerFactory.getLogger(StramEvent.class);
+
+    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
+    Assert.assertEquals(dtConfigLogger.getLevel(), Level.DEBUG);
+
+    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
+    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
+
+    LoggerFactory.getLogger(StreamingContainer.class);
+    org.apache.log4j.Logger stramChildLogger = LogManager.getLogger(StreamingContainer.class);
+    Assert.assertEquals(stramChildLogger.getLevel(), Level.ERROR);
+  }
+
+  @Test
+  public void testGetPatternLevels()
+  {
+    Map<String, String> changes = Maps.newHashMap();
+    changes.put("com.datatorrent.io.fs.*", "DEBUG");
+    changes.put("com.datatorrent.io.*", "ERROR");
+    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
+
+    Map<String, String> levels = DTLoggerFactory.getInstance().getPatternLevels();
+
+    Assert.assertEquals(levels.get("com.datatorrent.io.fs.*"), "DEBUG");
+    Assert.assertEquals(levels.get("com.datatorrent.io.*"), "ERROR");
+  }
+}

http://git-wip-us.apache.org/repos/asf/apex-core/blob/80461746/engine/src/test/java/org/apache/log4j/DTLoggerFactoryTest.java
----------------------------------------------------------------------
diff --git a/engine/src/test/java/org/apache/log4j/DTLoggerFactoryTest.java b/engine/src/test/java/org/apache/log4j/DTLoggerFactoryTest.java
deleted file mode 100644
index 5ec5af8..0000000
--- a/engine/src/test/java/org/apache/log4j/DTLoggerFactoryTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.log4j;
-
-import java.lang.reflect.Field;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-import com.datatorrent.stram.StreamingAppMaster;
-import com.datatorrent.stram.api.StramEvent;
-import com.datatorrent.stram.client.DTConfiguration;
-import com.datatorrent.stram.engine.StreamingContainer;
-
-public class DTLoggerFactoryTest
-{
-
-  @BeforeClass
-  public static void setup() throws Exception
-  {
-    System.setProperty(DTLoggerFactory.DT_LOGGERS_LEVEL, "com.datatorrent.stram.client.*:INFO,com.datatorrent.stram.api.*:DEBUG");
-    Field f = DTLoggerFactory.class.getDeclaredField("initialized");
-    f.setAccessible(true);
-    f.set(DTLoggerFactory.getInstance(), false);
-    DTLoggerFactory.getInstance().initialize();
-  }
-
-  @Test
-  public void test()
-  {
-    LoggerFactory.getLogger(DTConfiguration.class);
-    LoggerFactory.getLogger(StramEvent.class);
-    LoggerFactory.getLogger(StreamingAppMaster.class);
-
-    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
-    Assert.assertEquals(dtConfigLogger.getLevel(), Level.INFO);
-
-    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
-    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
-
-    org.apache.log4j.Logger streamingAppMasterLogger = LogManager.getLogger(StreamingAppMaster.class);
-    Assert.assertNull(streamingAppMasterLogger.getLevel());
-  }
-
-  @Test
-  public void test1()
-  {
-    Map<String, String> changes = Maps.newHashMap();
-    changes.put("com.datatorrent.*", "DEBUG");
-    changes.put("com.datatorrent.stram.engine.*", "ERROR");
-    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
-
-    LoggerFactory.getLogger(DTConfiguration.class);
-    LoggerFactory.getLogger(StramEvent.class);
-
-    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
-    Assert.assertEquals(dtConfigLogger.getLevel(), Level.DEBUG);
-
-    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
-    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
-
-    LoggerFactory.getLogger(StreamingContainer.class);
-    org.apache.log4j.Logger stramChildLogger = LogManager.getLogger(StreamingContainer.class);
-    Assert.assertEquals(stramChildLogger.getLevel(), Level.ERROR);
-  }
-
-  @Test
-  public void testGetPatternLevels()
-  {
-    Map<String, String> changes = Maps.newHashMap();
-    changes.put("com.datatorrent.io.fs.*", "DEBUG");
-    changes.put("com.datatorrent.io.*", "ERROR");
-    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
-
-    Map<String, String> levels = DTLoggerFactory.getInstance().getPatternLevels();
-
-    Assert.assertEquals(levels.get("com.datatorrent.io.fs.*"), "DEBUG");
-    Assert.assertEquals(levels.get("com.datatorrent.io.*"), "ERROR");
-  }
-}


[2/2] apex-core git commit: APEXCORE-169 - instantiating DTLoggerFactory during test causes incorrect logging behavior

Posted by th...@apache.org.
APEXCORE-169 - instantiating DTLoggerFactory during test causes incorrect logging behavior


Project: http://git-wip-us.apache.org/repos/asf/apex-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/apex-core/commit/9c48c41e
Tree: http://git-wip-us.apache.org/repos/asf/apex-core/tree/9c48c41e
Diff: http://git-wip-us.apache.org/repos/asf/apex-core/diff/9c48c41e

Branch: refs/heads/master
Commit: 9c48c41e989b917a9e6c59e3fb284432cd1664d3
Parents: 8046174
Author: Vlad Rozov <v....@datatorrent.com>
Authored: Thu Aug 25 13:34:33 2016 -0700
Committer: Vlad Rozov <v....@datatorrent.com>
Committed: Thu Aug 25 13:34:33 2016 -0700

----------------------------------------------------------------------
 .../com/datatorrent/stram/util/LoggerUtil.java  | 298 ++++++++++---------
 .../datatorrent/stram/util/LoggerUtilTest.java  | 173 +++++++----
 2 files changed, 282 insertions(+), 189 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/apex-core/blob/9c48c41e/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
----------------------------------------------------------------------
diff --git a/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java b/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
index 04e6856..e774bea 100644
--- a/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
+++ b/engine/src/main/java/com/datatorrent/stram/util/LoggerUtil.java
@@ -16,95 +16,202 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.log4j;
+package com.datatorrent.stram.util;
 
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
 import java.util.regex.Pattern;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
+import org.apache.log4j.Appender;
+import org.apache.log4j.Category;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.DefaultRepositorySelector;
+import org.apache.log4j.spi.HierarchyEventListener;
 import org.apache.log4j.spi.LoggerFactory;
 import org.apache.log4j.spi.LoggerRepository;
-import org.apache.log4j.spi.RepositorySelector;
 
 import com.google.common.base.Function;
-import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 
-/**
- * An implementation of {@link LoggerFactory}
- *
- * @since 1.0.2
- */
-public class DTLoggerFactory implements LoggerFactory
+public class LoggerUtil
 {
-  public static final String DT_LOGGERS_LEVEL = "dt.loggers.level";
 
-  private static DTLoggerFactory SINGLETON;
+  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LoggerUtil.class);
 
-  public static synchronized DTLoggerFactory getInstance()
+  private static final Map<String, Level> patternLevel = Maps.newHashMap();
+  private static final Map<String, Pattern> patterns = Maps.newHashMap();
+  private static final Function<Level, String> levelToString = new Function<Level, String>()
   {
-    if (SINGLETON == null) {
-      SINGLETON = new DTLoggerFactory();
+    @Override
+    public String apply(@Nullable Level input)
+    {
+      return input == null ? "" : input.toString();
     }
-    return SINGLETON;
-  }
-
-  private final ConcurrentMap<String, Logger> loggerMap;
-  private final Map<String, Level> patternLevel;
+  };
 
-  public ImmutableMap<String, String> getPatternLevels()
+  private static class DelegatingLoggerRepository implements LoggerRepository
   {
-    return ImmutableMap.copyOf(Maps.transformValues(patternLevel, new Function<Level, String>()
+    private static class DefaultLoggerFactory implements LoggerFactory
     {
+      private static class DefaultLogger extends Logger
+      {
+        public DefaultLogger(String name)
+        {
+          super(name);
+        }
+      }
+
       @Override
-      public String apply(Level input)
+      public Logger makeNewLoggerInstance(String name)
       {
-        return input == null ? "" : input.toString();
+        Logger logger = new DefaultLogger(name);
+        Level level = getLevelFor(name);
+        if (level != null) {
+          logger.setLevel(level);
+        }
+        return logger;
       }
-    }));
-  }
+    }
 
-  private final Map<String, Pattern> patterns;
-  private boolean initialized = false;
+    private final LoggerFactory loggerFactory = new DefaultLoggerFactory();
+    private final LoggerRepository loggerRepository;
 
-  private DTLoggerFactory()
-  {
-    loggerMap = Maps.newConcurrentMap();
-    patternLevel = Maps.newHashMap();
-    patterns = Maps.newHashMap();
+    private DelegatingLoggerRepository(LoggerRepository loggerRepository)
+    {
+      this.loggerRepository = loggerRepository;
+    }
+
+    @Override
+    public void addHierarchyEventListener(HierarchyEventListener listener)
+    {
+      loggerRepository.addHierarchyEventListener(listener);
+    }
+
+    @Override
+    public boolean isDisabled(int level)
+    {
+      return loggerRepository.isDisabled(level);
+    }
+
+    @Override
+    public void setThreshold(Level level)
+    {
+      loggerRepository.setThreshold(level);
+    }
+
+    @Override
+    public void setThreshold(String val)
+    {
+      loggerRepository.setThreshold(val);
+    }
+
+    @Override
+    public void emitNoAppenderWarning(Category cat)
+    {
+      loggerRepository.emitNoAppenderWarning(cat);
+    }
+
+    @Override
+    public Level getThreshold()
+    {
+      return loggerRepository.getThreshold();
+    }
+
+    @Override
+    public Logger getLogger(String name)
+    {
+      return loggerRepository.getLogger(name, loggerFactory);
+    }
+
+    @Override
+    public Logger getLogger(String name, LoggerFactory factory)
+    {
+      return loggerRepository.getLogger(name, factory);
+    }
+
+    @Override
+    public Logger getRootLogger()
+    {
+      return loggerRepository.getRootLogger();
+    }
+
+    @Override
+    public Logger exists(String name)
+    {
+      return loggerRepository.exists(name);
+    }
+
+    @Override
+    public void shutdown()
+    {
+      loggerRepository.shutdown();
+    }
+
+    @Override
+    public Enumeration<Logger> getCurrentLoggers()
+    {
+      return loggerRepository.getCurrentLoggers();
+    }
+
+    @Override
+    public Enumeration<Logger> getCurrentCategories()
+    {
+      return loggerRepository.getCurrentCategories();
+    }
+
+    @Override
+    public void fireAddAppenderEvent(Category logger, Appender appender)
+    {
+      loggerRepository.fireAddAppenderEvent(logger, appender);
+    }
+
+    @Override
+    public void resetConfiguration()
+    {
+      loggerRepository.resetConfiguration();
+    }
   }
 
-  public synchronized void initialize()
+  static {
+    logger.debug("initializing LoggerUtil");
+    LogManager.setRepositorySelector(new DefaultRepositorySelector(new DelegatingLoggerRepository(LogManager.getLoggerRepository())), null);
+  }
+
+  private static synchronized Level getLevelFor(String name)
   {
-    if (!initialized) {
-      LOG.debug("initializing DT Logger Factory");
-      new RepositorySelectorImpl().initialize();
-      String loggersLevel = System.getProperty(DT_LOGGERS_LEVEL);
-      if (!Strings.isNullOrEmpty(loggersLevel)) {
-        Map<String, String> targetChanges = Maps.newHashMap();
-        String[] targets = loggersLevel.split(",");
-        for (String target : targets) {
-          String[] parts = target.split(":");
-          targetChanges.put(parts[0], parts[1]);
-        }
-        changeLoggersLevel(targetChanges);
+    if (patternLevel.isEmpty()) {
+      return null;
+    }
+    String longestPatternKey = null;
+    for (String patternKey : patternLevel.keySet()) {
+      Pattern pattern = patterns.get(patternKey);
+      if (pattern.matcher(name).matches() && (longestPatternKey == null || longestPatternKey.length() < patternKey.length())) {
+        longestPatternKey = patternKey;
       }
-      initialized = true;
-    } else {
-      LOG.warn("DT Logger Factory already initialized.");
     }
+    if (longestPatternKey != null) {
+      return patternLevel.get(longestPatternKey);
+    }
+    return null;
   }
 
-  public synchronized void changeLoggersLevel(@Nonnull Map<String, String> targetChanges)
+  public static ImmutableMap<String, String> getPatternLevels()
   {
-    /*remove existing patterns which are subsets of new patterns. for eg. if x.y.z.* will be removed if
-    there is x.y.* in the target changes.
-    */
+    return ImmutableMap.copyOf(Maps.transformValues(patternLevel, levelToString));
+  }
+
+  public static synchronized void changeLoggersLevel(@Nonnull Map<String, String> targetChanges)
+  {
+    /* remove existing patterns which are subsets of new patterns. for eg. if x.y.z.* will be removed if
+     *  there is x.y.* in the target changes.
+     */
     for (Map.Entry<String, String> changeEntry : targetChanges.entrySet()) {
       Iterator<Map.Entry<String, Pattern>> patternsIterator = patterns.entrySet().iterator();
       while ((patternsIterator.hasNext())) {
@@ -146,44 +253,14 @@ public class DTLoggerFactory implements LoggerFactory
         Level oldLevel = classLogger.getLevel();
         Level newLevel = getLevelFor(classLogger.getName());
         if (newLevel != null && (oldLevel == null || !newLevel.equals(oldLevel))) {
-          LOG.info("changing level of " + classLogger.getName() + " to " + newLevel);
+          logger.info("changing level of {} to {}", classLogger.getName(), newLevel);
           classLogger.setLevel(newLevel);
         }
       }
     }
   }
 
-  @Override
-  public Logger makeNewLoggerInstance(String name)
-  {
-    Logger newInstance = new Logger(name);
-    Level level = getLevelFor(name);
-    if (level != null) {
-      newInstance.setLevel(level);
-    }
-    loggerMap.put(name, newInstance);
-    return newInstance;
-  }
-
-  private synchronized Level getLevelFor(String name)
-  {
-    if (patternLevel.isEmpty()) {
-      return null;
-    }
-    String longestPatternKey = null;
-    for (String partternKey : patternLevel.keySet()) {
-      Pattern pattern = patterns.get(partternKey);
-      if (pattern.matcher(name).matches() && (longestPatternKey == null || longestPatternKey.length() < partternKey.length())) {
-        longestPatternKey = partternKey;
-      }
-    }
-    if (longestPatternKey != null) {
-      return patternLevel.get(longestPatternKey);
-    }
-    return null;
-  }
-
-  public synchronized ImmutableMap<String, String> getClassesMatching(@Nonnull String searchKey)
+  public static synchronized ImmutableMap<String, String> getClassesMatching(@Nonnull String searchKey)
   {
     Pattern searchPattern = Pattern.compile(searchKey);
     Map<String, String> matchedClasses = Maps.newHashMap();
@@ -198,55 +275,4 @@ public class DTLoggerFactory implements LoggerFactory
     }
     return ImmutableMap.copyOf(matchedClasses);
   }
-
-  private static class RepositorySelectorImpl implements RepositorySelector
-  {
-
-    private boolean initialized;
-    private Logger guard;
-    private Hierarchy hierarchy;
-
-    private RepositorySelectorImpl()
-    {
-      initialized = false;
-    }
-
-    private void initialize()
-    {
-      if (!initialized) {
-        LOG.debug("initializing logger repository selector impl");
-        guard = LogManager.getRootLogger();
-        LogManager.setRepositorySelector(this, guard);
-        hierarchy = new LoggerRepositoryImpl(guard);
-        initialized = true;
-      }
-    }
-
-    @Override
-    public LoggerRepository getLoggerRepository()
-    {
-      return hierarchy;
-    }
-  }
-
-  private static class LoggerRepositoryImpl extends Hierarchy
-  {
-    /**
-     * Create a new logger hierarchy.
-     *
-     * @param root The root of the new hierarchy.
-     */
-    private LoggerRepositoryImpl(Logger root)
-    {
-      super(root);
-    }
-
-    @Override
-    public Logger getLogger(String name)
-    {
-      return super.getLogger(name, DTLoggerFactory.getInstance());
-    }
-  }
-
-  private static final Logger LOG = LogManager.getLogger(DTLoggerFactory.class);
 }

http://git-wip-us.apache.org/repos/asf/apex-core/blob/9c48c41e/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
----------------------------------------------------------------------
diff --git a/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java b/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
index 5ec5af8..2ad3f4a 100644
--- a/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
+++ b/engine/src/test/java/com/datatorrent/stram/util/LoggerUtilTest.java
@@ -16,86 +16,153 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.log4j;
+package com.datatorrent.stram.util;
 
-import java.lang.reflect.Field;
 import java.util.Map;
 
-import org.junit.Assert;
 import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
+import org.junit.runners.MethodSorters;
 import org.slf4j.LoggerFactory;
 
+import org.apache.log4j.Category;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
 import com.google.common.collect.Maps;
 
-import com.datatorrent.stram.StreamingAppMaster;
-import com.datatorrent.stram.api.StramEvent;
-import com.datatorrent.stram.client.DTConfiguration;
-import com.datatorrent.stram.engine.StreamingContainer;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
-public class DTLoggerFactoryTest
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class LoggerUtilTest
 {
+  private static final org.slf4j.Logger logger = LoggerFactory.getLogger(LoggerUtilTest.class);
 
   @BeforeClass
   public static void setup() throws Exception
   {
-    System.setProperty(DTLoggerFactory.DT_LOGGERS_LEVEL, "com.datatorrent.stram.client.*:INFO,com.datatorrent.stram.api.*:DEBUG");
-    Field f = DTLoggerFactory.class.getDeclaredField("initialized");
-    f.setAccessible(true);
-    f.set(DTLoggerFactory.getInstance(), false);
-    DTLoggerFactory.getInstance().initialize();
+    logger.debug("Logger repository before LoggerUtil.changeLoggersLevel() {}", LogManager.getLoggerRepository());
+    LoggerUtil.changeLoggersLevel(Maps.<String, String>newHashMap());
+    logger.debug("Logger repository after LoggerUtil.changeLoggersLevel() {}", LogManager.getLoggerRepository());
   }
 
   @Test
-  public void test()
+  public void testGetPatternLevels()
   {
-    LoggerFactory.getLogger(DTConfiguration.class);
-    LoggerFactory.getLogger(StramEvent.class);
-    LoggerFactory.getLogger(StreamingAppMaster.class);
-
-    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
-    Assert.assertEquals(dtConfigLogger.getLevel(), Level.INFO);
-
-    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
-    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
-
-    org.apache.log4j.Logger streamingAppMasterLogger = LogManager.getLogger(StreamingAppMaster.class);
-    Assert.assertNull(streamingAppMasterLogger.getLevel());
+    Map<String, String> changes = Maps.newHashMap();
+    changes.put("_.org.apache.*", "WARN");
+    changes.put("_.com.datatorrent.io.fs.*", "DEBUG");
+    changes.put("_.com.datatorrent.io.*", "ERROR");
+    LoggerUtil.changeLoggersLevel(changes);
+
+    Map<String, String> levels = LoggerUtil.getPatternLevels();
+
+    assertEquals(3, levels.size());
+    assertEquals(levels.get("_.org.apache.*"), "WARN");
+    assertEquals(levels.get("_.com.datatorrent.io.fs.*"), "DEBUG");
+    assertEquals(levels.get("_.com.datatorrent.io.*"), "ERROR");
+
+    changes.clear();
+    changes.put("_.com.datatorrent.*", "WARN");
+    LoggerUtil.changeLoggersLevel(changes);
+
+    levels = LoggerUtil.getPatternLevels();
+    assertEquals(2, levels.size());
+    assertEquals(levels.get("_.org.apache.*"), "WARN");
+    assertNull(levels.get("_.com.datatorrent.io.fs.*"));
+    assertNull(levels.get("_.com.datatorrent.io.*"));
+    assertEquals(levels.get("_.com.datatorrent.*"), "WARN");
   }
 
   @Test
-  public void test1()
+  public void testLoggerLevels()
   {
-    Map<String, String> changes = Maps.newHashMap();
-    changes.put("com.datatorrent.*", "DEBUG");
-    changes.put("com.datatorrent.stram.engine.*", "ERROR");
-    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
-
-    LoggerFactory.getLogger(DTConfiguration.class);
-    LoggerFactory.getLogger(StramEvent.class);
+    org.slf4j.Logger sl4jLogger;
+    org.apache.log4j.Logger log4jLogger;
 
-    org.apache.log4j.Logger dtConfigLogger = LogManager.getLogger(DTConfiguration.class);
-    Assert.assertEquals(dtConfigLogger.getLevel(), Level.DEBUG);
-
-    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger(StramEvent.class);
-    Assert.assertEquals(stramEventLogger.getLevel(), Level.DEBUG);
-
-    LoggerFactory.getLogger(StreamingContainer.class);
-    org.apache.log4j.Logger stramChildLogger = LogManager.getLogger(StreamingContainer.class);
-    Assert.assertEquals(stramChildLogger.getLevel(), Level.ERROR);
+    Map<String, String> changes = Maps.newHashMap();
+    changes.put("_.org.apache.*", "WARN");
+    changes.put("_.com.datatorrent.*", "WARN");
+    changes.put("_.com.datatorrent.stram.client.*", "INFO");
+    changes.put("_.com.datatorrent.stram.api.*", "DEBUG");
+    LoggerUtil.changeLoggersLevel(changes);
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.client.DTConfiguration");
+    assertTrue(sl4jLogger.isInfoEnabled());
+    assertFalse(sl4jLogger.isDebugEnabled());
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.api.StramEvent");
+    assertTrue(sl4jLogger.isInfoEnabled());
+    assertTrue(sl4jLogger.isDebugEnabled());
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.StreamingAppMaster");
+    assertFalse(sl4jLogger.isInfoEnabled());
+    assertFalse(sl4jLogger.isDebugEnabled());
+
+    log4jLogger = LogManager.getLogger("_.com.datatorrent.stram.client.DTConfiguration");
+    assertSame(log4jLogger.getLevel(), Level.INFO);
+    assertSame(log4jLogger.getEffectiveLevel(), Level.INFO);
+
+    org.apache.log4j.Logger stramEventLogger = LogManager.getLogger("_.com.datatorrent.stram.api.StramEvent");
+    assertSame(stramEventLogger.getLevel(), Level.DEBUG);
+    assertSame(stramEventLogger.getEffectiveLevel(), Level.DEBUG);
+
+    org.apache.log4j.Logger streamingAppMasterLogger = LogManager.getLogger("_.com.datatorrent.stram.StreamingAppMaster");
+    assertSame(streamingAppMasterLogger.getLevel(), Level.WARN);
+    assertSame(streamingAppMasterLogger.getEffectiveLevel(), Level.WARN);
+
+    changes.clear();
+    changes.put("_.com.datatorrent.*", "DEBUG");
+    changes.put("_.com.datatorrent.stram.engine.*", "ERROR");
+    LoggerUtil.changeLoggersLevel(changes);
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.client.DTConfiguration");
+    assertTrue(sl4jLogger.isInfoEnabled());
+    assertTrue(sl4jLogger.isDebugEnabled());
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.api.StramEvent");
+    assertTrue(sl4jLogger.isInfoEnabled());
+    assertTrue(sl4jLogger.isDebugEnabled());
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.StreamingAppMaster");
+    assertTrue(sl4jLogger.isInfoEnabled());
+    assertTrue(sl4jLogger.isDebugEnabled());
+
+    sl4jLogger = LoggerFactory.getLogger("_.com.datatorrent.stram.engine.StreamingContainer");
+    assertFalse(sl4jLogger.isInfoEnabled());
+    assertFalse(sl4jLogger.isDebugEnabled());
+
+    log4jLogger = LogManager.getLogger("_.com.datatorrent.stram.client.DTConfiguration");
+    assertSame(log4jLogger.getLevel(), Level.DEBUG);
+    assertSame(log4jLogger.getEffectiveLevel(), Level.DEBUG);
+
+    log4jLogger = LogManager.getLogger("_.com.datatorrent.stram.api.StramEvent");
+    assertSame(log4jLogger.getLevel(), Level.DEBUG);
+    assertSame(log4jLogger.getEffectiveLevel(), Level.DEBUG);
+
+    log4jLogger = LogManager.getLogger("_.com.datatorrent.stram.StreamingAppMaster");
+    assertSame(log4jLogger.getLevel(), Level.DEBUG);
+    assertSame(log4jLogger.getEffectiveLevel(), Level.DEBUG);
+
+    log4jLogger = LogManager.getLogger("_.com.datatorrent.stram.engine.StreamingContainer");
+    assertSame(log4jLogger.getLevel(), Level.ERROR);
+    assertSame(log4jLogger.getEffectiveLevel(), Level.ERROR);
   }
 
   @Test
-  public void testGetPatternLevels()
+  public void testParentLevel()
   {
-    Map<String, String> changes = Maps.newHashMap();
-    changes.put("com.datatorrent.io.fs.*", "DEBUG");
-    changes.put("com.datatorrent.io.*", "ERROR");
-    DTLoggerFactory.getInstance().changeLoggersLevel(changes);
-
-    Map<String, String> levels = DTLoggerFactory.getInstance().getPatternLevels();
-
-    Assert.assertEquals(levels.get("com.datatorrent.io.fs.*"), "DEBUG");
-    Assert.assertEquals(levels.get("com.datatorrent.io.*"), "ERROR");
+    org.apache.log4j.Logger log4jLogger = LogManager.getLogger("com.datatorrent.stram.util.Unknown");
+    assertNull(log4jLogger.getLevel());
+    Category parent = log4jLogger.getParent();
+    while (parent.getLevel() == null) {
+      parent = parent.getParent();
+    }
+    assertSame(log4jLogger.getEffectiveLevel(), parent.getLevel());
   }
 }