LOG4J2-1447 replace context Map<String,String> with ContextData in LogEvent implementation classes; update tests
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/6caf1e83 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/6caf1e83 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/6caf1e83 Branch: refs/heads/LOG4J2-1010&LOG4J2-1447-injectable-contextdata&better-datastructure Commit: 6caf1e8375bf6c23f701c9fe7f88e7b7699dc58e Parents: e8902af Author: rpopma <[email protected]> Authored: Wed Jul 27 01:17:34 2016 +0900 Committer: rpopma <[email protected]> Committed: Wed Jul 27 01:17:34 2016 +0900 ---------------------------------------------------------------------- .../log4j/core/async/RingBufferLogEvent.java | 55 +++------- .../logging/log4j/core/impl/Log4jLogEvent.java | 110 ++++++++++++------- .../log4j/core/impl/MutableLogEvent.java | 28 +++-- .../core/async/RingBufferLogEventTest.java | 31 +++--- .../log4j/core/impl/Log4jLogEventTest.java | 66 +++++++++-- .../log4j/core/impl/MutableLogEventTest.java | 27 +++-- 6 files changed, 193 insertions(+), 124 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java index 463536c..20a57ce 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java @@ -18,17 +18,17 @@ package org.apache.logging.log4j.core.async; import java.io.IOException; import java.util.Arrays; -import java.util.HashMap; import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext.ContextStack; +import org.apache.logging.log4j.core.ContextData; import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.config.Property; +import org.apache.logging.log4j.core.impl.ContextDataFactory; import org.apache.logging.log4j.core.impl.Log4jLogEvent; +import org.apache.logging.log4j.core.impl.MutableContextData; import org.apache.logging.log4j.core.impl.ThrowableProxy; -import org.apache.logging.log4j.core.lookup.StrSubstitutor; import org.apache.logging.log4j.core.util.Constants; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.ParameterizedMessage; @@ -82,7 +82,7 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen private Object[] parameters; private transient Throwable thrown; private ThrowableProxy thrownProxy; - private Map<String, String> contextMap; + private final MutableContextData contextData = ContextDataFactory.getContextData(); private Marker marker; private String fqcn; private StackTraceElement location; @@ -92,8 +92,8 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen public void setValues(final AsyncLogger anAsyncLogger, final String aLoggerName, final Marker aMarker, final String theFqcn, final Level aLevel, final Message msg, final Throwable aThrowable, - final Map<String, String> aMap, final ContextStack aContextStack, final long threadId, - final String threadName, final int threadPriority, final StackTraceElement aLocation, final long aCurrentTimeMillis, final long aNanoTime) { + final ContextStack aContextStack, final long threadId, final String threadName, final int threadPriority, + final StackTraceElement aLocation, final long aCurrentTimeMillis, final long aNanoTime) { this.threadPriority = threadPriority; this.threadId = threadId; this.currentTimeMillis = aCurrentTimeMillis; @@ -104,11 +104,11 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen setMessage(msg); this.thrown = aThrowable; this.thrownProxy = null; - this.contextMap = aMap; this.marker = aMarker; this.fqcn = theFqcn; this.location = aLocation; this.contextStack = aContextStack; + // contextData is never replaced, only its contents are modified this.asyncLogger = anAsyncLogger; } @@ -319,9 +319,16 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen return this.thrownProxy; } + @SuppressWarnings("unchecked") + @Override + public ContextData getContextData() { + return contextData; + } + + @SuppressWarnings("unchecked") @Override public Map<String, String> getContextMap() { - return contextMap; + return contextData.asMap(); } @Override @@ -360,34 +367,6 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen } /** - * Merges the contents of the specified map into the contextMap, after replacing any variables in the property - * values with the StrSubstitutor-supplied actual values. - * - * @param properties configured properties - * @param strSubstitutor used to lookup values of variables in properties - */ - public void mergePropertiesIntoContextMap(final Map<Property, Boolean> properties, - final StrSubstitutor strSubstitutor) { - if (properties == null) { - return; // nothing to do - } - - final Map<String, String> map = contextMap == null ? new HashMap<String, String>() - : new HashMap<>(contextMap); - - for (final Map.Entry<Property, Boolean> entry : properties.entrySet()) { - final Property prop = entry.getKey(); - if (map.containsKey(prop.getName())) { - continue; // contextMap overrides config properties - } - final String value = entry.getValue().booleanValue() ? strSubstitutor.replace(prop.getValue()) : prop - .getValue(); - map.put(prop.getName(), value); - } - contextMap = map; - } - - /** * Release references held by ring buffer to allow objects to be garbage-collected. */ public void clear() { @@ -399,7 +378,7 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen this.message = null; this.thrown = null; this.thrownProxy = null; - this.contextMap = null; + this.contextData.clear(); this.contextStack = null; this.location = null; @@ -440,7 +419,7 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen * @param builder the builder whose fields to populate */ public void initializeBuilder(final Log4jLogEvent.Builder builder) { - builder.setContextMap(contextMap) // + builder.setContextData(contextData) // .setContextStack(contextStack) // .setEndOfBatch(endOfBatch) // .setIncludeLocation(includeLocation) // http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/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 7efc8dd..e283bea 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 @@ -19,8 +19,6 @@ package org.apache.logging.log4j.core.impl; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -28,6 +26,7 @@ import java.util.Objects; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext; +import org.apache.logging.log4j.core.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.async.RingBufferLogEvent; import org.apache.logging.log4j.core.config.LoggerConfig; @@ -60,7 +59,7 @@ public class Log4jLogEvent implements LogEvent { private final long timeMillis; private final transient Throwable thrown; private ThrowableProxy thrownProxy; - private final Map<String, String> contextMap; + private final MutableContextData contextData; private final ThreadContext.ContextStack contextStack; private long threadId; private String threadName; @@ -82,7 +81,7 @@ public class Log4jLogEvent implements LogEvent { private Throwable thrown; private long timeMillis = CLOCK.currentTimeMillis(); private ThrowableProxy thrownProxy; - private Map<String, String> contextMap = ThreadContext.getImmutableContext(); + private MutableContextData contextData = createContextData((List<Property>) null); private ThreadContext.ContextStack contextStack = ThreadContext.getImmutableStack(); private long threadId; private String threadName; @@ -112,7 +111,6 @@ public class Log4jLogEvent implements LogEvent { this.message = other.getMessage(); this.timeMillis = other.getTimeMillis(); this.thrown = other.getThrown(); - this.contextMap = other.getContextMap(); this.contextStack = other.getContextStack(); this.includeLocation = other.isIncludeLocation(); this.endOfBatch = other.isEndOfBatch(); @@ -121,12 +119,19 @@ public class Log4jLogEvent implements LogEvent { // Avoid unnecessarily initializing thrownProxy, threadName and source if possible if (other instanceof Log4jLogEvent) { final Log4jLogEvent evt = (Log4jLogEvent) other; + this.contextData = evt.contextData; this.thrownProxy = evt.thrownProxy; this.source = evt.source; this.threadId = evt.threadId; this.threadName = evt.threadName; this.threadPriority = evt.threadPriority; } else { + if (other.getContextData() instanceof MutableContextData) { + this.contextData = (MutableContextData) other.getContextData(); + } else { + this.contextData.clear(); + this.contextData.putAll(other.getContextData()); + } this.thrownProxy = other.getThrownProxy(); this.source = other.getSource(); this.threadId = other.getThreadId(); @@ -175,8 +180,20 @@ public class Log4jLogEvent implements LogEvent { return this; } + @SuppressWarnings("unchecked") + @Deprecated public Builder setContextMap(final Map<String, String> contextMap) { - this.contextMap = contextMap; + contextData = ContextDataFactory.getContextData(); // replace with new instance + if (contextMap != null) { + for (Map.Entry<String, String> entry : contextMap.entrySet()) { + contextData.putValue(entry.getKey(), entry.getValue()); + } + } + return this; + } + + public Builder setContextData(final MutableContextData contextData) { + this.contextData = contextData; return this; } @@ -229,7 +246,8 @@ public class Log4jLogEvent implements LogEvent { @Override public Log4jLogEvent build() { final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFqcn, level, message, thrown, - thrownProxy, contextMap, contextStack, threadId, threadName, threadPriority, source, timeMillis, nanoTime); + thrownProxy, contextData, contextStack, threadId, threadName, threadPriority, source, timeMillis, + nanoTime); result.setIncludeLocation(includeLocation); result.setEndOfBatch(endOfBatch); return result; @@ -282,14 +300,13 @@ public class Log4jLogEvent implements LogEvent { * @param loggerFQCN The fully qualified class name of the caller. * @param level The logging Level. * @param message The Message. - * @param properties properties to add to the event. + * @param properties the properties to be merged with ThreadContext key-value pairs into the event's ContextData. * @param t A Throwable or null. */ // This constructor is called from LogEventFactories. public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level, final Message message, final List<Property> properties, final Throwable t) { - this(loggerName, marker, loggerFQCN, level, message, t, null, - createMap(properties), + this(loggerName, marker, loggerFQCN, level, message, t, null, createContextData(properties), ThreadContext.getDepth() == 0 ? null : ThreadContext.cloneStack(), // mutable copy 0, // thread name null, // stack trace element @@ -316,11 +333,11 @@ public class Log4jLogEvent implements LogEvent { * @deprecated use {@link Log4jLogEvent.Builder} instead. This constructor will be removed in an upcoming release. */ @Deprecated -public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level, + public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level, final Message message, final Throwable t, final Map<String, String> mdc, final ThreadContext.ContextStack ndc, final String threadName, final StackTraceElement location, final long timestampMillis) { - this(loggerName, marker, loggerFQCN, level, message, t, null, mdc, ndc, 0, + this(loggerName, marker, loggerFQCN, level, message, t, null, createContextData(mdc), ndc, 0, threadName, 0, location, timestampMillis, nanoClock.nanoTime()); } @@ -349,7 +366,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String final String threadName, final StackTraceElement location, final long timestamp) { final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFQCN, level, message, thrown, - thrownProxy, mdc, ndc, 0, threadName, 0, location, timestamp, nanoClock.nanoTime()); + thrownProxy, createContextData(mdc), ndc, 0, threadName, 0, location, timestamp, nanoClock.nanoTime()); return result; } @@ -362,7 +379,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String * @param message The Message. * @param thrown A Throwable or null. * @param thrownProxy A ThrowableProxy or null. - * @param contextMap The mapped diagnostic context. + * @param contextData The key-value pairs from the context. * @param contextStack the nested diagnostic context. * @param threadId the thread ID * @param threadName The name of the thread. @@ -374,9 +391,9 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String */ private Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level, final Message message, final Throwable thrown, final ThrowableProxy thrownProxy, - final Map<String, String> contextMap, final ThreadContext.ContextStack contextStack, final long threadId, - final String threadName, final int threadPriority, final StackTraceElement source, final long timestampMillis, - final long nanoTime) { + final MutableContextData contextData, final ThreadContext.ContextStack contextStack, final long threadId, + final String threadName, final int threadPriority, final StackTraceElement source, + final long timestampMillis, final long nanoTime) { this.loggerName = loggerName; this.marker = marker; this.loggerFqcn = loggerFQCN; @@ -384,7 +401,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String this.message = message; this.thrown = thrown; this.thrownProxy = thrownProxy; - this.contextMap = contextMap == null ? ThreadContext.EMPTY_MAP : contextMap; + this.contextData = contextData == null ? ContextDataFactory.getContextData() : contextData; this.contextStack = contextStack == null ? ThreadContext.EMPTY_STACK : contextStack; this.timeMillis = message instanceof TimestampMessage ? ((TimestampMessage) message).getTimestamp() @@ -399,19 +416,21 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String this.nanoTime = nanoTime; } - 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 - } - final Map<String, String> map = new HashMap<>(contextMap); - - for (final Property prop : properties) { - if (!map.containsKey(prop.getName())) { - map.put(prop.getName(), prop.getValue()); + private static MutableContextData createContextData(final Map<String, String> contextMap) { + final MutableContextData result = ContextDataFactory.getContextData(); + if (contextMap != null) { + for (Map.Entry<String, String> entry : contextMap.entrySet()) { + result.putValue(entry.getKey(), entry.getValue()); } } - return Collections.unmodifiableMap(map); + return result; + } + + private static MutableContextData createContextData(final List<Property> properties) { + final MutableContextData result = ContextDataFactory.getContextData(); + final ContextDataInjector injector = ContextDataInjectorFactory.getInjector(); + injector.injectContextData(properties, result); + return result; } /** @@ -552,12 +571,21 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String } /** + * Returns the {@code ContextData} containing context data key-value pairs. + * @return the {@code ContextData} containing context data key-value pairs + * @since 2.7 + */ + @Override + public ContextData getContextData() { + return contextData; + } + /** * Returns the immutable copy of the ThreadContext Map. * @return The context Map. */ @Override public Map<String, String> getContextMap() { - return contextMap; + return contextData.asMap(); } /** @@ -678,7 +706,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String final LogEventProxy proxy = (LogEventProxy) event; final Log4jLogEvent result = new Log4jLogEvent(proxy.loggerName, proxy.marker, proxy.loggerFQCN, proxy.level, proxy.message, - proxy.thrown, proxy.thrownProxy, proxy.contextMap, proxy.contextStack, proxy.threadId, + proxy.thrown, proxy.thrownProxy, proxy.contextData, proxy.contextStack, proxy.threadId, proxy.threadName, proxy.threadPriority, proxy.source, proxy.timeMillis, proxy.nanoTime); result.setEndOfBatch(proxy.isEndOfBatch); result.setIncludeLocation(proxy.isLocationRequired); @@ -746,7 +774,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String if (marker != null ? !marker.equals(that.marker) : that.marker != null) { return false; } - if (contextMap != null ? !contextMap.equals(that.contextMap) : that.contextMap != null) { + if (contextData != null ? !contextData.equals(that.contextData) : that.contextData != null) { return false; } if (!message.equals(that.message)) { @@ -789,7 +817,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32)); result = 31 * result + (thrown != null ? thrown.hashCode() : 0); result = 31 * result + (thrownProxy != null ? thrownProxy.hashCode() : 0); - result = 31 * result + (contextMap != null ? contextMap.hashCode() : 0); + result = 31 * result + (contextData != null ? contextData.hashCode() : 0); result = 31 * result + (contextStack != null ? contextStack.hashCode() : 0); result = 31 * result + (int) (threadId ^ (threadId >>> 32)); result = 31 * result + (threadName != null ? threadName.hashCode() : 0); @@ -815,7 +843,8 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String private final long timeMillis; private final transient Throwable thrown; private final ThrowableProxy thrownProxy; - private final Map<String, String> contextMap; + /** @since 2.7 */ + private final MutableContextData contextData; private final ThreadContext.ContextStack contextStack; /** @since 2.6 */ private final long threadId; @@ -839,7 +868,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String this.timeMillis = event.timeMillis; this.thrown = event.thrown; this.thrownProxy = event.thrownProxy; - this.contextMap = event.contextMap; + this.contextData = event.contextData; this.contextStack = event.contextStack; this.source = includeLocation ? event.getSource() : null; this.threadId = event.getThreadId(); @@ -863,7 +892,7 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String this.timeMillis = event.getTimeMillis(); this.thrown = event.getThrown(); this.thrownProxy = event.getThrownProxy(); - this.contextMap = event.getContextMap(); + this.contextData = memento(event.getContextData()); this.contextStack = event.getContextStack(); this.source = includeLocation ? event.getSource() : null; this.threadId = event.getThreadId(); @@ -874,17 +903,22 @@ public Log4jLogEvent(final String loggerName, final Marker marker, final String this.nanoTime = event.getNanoTime(); } - private Message memento(final ReusableMessage message) { + private static Message memento(final ReusableMessage message) { return message.memento(); } + private static MutableContextData memento(final ContextData data) { + return new ArrayContextData(data); // TODO necessary to construct new instance? + } + /** * Returns a Log4jLogEvent using the data in the proxy. * @return Log4jLogEvent. */ protected Object readResolve() { final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFQCN, level, message, thrown, - thrownProxy, contextMap, contextStack, threadId, threadName, threadPriority, source, timeMillis, nanoTime); + thrownProxy, contextData, contextStack, threadId, threadName, threadPriority, source, timeMillis, + nanoTime); result.setEndOfBatch(isEndOfBatch); result.setIncludeLocation(isLocationRequired); return result; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/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 index fc44acc..a5a69d4 100644 --- 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 @@ -24,6 +24,7 @@ import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext; +import org.apache.logging.log4j.core.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.util.Constants; import org.apache.logging.log4j.message.Message; @@ -54,7 +55,7 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { private Object[] parameters; private Throwable thrown; private ThrowableProxy thrownProxy; - private Map<String, String> contextMap; + private MutableContextData contextData = ContextDataFactory.getContextData(); private Marker marker; private String loggerFqcn; private StackTraceElement source; @@ -87,7 +88,11 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { this.timeMillis = event.getTimeMillis(); this.thrown = event.getThrown(); this.thrownProxy = event.getThrownProxy(); - this.contextMap = event.getContextMap(); + if (event.getContextData() instanceof MutableContextData) { + this.contextData = (MutableContextData) event.getContextData(); + } else { + this.contextData.putAll(event.getContextData()); + } this.contextStack = event.getContextStack(); this.source = event.isIncludeLocation() ? event.getSource() : null; this.threadId = event.getThreadId(); @@ -101,6 +106,7 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { /** * Clears all references this event has to other objects. + * */ public void clear() { loggerFqcn = null; @@ -111,7 +117,9 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { thrown = null; thrownProxy = null; source = null; - contextMap = null; + if (contextData != null) { + contextData.clear(); + } contextStack = null; // ThreadName should not be cleared: this field is set in the ReusableLogEventFactory @@ -333,13 +341,19 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { return source; } + @SuppressWarnings("unchecked") + @Override + public ContextData getContextData() { + return contextData; + } + @Override public Map<String, String> getContextMap() { - return contextMap; + return contextData.asMap(); } - public void setContextMap(final Map<String, String> contextMap) { - this.contextMap = contextMap; + public void setContextData(final MutableContextData mutableContextData) { + this.contextData = mutableContextData; } @Override @@ -434,7 +448,7 @@ public class MutableLogEvent implements LogEvent, ReusableMessage { * @param builder the builder whose fields to populate */ public void initializeBuilder(final Log4jLogEvent.Builder builder) { - builder.setContextMap(contextMap) // + builder.setContextData(contextData) // .setContextStack(contextStack) // .setEndOfBatch(endOfBatch) // .setIncludeLocation(includeLocation) // http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java index ec3a874..12235d1 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java @@ -23,14 +23,13 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.ThreadContext.ContextStack; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.impl.MutableContextData; import org.apache.logging.log4j.core.impl.ThrowableProxy; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.SimpleMessage; @@ -53,13 +52,12 @@ public class RingBufferLogEventTest { final Level level = null; final Message data = null; final Throwable t = null; - final Map<String, String> map = null; final ContextStack contextStack = null; final String threadName = null; final StackTraceElement location = null; final long currentTimeMillis = 0; final long nanoTime = 1; - evt.setValues(null, loggerName, marker, fqcn, level, data, t, map, + evt.setValues(null, loggerName, marker, fqcn, level, data, t, contextStack, -1, threadName, -1, location, currentTimeMillis, nanoTime); assertEquals(Level.OFF, evt.getLevel()); } @@ -73,13 +71,12 @@ public class RingBufferLogEventTest { final Level level = null; final Message data = null; final Throwable t = null; - final Map<String, String> map = null; final ContextStack contextStack = null; final String threadName = null; final StackTraceElement location = null; final long currentTimeMillis = 0; final long nanoTime = 1; - evt.setValues(null, loggerName, marker, fqcn, level, data, t, map, + evt.setValues(null, loggerName, marker, fqcn, level, data, t, contextStack, -1, threadName, -1, location, currentTimeMillis, nanoTime); assertNotNull(evt.getMessage()); } @@ -93,13 +90,12 @@ public class RingBufferLogEventTest { final Level level = null; final Message data = null; final Throwable t = null; - final Map<String, String> map = null; final ContextStack contextStack = null; final String threadName = null; final StackTraceElement location = null; final long currentTimeMillis = 123; final long nanoTime = 1; - evt.setValues(null, loggerName, marker, fqcn, level, data, t, map, + evt.setValues(null, loggerName, marker, fqcn, level, data, t, contextStack, -1, threadName, -1, location, currentTimeMillis, nanoTime); assertEquals(123, evt.getTimeMillis()); } @@ -113,19 +109,19 @@ public class RingBufferLogEventTest { final Level level = Level.TRACE; final Message data = new SimpleMessage("message"); final Throwable t = new InternalError("not a real error"); - final Map<String, String> map = null; final ContextStack contextStack = null; final String threadName = "main"; final StackTraceElement location = null; final long currentTimeMillis = 12345; final long nanoTime = 1; - evt.setValues(null, loggerName, marker, fqcn, level, data, t, map, + evt.setValues(null, loggerName, marker, fqcn, level, data, t, contextStack, -1, threadName, -1, location, currentTimeMillis, nanoTime); - + ((MutableContextData) evt.getContextData()).putValue("key", "value"); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(evt); - + final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); final RingBufferLogEvent other = (RingBufferLogEvent) in.readObject(); assertEquals(loggerName, other.getLoggerName()); @@ -135,13 +131,13 @@ public class RingBufferLogEventTest { assertEquals(data, other.getMessage()); assertNull("null after serialization", other.getThrown()); assertEquals(new ThrowableProxy(t), other.getThrownProxy()); - assertEquals(map, other.getContextMap()); + assertEquals(evt.getContextData(), other.getContextData()); assertEquals(contextStack, other.getContextStack()); assertEquals(threadName, other.getThreadName()); assertEquals(location, other.getSource()); assertEquals(currentTimeMillis, other.getTimeMillis()); } - + @Test public void testCreateMementoReturnsCopy() { final RingBufferLogEvent evt = new RingBufferLogEvent(); @@ -151,16 +147,15 @@ public class RingBufferLogEventTest { final Level level = Level.TRACE; final Message data = new SimpleMessage("message"); final Throwable t = new InternalError("not a real error"); - final Map<String, String> map = new HashMap<>(); - map.put("key", "value"); final ContextStack contextStack = new MutableThreadContextStack(Arrays.asList("a", "b")); final String threadName = "main"; final StackTraceElement location = null; final long currentTimeMillis = 12345; final long nanoTime = 1; - evt.setValues(null, loggerName, marker, fqcn, level, data, t, map, + evt.setValues(null, loggerName, marker, fqcn, level, data, t, contextStack, -1, threadName, -1, location, currentTimeMillis, nanoTime); - + ((MutableContextData) evt.getContextData()).putValue("key", "value"); + final LogEvent actual = evt.createMemento(); assertEquals(evt.getLoggerName(), actual.getLoggerName()); assertEquals(evt.getMarker(), actual.getMarker()); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java index d57a058..964a017 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java @@ -25,7 +25,6 @@ import java.lang.reflect.Field; import java.util.Collections; import java.util.HashMap; import java.util.Map; - import javax.xml.bind.DatatypeConverter; import org.apache.logging.log4j.Level; @@ -264,7 +263,56 @@ public class Log4jLogEventTest { .setTimeMillis(987654321L) .build(); - assertSame(contextMap, event.getContextMap()); + assertEquals(contextMap, event.getContextMap()); + assertSame(contextStack, event.getContextStack()); + assertEquals(true, event.isEndOfBatch()); + assertEquals(true, event.isIncludeLocation()); + assertSame(Level.FATAL, event.getLevel()); + assertSame(fqcn, event.getLoggerFqcn()); + assertSame(name, event.getLoggerName()); + assertSame(marker, event.getMarker()); + assertSame(message, event.getMessage()); + assertEquals(1234567890L, event.getNanoTime()); + assertSame(stackTraceElement, event.getSource()); + assertSame(threadName, event.getThreadName()); + assertSame(exception, event.getThrown()); + assertEquals(987654321L, event.getTimeMillis()); + + final LogEvent event2 = new Log4jLogEvent.Builder(event).build(); + assertEquals("copy constructor builder", event2, event); + assertEquals("same hashCode", event2.hashCode(), event.hashCode()); + } + + @Test + public void testBuilderCorrectlyCopiesAllEventAttributesInclContextData() { + final MutableContextData contextData = new ArrayContextData(); + contextData.putValue("A", "B"); + final ContextStack contextStack = ThreadContext.getImmutableStack(); + final Exception exception = new Exception("test"); + final Marker marker = MarkerManager.getMarker("EVENTTEST"); + final Message message = new SimpleMessage("foo"); + final StackTraceElement stackTraceElement = new StackTraceElement("A", "B", "file", 123); + final String fqcn = "qualified"; + final String name = "Ceci n'est pas une pipe"; + final String threadName = "threadName"; + final Log4jLogEvent event = Log4jLogEvent.newBuilder() // + .setContextData(contextData) // + .setContextStack(contextStack) // + .setEndOfBatch(true) // + .setIncludeLocation(true) // + .setLevel(Level.FATAL) // + .setLoggerFqcn(fqcn) // + .setLoggerName(name) // + .setMarker(marker) // + .setMessage(message) // + .setNanoTime(1234567890L) // + .setSource(stackTraceElement) // + .setThreadName(threadName) // + .setThrown(exception) // + .setTimeMillis(987654321L) + .build(); + + assertSame(contextData, event.getContextData()); assertSame(contextStack, event.getContextStack()); assertEquals(true, event.isEndOfBatch()); assertEquals(true, event.isIncludeLocation()); @@ -286,8 +334,8 @@ public class Log4jLogEventTest { @Test public void testBuilderCorrectlyCopiesMutableLogEvent() throws Exception { - final Map<String, String> contextMap = new HashMap<>(); - contextMap.put("A", "B"); + final MutableContextData contextData = new ArrayContextData(); + contextData.putValue("A", "B"); final ContextStack contextStack = ThreadContext.getImmutableStack(); final Exception exception = new Exception("test"); final Marker marker = MarkerManager.getMarker("EVENTTEST"); @@ -297,7 +345,7 @@ public class Log4jLogEventTest { final String name = "Ceci n'est pas une pipe"; final String threadName = "threadName"; final MutableLogEvent event = new MutableLogEvent(); - event.setContextMap(contextMap); + event.setContextData(contextData); event.setContextStack(contextStack); event.setEndOfBatch(true); event.setIncludeLocation(true); @@ -312,7 +360,7 @@ public class Log4jLogEventTest { event.setThrown(exception); event.setTimeMillis(987654321L); - assertSame(contextMap, event.getContextMap()); + assertSame(contextData, event.getContextData()); assertSame(contextStack, event.getContextStack()); assertEquals(true, event.isEndOfBatch()); assertEquals(true, event.isIncludeLocation()); @@ -328,7 +376,7 @@ public class Log4jLogEventTest { assertEquals(987654321L, event.getTimeMillis()); final LogEvent e2 = new Log4jLogEvent.Builder(event).build(); - assertSame(contextMap, e2.getContextMap()); + assertEquals(contextData, e2.getContextData()); assertSame(contextStack, e2.getContextStack()); assertEquals(true, e2.isEndOfBatch()); assertEquals(true, e2.isIncludeLocation()); @@ -381,7 +429,7 @@ public class Log4jLogEventTest { .setTimeMillis(987654321L) .build(); - assertSame(contextMap, event.getContextMap()); + assertEquals(contextMap, event.getContextMap()); assertSame(contextStack, event.getContextStack()); assertEquals(true, event.isEndOfBatch()); assertEquals(true, event.isIncludeLocation()); @@ -400,7 +448,7 @@ public class Log4jLogEventTest { assertEquals("copy constructor builder", event2, event); assertEquals("same hashCode", event2.hashCode(), event.hashCode()); - assertSame(contextMap, event2.getContextMap()); + assertEquals(contextMap, event2.getContextMap()); assertSame(contextStack, event2.getContextStack()); assertEquals(true, event2.isEndOfBatch()); assertEquals(true, event2.isIncludeLocation()); http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6caf1e83/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java index 928e801..e531adc 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java @@ -23,8 +23,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.MarkerManager; @@ -40,13 +38,13 @@ import static org.junit.Assert.*; * Tests the MutableLogEvent class. */ public class MutableLogEventTest { - private static final Map<String, String> CONTEXTMAP = createContextMap(); + private static final MutableContextData CONTEXT_DATA = createContextData(); private static final ThreadContext.ContextStack STACK = new MutableThreadContextStack(Arrays.asList("abc", "xyz")); - private static Map<String,String> createContextMap() { - final Map<String,String> result = new HashMap<>(); - result.put("a", "1"); - result.put("b", "2"); + private static MutableContextData createContextData() { + final MutableContextData result = new ArrayContextData(); + result.putValue("a", "1"); + result.putValue("b", "2"); return result; } @@ -54,7 +52,7 @@ public class MutableLogEventTest { public void testInitFromCopiesAllFields() { // private ThrowableProxy thrownProxy; final Log4jLogEvent source = Log4jLogEvent.newBuilder() // - .setContextMap(CONTEXTMAP) // + .setContextData(CONTEXT_DATA) // .setContextStack(STACK) // .setEndOfBatch(true) // .setIncludeLocation(true) // @@ -71,7 +69,7 @@ public class MutableLogEventTest { .build(); final MutableLogEvent mutable = new MutableLogEvent(); mutable.initFrom(source); - assertEquals("contextMap", CONTEXTMAP, mutable.getContextMap()); + assertEquals("contextMap", CONTEXT_DATA, mutable.getContextData()); assertEquals("stack", STACK, mutable.getContextStack()); assertEquals("endOfBatch", true, mutable.isEndOfBatch()); assertEquals("IncludeLocation()", true, mutable.isIncludeLocation()); @@ -93,7 +91,7 @@ public class MutableLogEventTest { @Test public void testClear() { final MutableLogEvent mutable = new MutableLogEvent(); - assertNull("context map", mutable.getContextMap()); + assertEquals("context data", 0, mutable.getContextData().size()); assertNull("context stack", mutable.getContextStack()); assertFalse("end of batch", mutable.isEndOfBatch()); assertFalse("incl loc", mutable.isIncludeLocation()); @@ -112,7 +110,7 @@ public class MutableLogEventTest { assertNull("source", mutable.getSource()); assertNull("thrownProxy", mutable.getThrownProxy()); - mutable.setContextMap(CONTEXTMAP); + mutable.setContextData(CONTEXT_DATA); mutable.setContextStack(STACK); mutable.setEndOfBatch(true); mutable.setIncludeLocation(true); @@ -148,7 +146,7 @@ public class MutableLogEventTest { assertNotNull("thrownProxy", mutable.getThrownProxy()); mutable.clear(); - assertNull("context map", mutable.getContextMap()); + assertEquals("context map", 0, mutable.getContextData().size()); assertNull("context stack", mutable.getContextStack()); assertSame("level", Level.OFF, mutable.getLevel()); assertNull("fqcn", mutable.getLoggerFqcn()); @@ -175,7 +173,7 @@ public class MutableLogEventTest { @Test public void testJavaIoSerializable() throws Exception { final MutableLogEvent evt = new MutableLogEvent(); - evt.setContextMap(CONTEXTMAP); + evt.setContextData(CONTEXT_DATA); evt.setContextStack(STACK); evt.setEndOfBatch(true); evt.setIncludeLocation(true); @@ -199,6 +197,7 @@ public class MutableLogEventTest { assertEquals(evt.getLevel(), evt2.getLevel()); assertEquals(evt.getLoggerName(), evt2.getLoggerName()); assertEquals(evt.getMarker(), evt2.getMarker()); + assertEquals(evt.getContextData(), evt2.getContextData()); assertEquals(evt.getContextMap(), evt2.getContextMap()); assertEquals(evt.getContextStack(), evt2.getContextStack()); assertEquals(evt.getMessage(), evt2.getMessage()); @@ -218,7 +217,7 @@ public class MutableLogEventTest { public void testJavaIoSerializableWithThrown() throws Exception { final Error thrown = new InternalError("test error"); final MutableLogEvent evt = new MutableLogEvent(); - evt.setContextMap(CONTEXTMAP); + evt.setContextData(CONTEXT_DATA); evt.setContextStack(STACK); evt.setEndOfBatch(true); evt.setIncludeLocation(true);
