SLING-4907 - Provide support for registering Filter with all configured appenders

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1692823 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/commons/log/logback/internal/FilterTracker.java b/src/main/java/org/apache/sling/commons/log/logback/internal/FilterTracker.java
index 6843cd6..2ab960b 100644
--- a/src/main/java/org/apache/sling/commons/log/logback/internal/FilterTracker.java
+++ b/src/main/java/org/apache/sling/commons/log/logback/internal/FilterTracker.java
@@ -23,6 +23,7 @@
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.filter.Filter;
+import ch.qos.logback.core.util.ContextUtil;
 import org.apache.sling.commons.log.logback.internal.util.Util;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
@@ -38,9 +39,11 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 public class FilterTracker extends ServiceTracker implements LogbackResetListener{
+    private static final String ALL_APPENDERS = "*";
     private static final String PROP_APPENDER = "appenders";
 
     private final LoggerContext loggerContext;
+    private final ContextUtil contextUtil;
     private final LogbackManager logbackManager;
     private Map<ServiceReference, FilterInfo> filters = new ConcurrentHashMap<ServiceReference, FilterInfo>();
 
@@ -48,6 +51,7 @@
         super(context, createFilter(), null);
         this.logbackManager = logbackManager;
         this.loggerContext = logbackManager.getLoggerContext();
+        this.contextUtil =  new ContextUtil(loggerContext);
         super.open();
     }
 
@@ -61,7 +65,7 @@
         FilterInfo fi = new FilterInfo(reference, f);
         filters.put(reference, fi);
         attachFilter(fi, getAppenderMap());
-        return fi;
+        return f;
     }
 
     @SuppressWarnings("unchecked")
@@ -106,25 +110,36 @@
 
     //~-----------------------------------Internal Methods
 
