Repository: karaf Updated Branches: refs/heads/master a7a627467 -> c63c75795
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/c63c7579 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/c63c7579 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/c63c7579 Branch: refs/heads/master Commit: c63c75795583533c66570f904cb5ae480fb116a7 Parents: a7a6274 Author: Christian Schneider <[email protected]> Authored: Sun Jul 30 15:29:11 2017 +0200 Committer: Christian Schneider <[email protected]> Committed: Sun Jul 30 15:29:11 2017 +0200 ---------------------------------------------------------------------- .../karaf/log/core/internal/CircularBuffer.java | 109 ++++++++++++++++ .../karaf/log/core/internal/KarafLogEvent.java | 1 - .../karaf/log/core/internal/LogServiceImpl.java | 37 ++++-- .../apache/karaf/log/core/internal/LruList.java | 125 ------------------- .../karaf/log/core/internal/osgi/Activator.java | 11 +- .../log/core/internal/SetLogLevelTest.java | 2 +- 6 files changed, 142 insertions(+), 143 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/c63c7579/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/c63c7579/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/c63c7579/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/c63c7579/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java ---------------------------------------------------------------------- diff --git a/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java b/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java deleted file mode 100644 index 34485b1..0000000 --- a/log/src/main/java/org/apache/karaf/log/core/internal/LruList.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.ops4j.pax.logging.spi.PaxAppender; -import org.ops4j.pax.logging.spi.PaxLoggingEvent; - -/** - * A list that only keep the last N elements added - */ -public class LruList implements PaxAppender { - - private PaxLoggingEvent[] elements; - private transient int start = 0; - private transient int end = 0; - private transient boolean full = false; - private final int maxElements; - private final List<PaxAppender> appenders; - - public LruList(int size) { - if (size <= 0) { - throw new IllegalArgumentException("The size must be greater than 0"); - } - elements = new PaxLoggingEvent[size]; - maxElements = elements.length; - appenders = new ArrayList<>(); - } - - public synchronized int size() { - int size = 0; - if (end < start) { - size = maxElements - start + end; - } else if (end == start) { - size = (full ? maxElements : 0); - } else { - size = end - start; - } - return size; - } - - public synchronized void clear() { - start = 0; - end = 0; - full = false; - elements = new PaxLoggingEvent[maxElements]; - } - - public synchronized void add(PaxLoggingEvent element) { - if (null == element) { - throw new NullPointerException("Attempted to add null object to buffer"); - } - if (size() == maxElements) { - Object e = elements[start]; - if (null != e) { - elements[start++] = null; - if (start >= maxElements) { - start = 0; - } - full = false; - } - } - elements[end++] = new KarafLogEvent(element); - if (end >= maxElements) { - end = 0; - } - if (end == start) { - full = true; - } - for (PaxAppender appender : appenders) { - try { - appender.doAppend(element); - } catch (Throwable t) { - // Ignore - } - } - } - - public synchronized Iterable<PaxLoggingEvent> getElements() { - return getElements(size()); - } - - public synchronized Iterable<PaxLoggingEvent> getElements(int nb) { - int s = size(); - nb = Math.min(Math.max(0, nb), s); - PaxLoggingEvent[] e = new PaxLoggingEvent[nb]; - for (int i = 0; i < nb; i++) { - e[i] = elements[(i + s - nb + start) % maxElements]; - } - return Arrays.asList(e); - } - - public synchronized void addAppender(PaxAppender appender) { - this.appenders.add(appender); - } - - public synchronized void removeAppender(PaxAppender appender) { - this.appenders.remove(appender); - } - - public void doAppend(PaxLoggingEvent event) { - event.getProperties(); // ensure MDC properties are copied - add(event); - } - -} http://git-wip-us.apache.org/repos/asf/karaf/blob/c63c7579/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 5e93a0a..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<>(); - 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/c63c7579/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);
