You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2017/07/31 07:59:23 UTC

[4/6] karaf git commit: Extract and simplify buffer functionality

Extract and simplify buffer functionality


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

Branch: refs/heads/karaf-4.1.x
Commit: c9173c0ecbf26250a027b32a2f3a63953b9a6439
Parents: 2482d22
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Sun Jul 30 15:29:11 2017 +0200
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Mon Jul 31 09:26:50 2017 +0200

----------------------------------------------------------------------
 .../karaf/log/core/internal/CircularBuffer.java | 109 +++++++++++++++++++
 .../karaf/log/core/internal/KarafLogEvent.java  |   1 -
 .../karaf/log/core/internal/LogServiceImpl.java |  37 +++++--
 .../karaf/log/core/internal/osgi/Activator.java |  11 +-
 .../log/core/internal/SetLogLevelTest.java      |   2 +-
 5 files changed, 142 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/c9173c0e/log/src/main/java/org/apache/karaf/log/core/internal/CircularBuffer.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/CircularBuffer.java b/log/src/main/java/org/apache/karaf/log/core/internal/CircularBuffer.java
new file mode 100644
index 0000000..c953b31
--- /dev/null
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/CircularBuffer.java
@@ -0,0 +1,109 @@
+/*
+ * 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.karaf.log.core.internal;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * An array that only keeps the last N elements added
+ */
+public class CircularBuffer<T> {
+
+    private T[] elements;
+    private transient int start;
+    private transient int end;
+    private transient boolean full;
+    private final int maxElements;
+    private Class<?> type;
+
+    public CircularBuffer(int size, Class<?> type) {
+        if (size <= 0) {
+            throw new IllegalArgumentException("The size must be greater than 0");
+        }
+        this.type = type;
+        maxElements = size;
+        clear();
+    }
+
+    private int size() {
+        if (end == start) {
+            return full ? maxElements : 0;
+        } else if (end < start) {
+            return maxElements - start + end;
+        } else {
+            return end - start;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public synchronized void clear() {
+        start = 0;
+        end = 0;
+        full = false;
+        elements = (T[])Array.newInstance(type, maxElements);
+    }
+
+    public synchronized void add(T element) {
+        if (null == element) {
+             throw new NullPointerException("Attempted to add null object to buffer");
+        }
+        if (full) {
+            increaseStart();
+        }
+        elements[end] = element;
+        increaseEnd();
+        
+    }
+
+    private void increaseStart() {
+        start++;
+        if (start >= maxElements) {
+            start = 0;
+        }
+    }
+
+    private void increaseEnd() {
+        end++;
+        if (end >= maxElements) {
+            end = 0;
+        }
+        if (end == start) {
+            full = true;
+        }
+    }
+
+    public synchronized Iterable<T> getElements() {
+        return getElements(size());
+    }
+
+    public synchronized Iterable<T> getElements(int nb) {
+        int s = size();
+        nb = Math.min(Math.max(0, nb), s);
+        List<T> result = new ArrayList<T>();
+        for (int i = 0; i < nb; i++) {
+            result.add(elements[(i + s - nb + start) % maxElements]);
+        }
+        return result;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/c9173c0e/log/src/main/java/org/apache/karaf/log/core/internal/KarafLogEvent.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/KarafLogEvent.java b/log/src/main/java/org/apache/karaf/log/core/internal/KarafLogEvent.java
index b81b281..a7638fb 100644
--- a/log/src/main/java/org/apache/karaf/log/core/internal/KarafLogEvent.java
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/KarafLogEvent.java
@@ -61,7 +61,6 @@ public class KarafLogEvent implements PaxLoggingEvent {
 
     @Override
     public String getLoggerName() {
-        // TODO Auto-generated method stub
         return this.loggerName;
     }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/c9173c0e/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
index c72a0b6..9c32cfc 100644
--- a/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/LogServiceImpl.java
@@ -18,7 +18,9 @@ package org.apache.karaf.log.core.internal;
 
 import java.io.IOException;
 import java.util.Dictionary;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.karaf.log.core.Level;
 import org.apache.karaf.log.core.LogService;
@@ -27,16 +29,19 @@ import org.ops4j.pax.logging.spi.PaxLoggingEvent;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 
-public class LogServiceImpl implements LogService {
+public class LogServiceImpl implements LogService, PaxAppender {
 
     static final String CONFIGURATION_PID = "org.ops4j.pax.logging";
 
     private final ConfigurationAdmin configAdmin;
-    private final LruList events;
+    private final CircularBuffer<PaxLoggingEvent> buffer;
+    private List<PaxAppender> appenders;
+    
 
-    public LogServiceImpl(ConfigurationAdmin configAdmin, LruList events) {
+    public LogServiceImpl(ConfigurationAdmin configAdmin, int size) {
         this.configAdmin = configAdmin;
-        this.events = events;
+        this.appenders = new CopyOnWriteArrayList<>();
+        this.buffer = new CircularBuffer<>(size, PaxLoggingEvent.class);
     }
 
     private LogServiceInternal getDelegate(Dictionary<String, Object> config) {
@@ -113,17 +118,17 @@ public class LogServiceImpl implements LogService {
 
     @Override
     public Iterable<PaxLoggingEvent> getEvents() {
-        return events.getElements();
+        return buffer.getElements();
     }
 
     @Override
     public Iterable<PaxLoggingEvent> getEvents(int maxNum) {
-        return events.getElements(maxNum);
+        return buffer.getElements(maxNum);
     }
 
     @Override
     public void clearEvents() {
-        events.clear();
+        buffer.clear();
     }
     
     @Override
@@ -150,12 +155,26 @@ public class LogServiceImpl implements LogService {
 
     @Override
     public void addAppender(PaxAppender appender) {
-        events.addAppender(appender);
+        this.appenders.add(appender);
     }
 
     @Override
     public void removeAppender(PaxAppender appender) {
-        events.removeAppender(appender);
+        this.appenders.remove(appender);
+    }
+
+    @Override
+    public synchronized void doAppend(PaxLoggingEvent event) {
+        event.getProperties(); // ensure MDC properties are copied
+        KarafLogEvent eventCopy = new KarafLogEvent(event);
+        this.buffer.add(eventCopy);
+        for (PaxAppender appender : appenders) {
+            try {
+                appender.doAppend(eventCopy);
+            } catch (Throwable t) {
+                // Ignore
+            }
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/c9173c0e/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java b/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
index d2dc0e8..f47b456 100644
--- a/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
+++ b/log/src/main/java/org/apache/karaf/log/core/internal/osgi/Activator.java
@@ -23,7 +23,6 @@ import org.apache.karaf.log.core.LogService;
 import org.apache.karaf.log.core.internal.LogEventFormatterImpl;
 import org.apache.karaf.log.core.internal.LogMBeanImpl;
 import org.apache.karaf.log.core.internal.LogServiceImpl;
-import org.apache.karaf.log.core.internal.LruList;
 import org.apache.karaf.util.tracker.BaseActivator;
 import org.apache.karaf.util.tracker.annotation.Managed;
 import org.apache.karaf.util.tracker.annotation.ProvideService;
@@ -55,11 +54,6 @@ public class Activator extends BaseActivator implements ManagedService {
         String debugColor = getString("debugColor", "39");
         String traceColor = getString("traceColor", "39");
 
-        LruList events = new LruList(size);
-        Hashtable<String, Object> props = new Hashtable<String, Object>();
-        props.put("org.ops4j.pax.logging.appender.name", "VmLogAppender");
-        register(PaxAppender.class, events, props);
-
         LogEventFormatterImpl formatter = new LogEventFormatterImpl();
         formatter.setPattern(pattern);
         formatter.setColor(PaxLogger.LEVEL_ERROR, errorColor);
@@ -69,7 +63,10 @@ public class Activator extends BaseActivator implements ManagedService {
         formatter.setColor(PaxLogger.LEVEL_TRACE, traceColor);
         register(LogEventFormatter.class, formatter);
 
-        LogServiceImpl logService = new LogServiceImpl(configurationAdmin, events);
+        LogServiceImpl logService = new LogServiceImpl(configurationAdmin, size);
+        Hashtable<String, Object> props = new Hashtable<>();
+        props.put("org.ops4j.pax.logging.appender.name", "VmLogAppender");
+        register(PaxAppender.class, logService, props);
         register(LogService.class, logService);
 
         LogMBeanImpl securityMBean = new LogMBeanImpl(logService);

http://git-wip-us.apache.org/repos/asf/karaf/blob/c9173c0e/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
----------------------------------------------------------------------
diff --git a/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java b/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
index a6e4d46..957c6ff 100644
--- a/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
+++ b/log/src/test/java/org/apache/karaf/log/core/internal/SetLogLevelTest.java
@@ -52,7 +52,7 @@ public class SetLogLevelTest extends TestCase {
         configuration.update(properties);        
         ConfigurationAdmin configAdmin = EasyMock.createMock(ConfigurationAdmin.class);
         EasyMock.expect(configAdmin.getConfiguration(LogServiceImpl.CONFIGURATION_PID, null)).andReturn(configuration);
-        logService = new LogServiceImpl(configAdmin, new LruList(100));
+        logService = new LogServiceImpl(configAdmin, 100);
         logMBean = new LogMBeanImpl(logService);
         EasyMock.replay(configAdmin);
         EasyMock.replay(configuration);