-    private void attachFilter(FilterInfo fi, Map<String,Appender<ILoggingEvent>> appenderMap) {
-        //TODO Support attaching a filter to all appender if the appenerName list contains '*'
-        for(String appenderName : fi.appenderNames){
+    private void attachFilter(FilterInfo fi, Map<String, Appender<ILoggingEvent>> appenderMap) {
+        if (fi.registerAgainstAllAppenders){
+            for (Appender<ILoggingEvent> appender : appenderMap.values()){
+                attachFilter(appender, fi);
+            }
+            return;
+        }
+        for (String appenderName : fi.appenderNames) {
             Appender<ILoggingEvent> appender = appenderMap.get(appenderName);
-            if(appender != null){
-                attachFilter(appender,fi);
-            }else{
-                //TODO Log warning
+            if (appender != null) {
+                attachFilter(appender, fi);
+            } else {
+                contextUtil.addWarn("No appender with name [" + appenderName + "] found " +
+                        "to which " + fi.filter + " can be attached");
             }
         }
     }
 
-    private void detachFilter(FilterInfo fi,Map<String,Appender<ILoggingEvent>> appenderMap) {
-        for(String appenderName : fi.appenderNames){
-            Appender<ILoggingEvent> appender = appenderMap.get(appenderName);
-            if(appender != null){
+    private void detachFilter(FilterInfo fi, Map<String, Appender<ILoggingEvent>> appenderMap) {
+        if (fi.registerAgainstAllAppenders){
+            for (Appender<ILoggingEvent> appender : appenderMap.values()){
                 detachFilter(appender, fi);
-            }else{
-                //TODO Log warning
+            }
+            return;
+        }
+
+        for (String appenderName : fi.appenderNames) {
+            Appender<ILoggingEvent> appender = appenderMap.get(appenderName);
+            if (appender != null) {
+                detachFilter(appender, fi);
             }
         }
     }
@@ -168,6 +183,7 @@
         final ServiceReference reference;
         final Filter<ILoggingEvent> filter;
         final Set<String> appenderNames;
+        final boolean registerAgainstAllAppenders;
 
         FilterInfo(ServiceReference reference, Filter<ILoggingEvent> filter) {
             this.reference = reference;
@@ -175,6 +191,7 @@
 
             this.appenderNames = Collections.unmodifiableSet(
                     new HashSet<String>(Util.toList(reference.getProperty(PROP_APPENDER))));
+            this.registerAgainstAllAppenders = appenderNames.contains(ALL_APPENDERS);
         }
 
         public void stop(){
diff --git a/src/test/java/org/apache/sling/commons/log/logback/integration/ITFilterSupport.java b/src/test/java/org/apache/sling/commons/log/logback/integration/ITFilterSupport.java
index eba0eed..ca45caa 100644
--- a/src/test/java/org/apache/sling/commons/log/logback/integration/ITFilterSupport.java
+++ b/src/test/java/org/apache/sling/commons/log/logback/integration/ITFilterSupport.java
@@ -59,7 +59,7 @@
 
     @Test
     public void testTurboFilter() throws Exception {
-        TestAppender ta = registerAppender("turbofilter");
+        TestAppender ta = registerAppender("turbofilter", "TestAppender");
 
         org.slf4j.Logger bar = LoggerFactory.getLogger("turbofilter.foo.bar");
         assertTrue(bar.isDebugEnabled());
@@ -98,7 +98,7 @@
 
     @Test
     public void testNormalFilter() {
-        TestAppender ta = registerAppender("filter");
+        TestAppender ta = registerAppender("filter", "TestAppender");
 
         org.slf4j.Logger bar = LoggerFactory.getLogger("filter.foo.bar");
         assertTrue(bar.isDebugEnabled());
@@ -135,11 +135,43 @@
 
         bar.debug("Test");
         assertEquals(1, ta.events.size());
-
     }
 
-    private TestAppender registerAppender(String prefix) {
-        TestAppender ta = new TestAppender();
+    @Test
+    public void filterUsingWildcard() throws Exception{
+        TestAppender ta1 = registerAppender("filterUsingWildcard1", "app1");
+        TestAppender ta2 = registerAppender("filterUsingWildcard2", "app2");
+
+        //Set additivity to false to prevent other appender like CONSOLE from
+        //interfering
+        org.slf4j.Logger baz1 = LoggerFactory.getLogger("filterUsingWildcard1.foo.baz");
+        ((ch.qos.logback.classic.Logger)baz1).setAdditive(false);
+        org.slf4j.Logger baz2 = LoggerFactory.getLogger("filterUsingWildcard2.foo.baz");
+        ((ch.qos.logback.classic.Logger)baz2).setAdditive(false);
+
+        final List<String> msgs = new ArrayList<String>();
+        Filter stf = new Filter<ILoggingEvent>(){
+            @Override
+            public FilterReply decide(ILoggingEvent event) {
+                msgs.add(event.getMessage());
+                return FilterReply.NEUTRAL;
+            }
+        };
+
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put("appenders", "*");
+        ServiceRegistration sr  = bundleContext.registerService(Filter.class.getName(), stf, props);
+
+        delay();
+
+        baz1.info("baz1-1");
+        baz2.info("baz2-1");
+
+        assertEquals(2, msgs.size());
+    }
+
+    private TestAppender registerAppender(String prefix, String appenderName) {
+        TestAppender ta = new TestAppender(appenderName);
         Dictionary<String, Object> props = new Hashtable<String, Object>();
 
         String[] loggers = {
@@ -181,6 +213,11 @@
 
     private static class TestAppender extends AppenderBase<ILoggingEvent> {
         final List<ILoggingEvent> events = new ArrayList<ILoggingEvent>();
+        final String name;
+
+        public TestAppender(String name) {
+            this.name = name;
+        }
 
         @Override
         protected void append(ILoggingEvent eventObject) {
@@ -189,7 +226,7 @@
 
         @Override
         public String getName() {
-            return "TestAppender";
+            return name;
         }
     }
 }