You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2015/03/30 13:11:35 UTC
svn commit: r1670052 - in /sling/trunk/bundles/commons/logservice: ./
src/main/java/org/apache/sling/commons/logservice/internal/
src/test/java/org/ src/test/java/org/apache/
src/test/java/org/apache/sling/ src/test/java/org/apache/sling/commons/
src/t...
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