You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/04/13 18:49:55 UTC
logging-log4j2 git commit: LOG4J2-1334 initial version of reusable
LogEvent + factory
Repository: logging-log4j2
Updated Branches:
refs/heads/master 0a06f8f0d -> 5f461a722
LOG4J2-1334 initial version of reusable LogEvent + factory
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/5f461a72
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/5f461a72
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/5f461a72
Branch: refs/heads/master
Commit: 5f461a72203d5b729005db4690bfc4c9e2b4e64d
Parents: 0a06f8f
Author: rpopma <rp...@apache.org>
Authored: Thu Apr 14 01:49:55 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Thu Apr 14 01:49:55 2016 +0900
----------------------------------------------------------------------
.../logging/log4j/core/impl/Log4jLogEvent.java | 28 ++-
.../log4j/core/impl/MutableLogEvent.java | 200 +++++++++++++++++++
.../core/impl/ReusableLogEventFactory.java | 80 ++++++++
3 files changed, 306 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5f461a72/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
index 3f8961a..2e017dd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java
@@ -396,7 +396,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String
this.nanoTime = nanoTime;
}
- private static Map<String, String> createMap(final List<Property> properties) {
+ static Map<String, String> createMap(final List<Property> properties) {
final Map<String, String> contextMap = ThreadContext.getImmutableContext();
if (properties == null || properties.isEmpty()) {
return contextMap; // may be ThreadContext.EMPTY_MAP but not null
@@ -766,7 +766,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String
/**
* Proxy pattern used to serialize the LogEvent.
*/
- private static class LogEventProxy implements Serializable {
+ static class LogEventProxy implements Serializable {
private static final long serialVersionUID = -8634075037355293699L;
private final String loggerFQCN;
@@ -812,6 +812,30 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String
this.nanoTime = event.nanoTime;
}
+ public LogEventProxy(final MutableLogEvent event, final boolean includeLocation) {
+ this.loggerFQCN = event.getLoggerFqcn();
+ this.marker = event.getMarker();
+ this.level = event.getLevel();
+ this.loggerName = event.getLoggerName();
+
+ final Message msg = event.getMessage();
+ this.message = msg instanceof ReusableMessage
+ ? memento((ReusableMessage) msg)
+ : msg;
+ this.timeMillis = event.getTimeMillis();
+ this.thrown = event.getThrown();
+ this.thrownProxy = event.getThrownProxy();
+ this.contextMap = event.getContextMap();
+ this.contextStack = event.getContextStack();
+ this.source = includeLocation ? event.getSource() : null;
+ this.threadId = event.getThreadId();
+ this.threadName = event.getThreadName();
+ this.threadPriority = event.getThreadPriority();
+ this.isLocationRequired = includeLocation;
+ this.isEndOfBatch = event.isEndOfBatch();
+ this.nanoTime = event.getNanoTime();
+ }
+
private Message memento(final ReusableMessage message) {
return new SimpleMessage(message.getFormattedMessage());
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5f461a72/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
new file mode 100644
index 0000000..2e2626f
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/MutableLogEvent.java
@@ -0,0 +1,200 @@
+package org.apache.logging.log4j.core.impl;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.message.Message;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.util.Map;
+
+/**
+ * Mutable implementation of the {@code LogEvent} interface.
+ */
+public class MutableLogEvent implements LogEvent {
+ private String loggerFqcn;
+ private Marker marker;
+ private Level level;
+ private String loggerName;
+ private Message message;
+ private Throwable thrown;
+ private long timeMillis;
+ private Map<String, String> contextMap;
+ private ThreadContext.ContextStack contextStack;
+ private long threadId;
+ private String threadName;
+ private int threadPriority;
+ private boolean includeLocation;
+ private boolean endOfBatch = false;
+ private long nanoTime;
+ // private ThrowableProxy thrownProxy;
+ // private StackTraceElement source;
+
+ @Override
+ public String getLoggerFqcn() {
+ return loggerFqcn;
+ }
+
+ public void setLoggerFqcn(String loggerFqcn) {
+ this.loggerFqcn = loggerFqcn;
+ }
+
+ @Override
+ public Marker getMarker() {
+ return marker;
+ }
+
+ public void setMarker(Marker marker) {
+ this.marker = marker;
+ }
+
+ @Override
+ public Level getLevel() {
+ return level;
+ }
+
+ public void setLevel(Level level) {
+ this.level = level;
+ }
+
+ @Override
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ public void setLoggerName(String loggerName) {
+ this.loggerName = loggerName;
+ }
+
+ @Override
+ public Message getMessage() {
+ return message;
+ }
+
+ public void setMessage(Message message) {
+ this.message = message;
+ }
+
+ @Override
+ public Throwable getThrown() {
+ return thrown;
+ }
+
+ public void setThrown(Throwable thrown) {
+ this.thrown = thrown;
+ }
+
+ @Override
+ public long getTimeMillis() {
+ return timeMillis;
+ }
+
+ public void setTimeMillis(long timeMillis) {
+ this.timeMillis = timeMillis;
+ }
+
+ @Override
+ public ThrowableProxy getThrownProxy() {
+ if (thrown != null) {
+ return new ThrowableProxy(thrown);
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, String> getContextMap() {
+ return contextMap;
+ }
+
+ public void setContextMap(Map<String, String> contextMap) {
+ this.contextMap = contextMap;
+ }
+
+ @Override
+ public ThreadContext.ContextStack getContextStack() {
+ return contextStack;
+ }
+
+ public void setContextStack(ThreadContext.ContextStack contextStack) {
+ this.contextStack = contextStack;
+ }
+
+ @Override
+ public long getThreadId() {
+ return threadId;
+ }
+
+ public void setThreadId(long threadId) {
+ this.threadId = threadId;
+ }
+
+ @Override
+ public String getThreadName() {
+ return threadName;
+ }
+
+ public void setThreadName(String threadName) {
+ this.threadName = threadName;
+ }
+
+ @Override
+ public int getThreadPriority() {
+ return threadPriority;
+ }
+
+ public void setThreadPriority(int threadPriority) {
+ this.threadPriority = threadPriority;
+ }
+
+ @Override
+ public StackTraceElement getSource() {
+ if (loggerFqcn == null || !includeLocation) {
+ return null;
+ }
+ return Log4jLogEvent.calcLocation(loggerFqcn);
+ }
+
+ @Override
+ public boolean isIncludeLocation() {
+ return includeLocation;
+ }
+
+ @Override
+ public void setIncludeLocation(boolean includeLocation) {
+ this.includeLocation = includeLocation;
+ }
+
+ @Override
+ public boolean isEndOfBatch() {
+ return endOfBatch;
+ }
+
+ @Override
+ public void setEndOfBatch(boolean endOfBatch) {
+ this.endOfBatch = endOfBatch;
+ }
+
+ @Override
+ public long getNanoTime() {
+ return nanoTime;
+ }
+
+ public void setNanoTime(long nanoTime) {
+ this.nanoTime = nanoTime;
+ }
+
+ /**
+ * Creates a LogEventProxy that can be serialized.
+ * @return a LogEventProxy.
+ */
+ protected Object writeReplace() {
+ getThrownProxy(); // ensure ThrowableProxy is initialized
+ return new Log4jLogEvent.LogEventProxy(this, this.includeLocation);
+ }
+
+ private void readObject(final ObjectInputStream stream) throws InvalidObjectException {
+ throw new InvalidObjectException("Proxy required");
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/5f461a72/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
new file mode 100644
index 0000000..190b27a
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java
@@ -0,0 +1,80 @@
+/*
+ * 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.logging.log4j.core.impl;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.core.util.Clock;
+import org.apache.logging.log4j.core.util.ClockFactory;
+import org.apache.logging.log4j.message.Message;
+
+import java.util.List;
+
+/**
+ * Garbage-free LogEventFactory that reuses a single mutable log event.
+ */
+public class ReusableLogEventFactory implements LogEventFactory {
+
+ private static ThreadLocal<MutableLogEvent> mutableLogEventThreadLocal = new ThreadLocal<>();
+ private static final Clock CLOCK = ClockFactory.getClock();
+ /**
+ * Creates a log event.
+ *
+ * @param loggerName The name of the Logger.
+ * @param marker An optional Marker.
+ * @param fqcn The fully qualified class name of the caller.
+ * @param level The event Level.
+ * @param data The Message.
+ * @param properties Properties to be added to the log event.
+ * @param t An optional Throwable.
+ * @return The LogEvent.
+ */
+ @Override
+ public LogEvent createEvent(final String loggerName, final Marker marker,
+ final String fqcn, final Level level, final Message data,
+ final List<Property> properties, final Throwable t) {
+ MutableLogEvent result = mutableLogEventThreadLocal.get();
+ if (result == null) {
+ result = new MutableLogEvent();
+ result.setThreadId(Thread.currentThread().getId());
+ result.setThreadName(Thread.currentThread().getName());
+ result.setThreadPriority(Thread.currentThread().getPriority());
+ mutableLogEventThreadLocal.set(result);
+ }
+
+ result.setLoggerName(loggerName);
+ result.setMarker(marker);
+ result.setLoggerFqcn(fqcn);
+ result.setLevel(level == null ? Level.OFF : level);
+ result.setMessage(data);
+ result.setThrown(t);
+ result.setContextMap(Log4jLogEvent.createMap(properties));
+ result.setContextStack(ThreadContext.getDepth() == 0 ? null : ThreadContext.cloneStack());// mutable copy
+ result.setTimeMillis(CLOCK.currentTimeMillis());
+ result.setNanoTime(Log4jLogEvent.getNanoClock().nanoTime());
+
+ // TODO
+// result.setEndOfBatch();
+// result.setIncludeLocation();
+// result.setSource();
+ //return new Log4jLogEvent(loggerName, marker, fqcn, level, data, properties, t);
+ return result;
+ }
+}