Author: cziegeler
Date: Mon Mar 30 11:11:34 2015
New Revision: 1670052

URL: http://svn.apache.org/r1670052
Log:
SLING-4510 : Sling LogService could provide more usable output. Apply patch 
from David Bosschaert

Added:
    sling/trunk/bundles/commons/logservice/src/test/java/org/
    sling/trunk/bundles/commons/logservice/src/test/java/org/apache/
    sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/
    
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/
    
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/
    
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/
    
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
   (with props)
Modified:
    sling/trunk/bundles/commons/logservice/pom.xml
    
sling/trunk/bundles/commons/logservice/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java

Modified: sling/trunk/bundles/commons/logservice/pom.xml
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/logservice/pom.xml?rev=1670052&r1=1670051&r2=1670052&view=diff
==============================================================================
--- sling/trunk/bundles/commons/logservice/pom.xml (original)
+++ sling/trunk/bundles/commons/logservice/pom.xml Mon Mar 30 11:11:34 2015
@@ -111,5 +111,16 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

Modified: 
sling/trunk/bundles/commons/logservice/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/logservice/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java?rev=1670052&r1=1670051&r2=1670052&view=diff
==============================================================================
--- 
sling/trunk/bundles/commons/logservice/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java
 (original)
+++ 
sling/trunk/bundles/commons/logservice/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java
 Mon Mar 30 11:11:34 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sling.commons.logservice.internal;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.LinkedHashMap;
@@ -72,6 +73,7 @@ public class LogSupport implements Synch
         0.75f, true) {
         private static final int MAX_SIZE = 50;
 
+        @Override
         protected boolean removeEldestEntry(Map.Entry<Long, Logger> eldest) {
             return size() > MAX_SIZE;
         }
@@ -290,11 +292,6 @@ public class LogSupport implements Synch
                 message = "ServiceEvent " + event.getType();
         }
 
-        String s = (event.getServiceReference().getBundle() == null)
-                ? null
-                : "Bundle " + event.getServiceReference().getBundle();
-        s = (s == null) ? message : s + " " + message;
-
         LogEntry entry = new LogEntryImpl(
             event.getServiceReference().getBundle(),
             event.getServiceReference(), level, message, null);
@@ -362,10 +359,6 @@ public class LogSupport implements Synch
                 message = "FrameworkEvent " + event.getType();
         }
 
-        String s = (event.getBundle() == null) ? null : "Bundle "
-            + event.getBundle();
-        s = (s == null) ? message : s + " " + message;
-
         LogEntry entry = new LogEntryImpl(event.getBundle(), null, level,
             message, exception);
         fireLogEvent(entry);
@@ -434,13 +427,13 @@ public class LogSupport implements Synch
      * in the log entry.
      */
     private void logOut(LogEntry logEntry) {
-        // /* package */ void logOut(Bundle bundle, ServiceReference sr, int
-        // level, String message, Throwable exception) {
-
         // get the logger for the bundle
         Logger log = getLogger(logEntry.getBundle());
+        if (logEntry.getLevel() > getLevel(log))
+            // early Exit, this message will not be logged, don't do any 
work...
+            return;
 
-        StringBuffer msg = new StringBuffer();
+        final StringBuilder msg = new StringBuilder();
 
         ServiceReference sr = logEntry.getServiceReference();
         if (sr != null) {
@@ -453,7 +446,10 @@ public class LogSupport implements Synch
                 
msg.append(sr.getProperty(Constants.SERVICE_DESCRIPTION)).append(
                     ',');
             }
-            msg.append(sr.getProperty(Constants.SERVICE_ID)).append("] ");
+            msg.append(sr.getProperty(Constants.SERVICE_ID))
+                .append(", ")
+                .append(Arrays.toString((String[]) 
sr.getProperty(Constants.OBJECTCLASS)))
+                .append("] ");
         }
 
         if (logEntry.getMessage() != null) {
@@ -489,6 +485,18 @@ public class LogSupport implements Synch
         }
     }
 
+    static int getLevel(Logger log) {
+        if (log.isTraceEnabled())
+            return LogService.LOG_DEBUG + 1; // No constant for trace in 
LogService
+        else if (log.isDebugEnabled())
+            return LogService.LOG_DEBUG;
+        else if (log.isInfoEnabled())
+            return LogService.LOG_INFO;
+        else if (log.isWarnEnabled())
+            return LogService.LOG_WARNING;
+        return LogService.LOG_ERROR;
+    }
+
     // ---------- internal class 
