Return-Path: X-Original-To: apmail-logging-commits-archive@minotaur.apache.org Delivered-To: apmail-logging-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 9555AD9B2 for ; Tue, 25 Sep 2012 02:45:35 +0000 (UTC) Received: (qmail 35177 invoked by uid 500); 25 Sep 2012 02:45:35 -0000 Delivered-To: apmail-logging-commits-archive@logging.apache.org Received: (qmail 35148 invoked by uid 500); 25 Sep 2012 02:45:35 -0000 Mailing-List: contact commits-help@logging.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@logging.apache.org Delivered-To: mailing list commits@logging.apache.org Received: (qmail 35132 invoked by uid 99); 25 Sep 2012 02:45:35 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Sep 2012 02:45:35 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Sep 2012 02:45:32 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id ED8C223888CD; Tue, 25 Sep 2012 02:44:49 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1389690 - in /logging/log4j/log4j2/trunk: api/src/main/java/org/apache/logging/log4j/ api/src/main/java/org/apache/logging/log4j/message/ core/src/main/java/org/apache/logging/log4j/core/ core/src/main/java/org/apache/logging/log4j/core/im... Date: Tue, 25 Sep 2012 02:44:49 -0000 To: commits@logging.apache.org From: rgoers@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120925024449.ED8C223888CD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: rgoers Date: Tue Sep 25 02:44:48 2012 New Revision: 1389690 URL: http://svn.apache.org/viewvc?rev=1389690&view=rev Log: Log4J2-83 and Log4J2-84 - Set the Context Map and Context Stack to null in the LogEvent if they are empty. Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/ThreadContext.java logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LogEvent.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/DateLookupTest.java logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java logging/log4j/log4j2/trunk/log4j12-api/src/main/java/org/apache/log4j/NDC.java logging/log4j/log4j2/trunk/src/changes/changes.xml Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/ThreadContext.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/ThreadContext.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/ThreadContext.java (original) +++ logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/ThreadContext.java Tue Sep 25 02:44:48 2012 @@ -17,10 +17,13 @@ package org.apache.logging.log4j; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Stack; - +import java.util.NoSuchElementException; /** * The ThreadContext allows applications to store information either in a Map @@ -31,6 +34,16 @@ import java.util.Stack; */ public final class ThreadContext { + /** + * Empty, immutable Map. + */ + public static final Map EMPTY_MAP = new ImmutableMap(); + + /** + * Empty, immutable ContextStack. + */ + public static final ContextStack EMPTY_STACK = new ImmutableStack(); + private static ThreadLocal> localMap = new InheritableThreadLocal>() { protected Map childValue(Map parentValue) { @@ -38,14 +51,7 @@ public final class ThreadContext { } }; - private static ThreadLocal> localStack = - new InheritableThreadLocal>() { - protected Stack childValue(Stack parentValue) { - return parentValue == null ? null : (Stack) parentValue.clone(); - } - }; - - + private static ThreadLocal localStack = new ThreadLocal(); private ThreadContext() { @@ -112,13 +118,30 @@ public final class ThreadContext { } /** - * Get the current thread's MDC as a hashtable. This method is - * intended to be used internally. + * Get a copy of current thread's context Map. * @return a copy of the context. */ public static Map getContext() { Map map = localMap.get(); - return map == null ? new HashMap() : new HashMap(localMap.get()); + return map == null ? new HashMap() : new HashMap(map); + } + + /** + * Get an immutable copy of the current thread's context Map. + * @return An immutable copy of the ThreadContext Map. + */ + public static Map getImmutableContext() { + Map map = localMap.get(); + return map == null ? new ImmutableMap() : new ImmutableMap(map); + } + + /** + * Return true if the Map is empty. + * @return true if the Map is empty, false otherwise. + */ + public static boolean isEmpty() { + Map map = localMap.get(); + return map == null || map.size() == 0; } /** @@ -132,28 +155,40 @@ public final class ThreadContext { * Return a copy of this thread's stack. * @return A copy of this thread's stack. */ - public static Stack cloneStack() { - Stack stack = localStack.get(); - return stack == null ? new Stack() : (Stack) stack.clone(); + public static ContextStack cloneStack() { + ContextStack stack = localStack.get(); + return stack == null ? new ThreadContextStack() : new ThreadContextStack(stack.asList()); + } + + /** + * Get an immutable copy of this current thread's context stack. + * @return an immutable copy of the ThreadContext stack. + */ + public static ContextStack getImmutableStack() { + ContextStack stack = localStack.get(); + return stack == null ? EMPTY_STACK : new ImmutableStack(stack.asList()); } /** * Set this thread's stack. * @param stack The stack to use. */ - public static void setStack(Stack stack) { - localStack.set(stack); + public static void setStack(Collection stack) { + if (stack.size() == 0) { + return; + } + localStack.set(new ThreadContextStack(stack)); } /** * Get the current nesting depth of this thread's stack. * @return the number of items in the stack. * - * @see #setMaxDepth + * @see #trim */ public static int getDepth() { - Stack stack = localStack.get(); - return stack == null ? 0 : stack.size(); + ContextStack stack = localStack.get(); + return stack == null ? 0 : stack.getDepth(); } /** @@ -165,8 +200,8 @@ public final class ThreadContext { * @return String The innermost diagnostic context. */ public static String pop() { - Stack s = localStack.get(); - if (s == null || s.isEmpty()) { + ContextStack s = localStack.get(); + if (s == null || s.getDepth() == 0) { return ""; } return s.pop(); @@ -182,8 +217,8 @@ public final class ThreadContext { * @return String The innermost diagnostic context. */ public static String peek() { - Stack s = localStack.get(); - if (s == null || s.isEmpty()) { + ContextStack s = localStack.get(); + if (s == null || s.getDepth() == 0) { return ""; } return s.peek(); @@ -198,9 +233,10 @@ public final class ThreadContext { * @param message The new diagnostic context information. */ public static void push(String message) { - Stack stack = localStack.get(); + ContextStack stack = localStack.get(); if (stack == null) { - stack = new Stack(); + stack = new ThreadContextStack(); + localStack.set(stack); } stack.push(message); } @@ -228,24 +264,25 @@ public final class ThreadContext { } /** - * Set maximum depth of this diagnostic context. If the current + * Trims elements from this diagnostic context. If the current * depth is smaller or equal to maxDepth, then no - * action is taken. + * action is taken. If the current depth is larger than newDepth + * then all elements at maxDepth or higher are discarded. *

