You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by bb...@apache.org on 2014/07/14 03:20:13 UTC

svn commit: r1610333 - in /logging/log4j/log4j2/branches/LOG4J2-609: log4j-api/src/main/java/org/apache/logging/log4j/status/ log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/ log4j-core/src/main/java/org/apache/logging/log4j/core/j...

Author: bbrouwer
Date: Mon Jul 14 01:20:13 2014
New Revision: 1610333

URL: http://svn.apache.org/r1610333
Log:
Try to simplify the StatusLogger stuff

Added:
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java   (with props)
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java   (with props)
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java   (with props)
Removed:
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusFilter.java
Modified:
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueAppenderTest.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueFailoverTest.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueTest.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicFailoverTest.java
    logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicTest.java

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java Mon Jul 14 01:20:13 2014
@@ -17,21 +17,17 @@
 package org.apache.logging.log4j.status;
 
 import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
@@ -60,23 +56,19 @@ public final class StatusLogger extends 
 
     private static final int MAX_ENTRIES = PROPS.getIntegerProperty(MAX_STATUS_ENTRIES, 200);
 
-    private static final String DEFAULT_STATUS_LEVEL = PROPS.getStringProperty("log4j2.StatusLogger.level");
-
     private static final StatusLogger STATUS_LOGGER = new StatusLogger();
 
-    private final Lock lock = new ReentrantLock();
-    private final LoggerFilters sysOut;
-    private final LoggerFilters sysErr;
-    private final Map<File, LoggerFilters> files = new HashMap<File, LoggerFilters>();
-    private final Collection<ListenerLevel> listeners = new CopyOnWriteArrayList<ListenerLevel>();
-    private final Queue<StatusData> messages = new BoundedQueue<StatusData>(MAX_ENTRIES);
+    private final SimpleLogger logger;
+
+    private final Collection<StatusListener> listeners = new CopyOnWriteArrayList<StatusListener>();
+    private final ReadWriteLock listenersLock = new ReentrantReadWriteLock();
 
-    private Level defaultLogLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, Level.WARN);
-    private Level registeredLogLevel = null;
+    private final Queue<StatusData> messages = new BoundedQueue<StatusData>(MAX_ENTRIES);
+    private final Lock msgLock = new ReentrantLock();
 
     private StatusLogger() {
-        sysErr = new LoggerFilters("System.err", defaultLogLevel, System.err);
-        sysOut = new LoggerFilters("System.out", Level.OFF, System.out);
+        this.logger = new SimpleLogger("StatusLogger", Level.ERROR, false, true, false, false, Strings.EMPTY, null, PROPS,
+            System.err);
     }
 
     /**
@@ -88,167 +80,56 @@ public final class StatusLogger extends 
     }
 
     public void setLevel(final Level level) {
-        lock.lock();
-        try {
-            defaultLogLevel = level;
-            if (!hasRegistrations()) {
-                sysErr.logger.setLevel(level);
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-    public void registerSystemOutFilter(final StatusFilter filter, final Level level) {
-        registerFilter(sysOut, filter, level);
-    }
-
-    public boolean removeSystemOutFilter(final StatusFilter filter) {
-        return removeFilter(sysOut, filter);
-    }
-
-    public void registerSystemErrFilter(final StatusFilter filter, final Level level) {
-        registerFilter(sysErr, filter, level);
-    }
-
-    public boolean removeSystemErrFilter(final StatusFilter filter) {
-        return removeFilter(sysErr, filter);
-    }
-
-    public void registerFileFilter(final File file, final StatusFilter filter, final Level level) throws FileNotFoundException {
-        lock.lock();
-        try {
-            LoggerFilters filtered = files.get(file);
-            if (filtered == null) {
-                filtered = new LoggerFilters(file.toString(), level, new PrintStream(file));
-                files.put(file, filtered);
-            }
-            registerFilter(filtered, filter, level);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    public boolean removeFileFilter(final File file, final StatusFilter filter) {
-        lock.lock();
-        try {
-            LoggerFilters filtered = files.get(file);
-            if (filtered != null && filtered.remove(filter)) {
-                if (filtered.isEmpty()) {
-                    files.remove(file);
-                    closeSilently(filtered);
-                }
-                updateRegisteredLevel();
-                return true;
-            }
-        } finally {
-            lock.unlock();
-        }
-        return false;
-    }
-
-    private void registerFilter(final LoggerFilters filtered, final StatusFilter filter, final Level level) {
-        lock.lock();
-        try {
-            filtered.add(filter, level);
-            updateRegisteredLevel(level);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    private boolean removeFilter(final LoggerFilters filtered, final StatusFilter filter) {
-        lock.lock();
-        try {
-            if (filtered.remove(filter)) {
-                updateRegisteredLevel();
-                return true;
-            }
-        } finally {
-            lock.unlock();
-        }
-        return false;
+        logger.setLevel(level);
     }
 
     /**
      * Register a new listener.
      * @param listener The StatusListener to register.
      */