-----------------------------------------------
 
     /**

Added: 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java?rev=1670052&view=auto
==============================================================================
--- 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
 (added)
+++ 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
 Mon Mar 30 11:11:34 2015
@@ -0,0 +1,155 @@
+/*
+ * 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.sling.commons.logservice.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogService;
+import org.slf4j.Logger;
+
+public class LogSupportTest {
+    @Test @SuppressWarnings("unchecked")
+    public void testServiceEvent() throws Exception {
+        LogSupport ls = new LogSupport();
+        Field lf = LogSupport.class.getDeclaredField("loggers");
+        lf.setAccessible(true);
+        Map<Long, Logger> loggers = (Map<Long, Logger>) lf.get(ls);
+
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.getSymbolicName()).thenReturn("foo.bundle");
+        Mockito.when(b.getBundleId()).thenReturn(42L);
+
+        final Map<String, Object> props = new HashMap<String, Object>();
+        props.put(Constants.OBJECTCLASS, new String [] {"some.class.Name"});
+        props.put(Constants.SERVICE_ID, 999L);
+
+        ServiceReference sr = Mockito.mock(ServiceReference.class);
+        Mockito.when(sr.getBundle()).thenReturn(b);
+        Mockito.when(sr.getProperty(Mockito.anyString())).then(new 
Answer<Object>() {
+            public Object answer(InvocationOnMock invocation) throws Throwable 
{
+                return props.get(invocation.getArguments()[0]);
+            }
+        });
+        
Mockito.when(sr.getPropertyKeys()).thenReturn(props.keySet().toArray(new 
String[] {}));
+        ServiceEvent se = new ServiceEvent(ServiceEvent.REGISTERED, sr);
+
+        Logger testLogger = getMockInfoLogger();
+        loggers.put(42L, testLogger);
+
+        ls.serviceChanged(se);
+
+        Mockito.verify(testLogger).info("Service [999, [some.class.Name]] 
ServiceEvent REGISTERED", (Throwable) null);
+    }
+
+    @Test @SuppressWarnings("unchecked")
+    public void testEarlyExit() throws Exception {
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.getSymbolicName()).thenReturn("bar.bundle");
+        Mockito.when(b.getBundleId()).thenReturn(1L);
+
+        ServiceReference sr = Mockito.mock(ServiceReference.class);
+        LogEntry le = new LogEntryImpl(b, sr, LogService.LOG_DEBUG, "test", 
null);
+
+        LogSupport ls = new LogSupport();
+        Field lf = LogSupport.class.getDeclaredField("loggers");
+        lf.setAccessible(true);
+        Map<Long, Logger> loggers = (Map<Long, Logger>) lf.get(ls);
+
+        Logger testLogger = getMockInfoLogger();
+        loggers.put(1L, testLogger);
+
+        ls.fireLogEvent(le);
+
+        // The log message is on DEBUG level while the logger is set to INFO 
level
+        // we don't want the actual log.info() call to be made, neither do we 
want
+        // any preparatory work on the log message being made (which involves
+        // inspecting the service reference).
+        Mockito.verify(testLogger).isTraceEnabled();
+        Mockito.verify(testLogger).isDebugEnabled();
+        Mockito.verify(testLogger).isInfoEnabled();
+        Mockito.verifyNoMoreInteractions(testLogger);
+        Mockito.verifyZeroInteractions(sr);
+    }
+
+    @Test @SuppressWarnings("unchecked")
+    public void testErrorLogger() throws Exception {
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.getSymbolicName()).thenReturn("bar.bundle");
+        Mockito.when(b.getBundleId()).thenReturn(1L);
+
+        Exception e = new Exception();
+        LogEntry le = new LogEntryImpl(b, null, LogService.LOG_ERROR, 
"my-error-msg", e);
+
+        LogSupport ls = new LogSupport();
+        Field lf = LogSupport.class.getDeclaredField("loggers");
+        lf.setAccessible(true);
+        Map<Long, Logger> loggers = (Map<Long, Logger>) lf.get(ls);
+
+        Logger testLogger = getMockInfoLogger();
+        loggers.put(1L, testLogger);
+
+        ls.fireLogEvent(le);
+
+        Mockito.verify(testLogger).error("my-error-msg (java.lang.Exception)", 
e);
+    }
+
+    @Test
+    public void testGetLevels() {
+        Logger traceLogger = Mockito.mock(Logger.class);
+        Mockito.when(traceLogger.isTraceEnabled()).thenReturn(true);
+        assertEquals(5, LogSupport.getLevel(traceLogger));
+
+        Logger debugLogger = Mockito.mock(Logger.class);
+        Mockito.when(debugLogger.isDebugEnabled()).thenReturn(true);
+        assertEquals(LogService.LOG_DEBUG, LogSupport.getLevel(debugLogger));
+
+        Logger infoLogger = Mockito.mock(Logger.class);
+        Mockito.when(infoLogger.isInfoEnabled()).thenReturn(true);
+        assertEquals(LogService.LOG_INFO, LogSupport.getLevel(infoLogger));
+
+        Logger warnLogger = Mockito.mock(Logger.class);
+        Mockito.when(warnLogger.isWarnEnabled()).thenReturn(true);
+        assertEquals(LogService.LOG_WARNING, LogSupport.getLevel(warnLogger));
+
+        Logger errorLogger = Mockito.mock(Logger.class);
+        Mockito.when(errorLogger.isErrorEnabled()).thenReturn(true);
+        assertEquals(LogService.LOG_ERROR, LogSupport.getLevel(errorLogger));
+    }
+
+    private Logger getMockInfoLogger() {
+        Logger testLogger = Mockito.mock(Logger.class);
+        Mockito.when(testLogger.isTraceEnabled()).thenReturn(false);
+        Mockito.when(testLogger.isDebugEnabled()).thenReturn(false);
+        Mockito.when(testLogger.isInfoEnabled()).thenReturn(true);
+        Mockito.when(testLogger.isWarnEnabled()).thenReturn(true);
+        Mockito.when(testLogger.isErrorEnabled()).thenReturn(true);
+        return testLogger;
+    }
+}

Propchange: 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: 
sling/trunk/bundles/commons/logservice/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain


Reply via email to