*

This method is a convenient alternative to multiple {@link * #pop} calls. Moreover, it is often the case that at the end of - * complex call sequences, the depth of the NDC is - * unpredictable. The setMaxDepth method circumvents + * complex call sequences, the depth of the ThreadContext is + * unpredictable. The trim method circumvents * this problem. *

*

For example, the combination *

      * void foo() {
-     *    int depth = NDC.getDepth();
+     *    int depth = ThreadContext.getDepth();
      * 

*   ... complex sequence of calls *

- *   NDC.setMaxDepth(depth); + *   ThreadContext.trim(depth); * } *

*

@@ -253,9 +290,190 @@ public final class ThreadContext { * diagnostic stack is conserved. * * @see #getDepth - * @param maxDepth The maximum depth of the stack. + * @param depth The number of elements to keep. + */ + public static void trim(int depth) { + ContextStack stack = localStack.get(); + if (stack != null) { + stack.trim(depth); + } + } + + /** + * The ThreadContext Stack interface. + */ + public interface ContextStack extends Serializable { + + /** + * Clears all elements from the stack. + */ + void clear(); + + /** + * Return the element at the top of the stack. + * @return The element at the top of the stack. + * @throws java.util.NoSuchElementException if the stack is empty. + */ + String pop(); + + /** + * Return the element at the top of the stack without removing it or null if the stack is empty. + * @return the element at the top of the stack or null if the stack is empty. + */ + String peek(); + + /** + * Add an element to the stack. + * @param message The element to add. + */ + void push(String message); + + /** + * Return the number of elements in the stack. + * @return the number of elements in the stack. + */ + int getDepth(); + + /** + * Returns all the elements in the stack in a List. + * @return all the elements in the stack in a List. + */ + List asList(); + + /** + * Trims elements from the end of the stack. + * @param depth The maximum number of items in the stack to keep. + */ + void trim(int depth); + + /** + * Returns a copy of the ContextStack. + * @return a copy of the ContextStack. + */ + ContextStack copy(); + } + + /** + * The ContextStack implementation. + */ + private static class ThreadContextStack extends ArrayList implements ContextStack { + + private static final long serialVersionUID = 5050501L; + + public ThreadContextStack() { + super(); + } + + public ThreadContextStack(Collection collection) { + super(collection); + } + + public String pop() { + int index = size() - 1; + if (index >= 0) { + String result = get(index); + remove(index); + return result; + } + throw new NoSuchElementException("The ThreadContext stack is empty"); + } + + public String peek() { + int index = size() - 1; + if (index >= 0) { + return get(index); + } + return null; + } + + public void push(String message) { + add(message); + } + + public int getDepth() { + return size(); + } + + public List asList() { + return this; + } + + public void trim(int depth) { + if (depth < 0) { + throw new IllegalArgumentException("Maximum stack depth cannot be negative"); + } + while (size() > depth) { + remove(size() - 1); + } + + } + + public ContextStack copy() { + return new ThreadContextStack(this); + } + } + + /** + * An immutable ContextStack. */ - public static void setMaxDepth(int maxDepth) { + private static class ImmutableStack extends ThreadContextStack { + + private static final long serialVersionUID = 5050502L; + public ImmutableStack() { + } + + public ImmutableStack(Collection collection) { + super(collection); + } + + public ImmutableStack(ThreadContextStack stack) { + super(stack); + } + + @Override + public void push(String message) { + throw new UnsupportedOperationException("Stack cannot be modified"); + } + + @Override + public void trim(int depth) { + throw new UnsupportedOperationException("Stack cannot be modified"); + } + } + + /** + * An immutable Context Map. + */ + private static class ImmutableMap extends HashMap { + private static final long serialVersionUID = 5050503L; + + public ImmutableMap() { + super(); + } + + public ImmutableMap(Map map) { + super(map); + } + + @Override + public String put(String s, String s1) { + throw new UnsupportedOperationException("Map cannot be modified"); + } + + @Override + public void putAll(Map map) { + throw new UnsupportedOperationException("Map cannot be modified"); + } + + @Override + public String remove(Object o) { + throw new UnsupportedOperationException("Map cannot be modified"); + } + + @Override + public void clear() { + throw new UnsupportedOperationException("Map cannot be modified"); + } } } Modified: logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java (original) +++ logging/log4j/log4j2/trunk/api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java Tue Sep 25 02:44:48 2012 @@ -34,6 +34,9 @@ public class StructuredDataMessage exten private String type; + /** + * Supported formats. + */ public enum Format { /** The map should be formatted as XML. */ XML, Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LogEvent.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LogEvent.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LogEvent.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/LogEvent.java Tue Sep 25 02:44:48 2012 @@ -19,11 +19,11 @@ package org.apache.logging.log4j.core; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.message.Message; import java.io.Serializable; import java.util.Map; -import java.util.Stack; /** * @@ -94,9 +94,9 @@ public interface LogEvent extends Serial /** * Get the NDC data. * - * @return A copy of the Nested Diagnostic Context of null; + * @return A copy of the Nested Diagnostic Context or null; */ - Stack getContextStack(); + ThreadContext.ContextStack getContextStack(); /** * Returns the fully qualified class name of the caller of the logging api. Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/impl/Log4jLogEvent.java Tue Sep 25 02:44:48 2012 @@ -27,9 +27,7 @@ import org.apache.logging.log4j.message. import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; -import java.util.HashMap; import java.util.Map; -import java.util.Stack; /** * Implementation of a LogEvent. @@ -46,7 +44,7 @@ public class Log4jLogEvent implements Lo private final long timestamp; private final ThrowableProxy throwable; private final Map mdc; - private final Stack ndc; + private ThreadContext.ContextStack ndc; private String threadName = null; private StackTraceElement location; @@ -60,8 +58,10 @@ public class Log4jLogEvent implements Lo * @param t A Throwable or null. */ public Log4jLogEvent(String loggerName, Marker marker, String fqcn, Level level, Message message, Throwable t) { - this(loggerName, marker, fqcn, level, message, t, ThreadContext.getContext(), ThreadContext.cloneStack(), null, - null, System.currentTimeMillis()); + this(loggerName, marker, fqcn, level, message, t, + ThreadContext.getContext().size() == 0 ? null : ThreadContext.getImmutableContext(), + ThreadContext.getDepth() == 0 ? null : ThreadContext.cloneStack(), null, + null, System.currentTimeMillis()); } /** @@ -79,8 +79,8 @@ public class Log4jLogEvent implements Lo * @param timestamp The timestamp of the event. */ public Log4jLogEvent(String loggerName, Marker marker, String fqcn, Level level, Message message, Throwable t, - Map mdc, Stack ndc, String threadName, StackTraceElement location, - long timestamp) { + Map mdc, ThreadContext.ContextStack ndc, String threadName, + StackTraceElement location, long timestamp) { name = loggerName; this.marker = marker; this.fqcnOfLogger = fqcn; @@ -165,21 +165,19 @@ public class Log4jLogEvent implements Lo } /** - * @doubt Allows direct access to the map passed into the constructor, would allow appender - * or layout to manipulate event as seen by other appenders. + * Returns the immutable copy of the ThreadContext Map. * @return The context Map. */ public Map getContextMap() { - return mdc; + return mdc == null ? ThreadContext.EMPTY_MAP : mdc; } /** - * @doubt Allows direct access to the map passed into the constructor, would allow appender - * or layout to manipulate event as seen by other appenders. + * Returns an immutable copy of the ThreadContext stack. * @return The context Stack. */ - public Stack getContextStack() { - return ndc; + public ThreadContext.ContextStack getContextStack() { + return ndc == null ? ThreadContext.EMPTY_STACK : ndc; } /** @@ -266,8 +264,8 @@ public class Log4jLogEvent implements Lo private final Message message; private final long timestamp; private final Throwable throwable; - private final HashMap mdc; - private final Stack ndc; + private final Map mdc; + private ThreadContext.ContextStack ndc; private String threadName; private StackTraceElement location; @@ -279,7 +277,7 @@ public class Log4jLogEvent implements Lo this.message = event.message; this.timestamp = event.timestamp; this.throwable = event.throwable; - this.mdc = new HashMap(event.mdc); + this.mdc = event.mdc; this.ndc = event.ndc; this.location = event.getSource(); this.threadName = event.getThreadName(); Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/HTMLLayout.java Tue Sep 25 02:44:48 2012 @@ -123,7 +123,7 @@ public final class HTMLLayout extends Ab sbuf.append("").append(LINE_SEP); sbuf.append("").append(LINE_SEP); - if (event.getContextStack().size() > 0) { + if (event.getContextStack().getDepth() > 0) { sbuf.append(""); sbuf.append("NDC: ").append(Transform.escapeTags(event.getContextStack().toString())); Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/XMLLayout.java Tue Sep 25 02:44:48 2012 @@ -75,12 +75,12 @@ public class XMLLayout extends AbstractS private static final int DEFAULT_SIZE = 256; + private static final String[] FORMATS = new String[] {"xml"}; + private final boolean locationInfo; private final boolean properties; private final boolean complete; - private static final String[] FORMATS = new String[] {"xml"}; - protected XMLLayout(boolean locationInfo, boolean properties, boolean complete, Charset charset) { super(charset); this.locationInfo = locationInfo; @@ -136,7 +136,7 @@ public class XMLLayout extends AbstractS } } - if (event.getContextStack() != null && event.getContextStack().size() > 0) { + if (event.getContextStack().getDepth() > 0) { buf.append("\r\n"); Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java Tue Sep 25 02:44:48 2012 @@ -46,6 +46,7 @@ public final class MessagePatternConvert /** * Obtains an instance of pattern converter. * + * @param config The Configuration. * @param options options, may be null. * @return instance of pattern converter. */ Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java (original) +++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java Tue Sep 25 02:44:48 2012 @@ -269,7 +269,8 @@ public final class PatternParser { default: if (currentLiteral.length() != 0) { - patternConverters.add(new LiteralPatternConverter(config, currentLiteral.toString())); + patternConverters.add(new LiteralPatternConverter(config, + currentLiteral.toString())); formattingInfos.add(FormattingInfo.getDefault()); } @@ -292,12 +293,10 @@ public final class PatternParser { formattingInfo = new FormattingInfo(true, formattingInfo.getMinLength(), formattingInfo.getMaxLength()); - break; case '.': state = ParserState.DOT_STATE; - break; default: Modified: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/DateLookupTest.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/DateLookupTest.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/DateLookupTest.java (original) +++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/lookup/DateLookupTest.java Tue Sep 25 02:44:48 2012 @@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.lo 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 org.junit.Test; @@ -84,7 +85,7 @@ public class DateLookupTest { return null; } - public Stack getContextStack() { + public ThreadContext.ContextStack getContextStack() { return null; } Modified: logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java (original) +++ logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java Tue Sep 25 02:44:48 2012 @@ -20,6 +20,7 @@ import org.apache.flume.event.SimpleEven import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LoggingException; 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.helpers.UUIDUtil; import org.apache.logging.log4j.message.MapMessage; @@ -259,7 +260,7 @@ public class FlumeEvent extends SimpleEv * Return a copy of the context stack. * @return a copy of the context stack. */ - public Stack getContextStack() { + public ThreadContext.ContextStack getContextStack() { return event.getContextStack(); } } Modified: logging/log4j/log4j2/trunk/log4j12-api/src/main/java/org/apache/log4j/NDC.java URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j12-api/src/main/java/org/apache/log4j/NDC.java?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/log4j12-api/src/main/java/org/apache/log4j/NDC.java (original) +++ logging/log4j/log4j2/trunk/log4j12-api/src/main/java/org/apache/log4j/NDC.java Tue Sep 25 02:44:48 2012 @@ -53,7 +53,11 @@ public final class NDC { * @return Stack A clone of the current thread's diagnostic context. */ public static Stack cloneStack() { - return org.apache.logging.log4j.ThreadContext.cloneStack(); + Stack stack = new Stack(); + for (String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) { + stack.push(element); + } + return stack; } @@ -187,6 +191,6 @@ public final class NDC { * @param maxDepth The maximum depth of the stack. */ public static void setMaxDepth(int maxDepth) { - org.apache.logging.log4j.ThreadContext.setMaxDepth(maxDepth); + org.apache.logging.log4j.ThreadContext.trim(maxDepth); } } Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1389690&r1=1389689&r2=1389690&view=diff ============================================================================== --- logging/log4j/log4j2/trunk/src/changes/changes.xml (original) +++ logging/log4j/log4j2/trunk/src/changes/changes.xml Tue Sep 25 02:44:48 2012 @@ -23,6 +23,16 @@ + + If the ThreadContext stack is empty the LogEvent will contain a null value to reduce the overhead of + creating log events and in the size of the serialized object. Changed the ThreadContext stack to use + a custom stack interface instead of java.util.Stack as that class is overly heavy. This change will + cause an API incompatibility. + + + If the ThreadContext map is empty the LogEvent will contain a null value to reduce the overhead of creating + log events and in the size of the serialized object. + Add getFormats to MultiformatMessage and allow StructuredDataMessage to format as XML.