-    public void registerListener(final StatusListener listener, final Level level) {
-        lock.lock();
+    public void registerListener(final StatusListener listener) {
+        listenersLock.writeLock().lock();
         try {
-            listeners.add(new ListenerLevel(listener, level));
-            updateRegisteredLevel(level);
+            listeners.add(listener);
         } finally {
-            lock.unlock();
+            listenersLock.writeLock().unlock();
         }
     }
+
     /**
      * Remove a StatusListener.
-     * 
      * @param listener The StatusListener to remove.
      */
-    public boolean removeListener(final StatusListener listener) {
-        lock.lock();
+    public void removeListener(final StatusListener listener) {
+        closeSilently(listener);
+        listenersLock.writeLock().lock();
         try {
-            for (final Iterator<ListenerLevel> i = listeners.iterator(); i.hasNext(); ) {
-                final ListenerLevel listenerLevel = i.next();
-                if (listenerLevel.listener == listener) {
-                    listeners.remove(listenerLevel);
-                    updateRegisteredLevel();
-                    return true;
-                }
-            }
+            listeners.remove(listener);
         } finally {
-            lock.unlock();
+            listenersLock.writeLock().unlock();
         }
-        return false;
     }
 
-    private boolean hasRegistrations() {
-        return registeredLogLevel != null;
-    }
-
-    private void updateRegisteredLevel(Level level) {
-        registeredLogLevel = leastSpecificOf(level, registeredLogLevel);
-    }
-
-    private void updateRegisteredLevel() {
-        Level level = null;
-        for (ListenerLevel listener : listeners) {
-            level = leastSpecificOf(level, listener.level);
-        }
-        level = leastSpecificOf(level, sysOut.leastSpecificLevel());
-        level = leastSpecificOf(level, sysErr.leastSpecificLevel());
-        for (LoggerFilters file : files.values()) {
-            level = leastSpecificOf(level, file.leastSpecificLevel());
-        }
-        registeredLogLevel = level;
-    }
-
-    private static Level leastSpecificOf(Level first, Level second) {
-        if (first == null) {
-            return second;
-        } else if (second == null || first.isLessSpecificThan(second)) {
-            return first;
-        }
-        return second;
+    /**
+     * Returns a thread safe Iterable for the StatusListener.
+     * @return An Iterable for the list of StatusListeners.
+     */
+    public Iterable<StatusListener> getListeners() {
+        return listeners;
     }
 
     /**
      * Clears the list of status events and listeners.
      */
     public void reset() {
-        lock.lock();
+        listenersLock.writeLock().lock();
         try {
-            listeners.clear();
-            sysOut.filters.clear();
-            sysErr.filters.clear();
-            for (LoggerFilters file : files.values()) {
-                closeSilently(file);
+            for (final StatusListener listener : listeners) {
+                closeSilently(listener);
             }
-            files.clear();
         } finally {
-            lock.unlock();
+            listeners.clear();
+            listenersLock.writeLock().unlock();
             // note this should certainly come after the unlock to avoid unnecessary nested locking
             clear();
         }
@@ -266,11 +147,11 @@ public final class StatusLogger extends 
      * @return The list of StatusData objects.
      */
     public List<StatusData> getStatusData() {
-        lock.lock();
+        msgLock.lock();
         try {
             return new ArrayList<StatusData>(messages);
         } finally {
-            lock.unlock();
+            msgLock.unlock();
         }
     }
 
@@ -278,17 +159,17 @@ public final class StatusLogger extends 
      * Clears the list of status events.
      */
     public void clear() {
-        lock.lock();
+        msgLock.lock();
         try {
             messages.clear();
         } finally {
-            lock.unlock();
+            msgLock.unlock();
         }
     }
 
     @Override
     public Level getLevel() {
-        return registeredLogLevel;
+        return logger.getLevel();
     }
 
     /**
@@ -306,36 +187,18 @@ public final class StatusLogger extends 
             element = getStackTraceElement(fqcn, Thread.currentThread().getStackTrace());
         }
         final StatusData data = new StatusData(element, level, marker, msg, t);
-        lock.lock();
+        msgLock.lock();
         try {
             messages.add(data);
         } finally {
-            lock.unlock();
+            msgLock.unlock();
         }
-        if (hasRegistrations()) {
-            logMessage(sysOut, fqcn, data);
-            logMessage(sysErr, fqcn, data);
-            for (LoggerFilters file : files.values()) {
-                logMessage(file, fqcn, data);
-            }
-            for (final ListenerLevel listener : listeners) {
-                if (listener.level.isLessSpecificThan(level)) {
-                    listener.listener.log(data);
-                }
+        if (listeners.size() > 0) {
+            for (final StatusListener listener : listeners) {
+                listener.log(data);
             }
         } else {
-            sysErr.logger.logMessage(fqcn, level, marker, msg, t);
-        }
-    }
-
-    private void logMessage(final LoggerFilters filtered, final String fqcn, final StatusData data) {
-        if (filtered.logger.isEnabled(data.getLevel())) {
-            for (FilterLevel filter : filtered.filters) {
-                if (filter.filter.isEnabled(data)) {
-                    filtered.logger.logMessage(fqcn, data.getLevel(), data.getMarker(), data.getMessage(), data.getThrowable());
-                    break;
-                }
-            }
+            logger.logMessage(fqcn, level, marker, msg, t);
         }
     }
 
@@ -385,10 +248,10 @@ public final class StatusLogger extends 
 
     @Override
     public boolean isEnabled(final Level level, final Marker marker) {
-        if (hasRegistrations()) {
-            return level.isMoreSpecificThan(registeredLogLevel);
+        if (listeners.isEmpty()) {
+            return false;
         }
-        return sysErr.logger.isEnabled(level, marker);
+        return logger.isEnabled(level, marker);
     }
 
     /**
@@ -407,77 +270,10 @@ public final class StatusLogger extends 
 
         @Override
         public boolean add(final E object) {
-            while (size() > size) {
-                poll();
+            while (messages.size() > size) {
+                messages.poll();
             }
             return super.add(object);
         }
     }
-
-    private static class LoggerFilters implements Closeable {
-        final SimpleLogger logger;
-        final Collection<FilterLevel> filters = new CopyOnWriteArrayList<FilterLevel>();
-
-        LoggerFilters(final String name, final Level level, final PrintStream out) {
-            logger = new SimpleLogger(name, level, false, true, false, false, Strings.EMPTY, null, PROPS, out);
-        }
-
-        boolean isEmpty() {
-            return filters.isEmpty();
-        }
-
-        public void close() throws IOException {
-            filters.clear();
-            logger.close();
-        }
-
-        void add(final StatusFilter filter, final Level level) {
-            filters.add(new FilterLevel(filter, level));
-            if (level.isLessSpecificThan(logger.getLevel())) {
-                logger.setLevel(level);
-            }
-        }
-
-        boolean remove(final StatusFilter filter) {
-            for (final Iterator<FilterLevel> i = filters.iterator(); i.hasNext();) {
-                final FilterLevel existing = i.next();
-                if (existing.filter == filter) {
-                    filters.remove(existing);
-                    logger.setLevel(leastSpecificLevel());
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        Level leastSpecificLevel() {
-            Level level = Level.OFF;
-            for (FilterLevel existing : filters) {
-                if (existing.level.isLessSpecificThan(level)) {
-                    level = existing.level;
-                }
-            }
-            return level;
-        }
-    }
-
-    private static class FilterLevel {
-        final StatusFilter filter;
-        final Level level;
-
-        FilterLevel(final StatusFilter filter, final Level level) {
-            this.filter = filter;
-            this.level = level;
-        }
-    }
-
-    private static class ListenerLevel {
-        final StatusListener listener;
-        final Level level;
-
-        ListenerLevel(final StatusListener listener, final Level level) {
-            this.listener = listener;
-            this.level = level;
-        }
-    }
 }

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java Mon Jul 14 01:20:13 2014
@@ -17,18 +17,11 @@
 
 package org.apache.logging.log4j.core.config.status;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.util.FileUtils;
 import org.apache.logging.log4j.status.StatusListener;
 import org.apache.logging.log4j.status.StatusLogger;
 
@@ -37,8 +30,6 @@ import org.apache.logging.log4j.status.S
  */
 public class StatusConfiguration {
 
-    @SuppressWarnings("UseOfSystemOutOrSystemErr")
-    private static final PrintStream DEFAULT_STREAM = System.out;
     private static final Level DEFAULT_STATUS = Level.ERROR;
     private static final Verbosity DEFAULT_VERBOSITY = Verbosity.QUIET;
 
@@ -47,7 +38,7 @@ public class StatusConfiguration {
 
     private volatile boolean initialized = false;
 
-    private PrintStream destination = DEFAULT_STREAM;
+    private Class<? extends StatusConsoleListener> destination = StatusStdOutListener.class;
     private Level status = DEFAULT_STATUS;
     private Verbosity verbosity = DEFAULT_VERBOSITY;
     private String[] verboseClasses;
@@ -93,35 +84,17 @@ public class StatusConfiguration {
      * @return {@code this}
      */
     public StatusConfiguration withDestination(final String destination) {
-        try {
-            this.destination = parseStreamName(destination);
-        } catch (final URISyntaxException e) {
-            this.error("Could not parse URI [" + destination + "]. Falling back to default of stdout.");
-            this.destination = DEFAULT_STREAM;
-        } catch (final FileNotFoundException e) {
-            this.error("File could not be found at [" + destination + "]. Falling back to default of stdout.");
-            this.destination = DEFAULT_STREAM;
-        }
+    	if ("out".equalsIgnoreCase(destination)) {
+    		this.destination = StatusStdOutListener.class;
+    	} else if ("err".equalsIgnoreCase(destination)) {
+    		this.destination = StatusStdErrListener.class;
+    	} else {
+    		this.error("Invalid destination [" + destination + "]. Only 'out' or 'err' are supported. Defaulting to 'out'.");
+    		this.destination = StatusStdOutListener.class;
+    	}
         return this;
     }
 
-    private PrintStream parseStreamName(final String name) throws URISyntaxException, FileNotFoundException {
-        if (name == null || name.equalsIgnoreCase("out")) {
-            return DEFAULT_STREAM;
-        }
-        if (name.equalsIgnoreCase("err")) {
-            return System.err;
-        }
-        final URI destination = FileUtils.getCorrectedFilePathUri(name);
-        final File output = FileUtils.fileFromUri(destination);
-        if (output == null) {
-            // don't want any NPEs, no sir
-            return DEFAULT_STREAM;
-        }
-        final FileOutputStream fos = new FileOutputStream(output);
-        return new PrintStream(fos, true);
-    }
-
     /**
      * Specifies the logging level by name to use for filtering StatusLogger messages.
      *
@@ -192,7 +165,7 @@ public class StatusConfiguration {
     private boolean configureExistingStatusConsoleListener() {
         boolean configured = false;
         for (final StatusListener statusListener : this.logger.getListeners()) {
-            if (statusListener instanceof StatusConsoleListener) {
+        	if (this.destination.isInstance(statusListener)) {
                 final StatusConsoleListener listener = (StatusConsoleListener) statusListener;
                 listener.setLevel(this.status);
                 if (this.verbosity == Verbosity.QUIET) {
@@ -206,11 +179,17 @@ public class StatusConfiguration {
 
 
     private void registerNewStatusConsoleListener() {
-        final StatusConsoleListener listener = new StatusConsoleListener(this.status, this.destination);
-        if (this.verbosity == Verbosity.QUIET) {
-            listener.setFilters(this.verboseClasses);
-        }
-        this.logger.registerListener(listener);
+        StatusConsoleListener listener;
+		try {
+			listener = this.destination.newInstance();
+	        listener.setLevel(this.status);
+	        if (this.verbosity == Verbosity.QUIET) {
+	            listener.setFilters(this.verboseClasses);
+	        }
+	        this.logger.registerListener(listener);
+		} catch (ReflectiveOperationException e) {
+			logger.error("Cannot create listener of type " + destination.getClass());
+		}
     }
 
     private void migrateSavedLogMessages() {

Added: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java?rev=1610333&view=auto
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java (added)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java Mon Jul 14 01:20:13 2014
@@ -0,0 +1,88 @@
+/*
+ * 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.core.config.status;
+
+import java.io.IOException;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.status.StatusData;
+import org.apache.logging.log4j.status.StatusListener;
+
+/**
+ * StatusListener that writes to the Console.
+ */
+public abstract class StatusConsoleListener implements StatusListener {
+
+    protected Level level;
+    private String[] filters = null;
+
+    /**
+     * Creates the StatusConsoleListener using the supplied Level. 
+     */
+    public StatusConsoleListener() {
+        this(Level.FATAL);
+    }
+
+    /**
+     * Creates the StatusConsoleListener using the supplied Level. 
+     * @param level The Level of status messages that should appear on the console.
+     */
+    public StatusConsoleListener(final Level level) {
+        this.level = level;
+    }
+
+    /**
+     * Sets the level to a new value.
+     * @param level The new Level.
+     */
+    public void setLevel(final Level level) {
+        this.level = level;
+    }
+
+    public Object getLevel() {
+		return level;
+	}
+
+	/**
+     * Adds package name filters to exclude.
+     * @param filters An array of package names to exclude.
+     */
+    public void setFilters(final String... filters) {
+        this.filters = filters;
+    }
+
+    protected boolean isEnabledFor(final StatusData data) {
+        if (level.isMoreSpecificThan(data.getLevel())) {
+        	return false;
+        } 
+        if (filters == null) {
+        	return true;
+        }
+        final String caller = data.getStackTraceElement().getClassName();
+        for (final String filter : filters) {
+            if (caller.startsWith(filter)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void close() throws IOException {
+        // don't close system streams
+    }
+}

Propchange: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConsoleListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java?rev=1610333&view=auto
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java (added)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java Mon Jul 14 01:20:13 2014
@@ -0,0 +1,14 @@
+package org.apache.logging.log4j.core.config.status;
+
+import org.apache.logging.log4j.status.StatusData;
+
+public class StatusStdErrListener extends StatusConsoleListener {
+
+	@Override
+	public void log(StatusData data) {
+        if (isEnabledFor(data)) {
+            System.err.println(data.getFormattedStatus());
+        }
+	}
+
+}

Propchange: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdErrListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java?rev=1610333&view=auto
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java (added)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java Mon Jul 14 01:20:13 2014
@@ -0,0 +1,14 @@
+package org.apache.logging.log4j.core.config.status;
+
+import org.apache.logging.log4j.status.StatusData;
+
+public class StatusStdOutListener extends StatusConsoleListener {
+
+	@Override
+	public void log(StatusData data) {
+        if (isEnabledFor(data)) {
+            System.out.println(data.getFormattedStatus());
+        }
+	}
+
+}

Propchange: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusStdOutListener.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/StatusLoggerAdmin.java Mon Jul 14 01:20:13 2014
@@ -63,7 +63,7 @@ public class StatusLoggerAdmin extends N
         } catch (final Exception e) {
             throw new IllegalStateException(e);
         }
-        StatusLogger.getLogger().registerListener(this, level);
+        StatusLogger.getLogger().registerListener(this);
     }
 
     private static MBeanNotificationInfo createNotificationInfo() {
@@ -97,8 +97,6 @@ public class StatusLoggerAdmin extends N
     @Override
     public void setLevel(final String level) {
         this.level = Level.toLevel(level, Level.ERROR);
-        StatusLogger.getLogger().removeListener(this);
-        StatusLogger.getLogger().registerListener(this, this.level);
     }
 
     @Override
@@ -115,13 +113,15 @@ public class StatusLoggerAdmin extends N
      */
     @Override
     public void log(final StatusData data) {
-        final Notification notifMsg = new Notification(NOTIF_TYPE_MESSAGE, getObjectName(), nextSeqNo(), now(),
-                data.getFormattedStatus());
-        sendNotification(notifMsg);
-
-        final Notification notifData = new Notification(NOTIF_TYPE_DATA, getObjectName(), nextSeqNo(), now());
-        notifData.setUserData(data);
-        sendNotification(notifData);
+        if (level.isLessSpecificThan(data.getLevel())) {
+	    	final Notification notifMsg = new Notification(NOTIF_TYPE_MESSAGE, getObjectName(), nextSeqNo(), now(),
+	                data.getFormattedStatus());
+	        sendNotification(notifMsg);
+	
+	        final Notification notifData = new Notification(NOTIF_TYPE_DATA, getObjectName(), nextSeqNo(), now());
+	        notifData.setUserData(data);
+	        sendNotification(notifData);
+        }
     }
 
     /**

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java Mon Jul 14 01:20:13 2014
@@ -16,6 +16,9 @@
  */
 package org.apache.logging.log4j.core.config;
 
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
 import java.io.File;
 import java.io.Serializable;
 
@@ -25,10 +28,10 @@ import org.apache.logging.log4j.core.App
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.FileAppender;
+import org.apache.logging.log4j.core.config.status.StatusConsoleListener;
 import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.junit.InitialLoggerContext;
-import org.apache.logging.log4j.status.StatusConsoleListener;
 import org.apache.logging.log4j.status.StatusListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.Before;
@@ -36,8 +39,6 @@ import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
-
 /**
  *
  */
@@ -68,7 +69,7 @@ public class CustomConfigurationTest {
         assertTrue("Configuration is not an XmlConfiguration", config instanceof XmlConfiguration);
         for (final StatusListener listener : StatusLogger.getLogger().getListeners()) {
             if (listener instanceof StatusConsoleListener) {
-                assertSame(listener.getStatusLevel(), Level.INFO);
+                assertSame(((StatusConsoleListener) listener).getLevel(), Level.INFO);
                 break;
             }
         }

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueAppenderTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueAppenderTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueAppenderTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueAppenderTest.java Mon Jul 14 01:20:13 2014
@@ -28,7 +28,7 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.status.StatusConsoleListener;
+import org.apache.logging.log4j.core.config.status.StatusStdOutListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -58,7 +58,8 @@ public class JmsQueueAppenderTest {
     @BeforeClass
     public static void setupClass() throws Exception {
         // MockContextFactory becomes the primary JNDI provider
-        final StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+        final StatusStdOutListener listener = new StatusStdOutListener();
+        listener.setLevel(Level.ERROR);
         StatusLogger.getLogger().registerListener(listener);
         MockContextFactory.setAsInitial();
         context = new InitialContext();

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueFailoverTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueFailoverTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueFailoverTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueFailoverTest.java Mon Jul 14 01:20:13 2014
@@ -31,7 +31,7 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.status.StatusConsoleListener;
+import org.apache.logging.log4j.core.config.status.StatusStdOutListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.AfterClass;
@@ -86,7 +86,8 @@ public class JmsQueueFailoverTest {
 
     private static void setupQueue() throws Exception {
         // MockContextFactory becomes the primary JNDI provider
-        final StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+        final StatusStdOutListener listener = new StatusStdOutListener();
+        listener.setLevel(Level.ERROR);
         StatusLogger.getLogger().registerListener(listener);
         MockContextFactory.setAsInitial();
         context = new InitialContext();

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsQueueTest.java Mon Jul 14 01:20:13 2014
@@ -31,10 +31,10 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.appender.jms.JmsQueueAppender;
+import org.apache.logging.log4j.core.config.status.StatusStdOutListener;
 import org.apache.logging.log4j.core.filter.AbstractFilter;
 import org.apache.logging.log4j.core.filter.CompositeFilter;
 import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.status.StatusConsoleListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
@@ -64,7 +64,8 @@ public class JmsQueueTest {
     @BeforeClass
     public static void setupClass() throws Exception {
         // MockContextFactory becomes the primary JNDI provider
-        final StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+        final StatusStdOutListener listener = new StatusStdOutListener();
+        listener.setLevel(Level.ERROR);
         StatusLogger.getLogger().registerListener(listener);
         MockContextFactory.setAsInitial();
         context = new InitialContext();

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicFailoverTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicFailoverTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicFailoverTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicFailoverTest.java Mon Jul 14 01:20:13 2014
@@ -31,7 +31,7 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.status.StatusConsoleListener;
+import org.apache.logging.log4j.core.config.status.StatusStdOutListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.AfterClass;
@@ -85,7 +85,8 @@ public class JmsTopicFailoverTest {
 
     private static void setupQueue() throws Exception {
         // MockContextFactory becomes the primary JNDI provider
-        final StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+        final StatusStdOutListener listener = new StatusStdOutListener();
+        listener.setLevel(Level.ERROR);
         StatusLogger.getLogger().registerListener(listener);
         MockContextFactory.setAsInitial();
         context = new InitialContext();

Modified: logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicTest.java?rev=1610333&r1=1610332&r2=1610333&view=diff
==============================================================================
--- logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicTest.java (original)
+++ logging/log4j/log4j2/branches/LOG4J2-609/log4j-core/src/test/java/org/apache/logging/log4j/core/net/jms/JmsTopicTest.java Mon Jul 14 01:20:13 2014
@@ -31,10 +31,10 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.appender.jms.JmsTopicAppender;
+import org.apache.logging.log4j.core.config.status.StatusStdOutListener;
 import org.apache.logging.log4j.core.filter.AbstractFilter;
 import org.apache.logging.log4j.core.filter.CompositeFilter;
 import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.status.StatusConsoleListener;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
@@ -64,7 +64,8 @@ public class JmsTopicTest {
     @BeforeClass
     public static void setupClass() throws Exception {
         // MockContextFactory becomes the primary JNDI provider
-        final StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+        final StatusStdOutListener listener = new StatusStdOutListener();
+        listener.setLevel(Level.ERROR);
         StatusLogger.getLogger().registerListener(listener);
         MockContextFactory.setAsInitial();
         context = new InitialContext();