You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by rg...@apache.org on 2011/03/22 00:47:08 UTC

svn commit: r1084027 [1/2] - in /logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers: ./ log4j2-core/ log4j2-core/output/ log4j2-core/src/main/java/org/apache/logging/log4j/core/ log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ log4j...

Author: rgoers
Date: Mon Mar 21 23:47:06 2011
New Revision: 1084027

URL: http://svn.apache.org/viewvc?rev=1084027&view=rev
Log:
More work in progress. Moved converters out of layouts since they might be reused. Created FileManagers so multiple appenders can share the same file. Added locking and buffering to FileAppender. Added performance test to compare Log4j 1.2, Logback and Log4j 2.0 file appenders.

Added:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/CompressionType.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ManagerFactory.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/
      - copied from r1074871, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/PerformanceComparison.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/appender/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/appender/InMemoryAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/pattern/
      - copied from r1025816, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/pattern/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/util/Profiler.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j12-perf.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j2-perf.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/logback-perf.xml
Removed:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/output/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/pattern/
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/pattern/
Modified:
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/pom.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Appender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Logger.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RolloverStrategy.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/AppenderControl.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filterable.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/CachedDateFormat.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ConverterKeys.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileLocationPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FormattingInfo.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FullLocationPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/IntegerPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LevelPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineLocationPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineSeparatorPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LiteralPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LogEventPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LoggerPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/MDCPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/MethodLocationPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/NDCPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/NameAbbreviator.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/NamePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/PatternParser.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/RelativeTimePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ThreadPatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ThrowablePatternConverter.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/SimplePerfTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/config/XMLConfigurationTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/pattern/PatternParserTest.java
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/resources/log4j-test1.xml
    logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/pom.xml

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/pom.xml
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/pom.xml?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/pom.xml (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/pom.xml Mon Mar 21 23:47:06 2011
@@ -53,7 +53,69 @@
       <version>2.4</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.16</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <forkMode>always</forkMode>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+     <profile>
+      <!-- http://www.yourkit.com/docs/80/help/agent.jsp -->
+      <id>yourkit</id>
 
+      <properties>
+        <yourkit.home>/Applications/YourKit_Java_Profiler_8.0.17.app</yourkit.home>
+      </properties>
+      <dependencies>
+        <dependency>
+          <groupId>com.yourkit</groupId>
+          <artifactId>yjp-controller-api-redist</artifactId>
+          <version>8.0.17</version>
+          <scope>system</scope>
+          <systemPath>${yourkit.home}/lib/yjp-controller-api-redist.jar</systemPath>
+        </dependency>
+      </dependencies>
+        <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
 </project>
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Appender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Appender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Appender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Appender.java Mon Mar 21 23:47:06 2011
@@ -21,14 +21,7 @@ import java.util.List;
 /**
  * @issue LOG4J2-36: Appender interface should be refactored
  */
-public interface Appender {
-    /**
-     * Release any resources allocated within the appender such as file
-     * handles, network connections, etc.
-     * <p/>
-     * <p>It is a programming error to append to a closed appender.
-     */
-    void close();
+public interface Appender extends Lifecycle {
 
     /**
      * Log in <code>Appender</code> specific way. When appropriate,
@@ -78,7 +71,7 @@ public interface Appender {
      * If set to true any exceptions thrown by the Appender will be logged but not thrown.
      * @return true if Exceptions should be suppressed, false otherwise.
      */
-    boolean suppressException();
+    boolean isExceptionSuppressed();
 
     ErrorHandler getHandler();
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Logger.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Logger.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Logger.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/Logger.java Mon Mar 21 23:47:06 2011
@@ -21,6 +21,7 @@ import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.spi.AbstractLogger;
 
 import java.util.Iterator;
@@ -34,7 +35,7 @@ import java.util.Map;
  * used in global filters.
  */
 public class Logger extends AbstractLogger {
-    
+
     private final String name;
 
     private final LoggerContext context;
@@ -220,7 +221,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, String msg, Throwable t) {
@@ -235,7 +236,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, String msg, Object p1) {
@@ -250,7 +251,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, String msg, Object p1, Object p2) {
@@ -265,7 +266,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, String msg, Object p1, Object p2, Object p3) {
@@ -280,7 +281,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, String msg, Object p1, Object p2, Object p3,
@@ -296,7 +297,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, Object msg, Throwable t) {
@@ -311,7 +312,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
 
         boolean filter(Level level, Marker marker, Message msg, Throwable t) {
@@ -326,7 +327,7 @@ public class Logger extends AbstractLogg
                 }
             }
 
-            return level.lessOrEqual(intLevel);
+            return intLevel >= level.intLevel();
         }
     }
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java Mon Mar 21 23:47:06 2011
@@ -97,7 +97,12 @@ public class LoggerContext implements or
             throw new NullPointerException("No Configuration was provided");
         }
         Configuration prev = this.config;
+        config.start();
         this.config = config;
+        updateLoggers();
+        if (prev != null) {
+            prev.stop();
+        }
         return prev;
     }
 
@@ -107,12 +112,13 @@ public class LoggerContext implements or
     public synchronized void reconfigure() {
         logger.debug("Reconfiguration started");
         Configuration instance = ConfigurationFactory.getInstance().getConfiguration();
-        instance.start();
+        setConfiguration(instance);
+        /*instance.start();
         Configuration old = setConfiguration(instance);
         updateLoggers();
         if (old != null) {
             old.stop();
-        }
+        } */
         logger.debug("Reconfiguration completed");
     }
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/AppenderBase.java Mon Mar 21 23:47:06 2011
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.ap
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.ErrorHandler;
 import org.apache.logging.log4j.core.Lifecycle;
+import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
@@ -45,7 +46,7 @@ public abstract class AppenderBase exten
 
     private final String name;
 
-    private final boolean errors = false;
+    private final boolean handleException;
 
     /**
      * Allow subclasses access to the status logger without creating another instance.
@@ -57,8 +58,13 @@ public abstract class AppenderBase exten
     public static final String NAME = "name";
 
     public AppenderBase(String name, Filters filters, Layout layout) {
+        this(name, filters, layout, true);
+    }
+
+    public AppenderBase(String name, Filters filters, Layout layout, boolean handleException) {
         this.name = name;
         this.layout = layout;
+        this.handleException = handleException;
         setFilters(filters);
     }
 
@@ -119,8 +125,8 @@ public abstract class AppenderBase exten
      * Some appenders need to propogate exceptions back to the application. When suppressException is false the
      * AppenderControl will allow the exception to percolate.
      */
-    public boolean suppressException() {
-        return true;
+    public boolean isExceptionSuppressed() {
+        return handleException;
     }
 
     public void start() {
@@ -145,4 +151,31 @@ public abstract class AppenderBase exten
         return name;
     }
 
+    /**
+     * Handle an error with a message.
+     * @param msg The message.
+     */
+    public void error(String msg) {
+        handler.error(msg);
+    }
+
+    /**
+     * Handle an error with a message and an exception.
+     * @param msg The message.
+     * @param t The Throwable.
+     */
+    public void error(String msg, Throwable t) {
+        handler.error(msg, t);
+    }
+
+    /**
+     * Handle an error with a message, and exception and a logging event.
+     * @param msg The message.
+     * @param event The LogEvent.
+     * @param t The Throwable.
+     */
+    public void error(String msg, LogEvent event, Throwable t) {
+        handler.error(msg, event, t);
+    }
+
 }

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/CompressionType.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/CompressionType.java?rev=1084027&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/CompressionType.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/CompressionType.java Mon Mar 21 23:47:06 2011
@@ -0,0 +1,8 @@
+package org.apache.logging.log4j.core.appender;
+
+/**
+ *
+ */
+public enum CompressionType {
+    GZIP, NONE, ZIP
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java Mon Mar 21 23:47:06 2011
@@ -16,7 +16,6 @@
  */
 package org.apache.logging.log4j.core.appender;
 
-import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
@@ -24,6 +23,8 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.filter.Filters;
 
+import java.io.OutputStream;
+
 /**
  * ConsoleAppender appends log events to <code>System.out</code> or
  * <code>System.err</code> using a layout specified by the user. The
@@ -41,17 +42,19 @@ public class ConsoleAppender extends Out
     public static final String TARGET = "target";
     public static final String NAME = "name";
 
+    private static ManagerFactory factory = new ConsoleManagerFactory();
+
     public enum Target {
         SYSTEM_OUT, SYSTEM_ERR
     }
 
     public ConsoleAppender(String name, Layout layout) {
-        this(name, layout, null, Target.SYSTEM_OUT);
+        this(name, layout, null, getManager(Target.SYSTEM_OUT));
 
     }
 
-    public ConsoleAppender(String name, Layout layout, Filters filters, Target target) {
-        super(name, layout, filters, target == Target.SYSTEM_OUT ? System.out : System.err);
+    public ConsoleAppender(String name, Layout layout, Filters filters, OutputStreamManager manager) {
+        super(name, layout, filters, true, true, manager);
     }
 
     @PluginFactory
@@ -64,7 +67,32 @@ public class ConsoleAppender extends Out
             return null;
         }
         Target target = t == null ? Target.SYSTEM_OUT : Target.valueOf(t);
-        return new ConsoleAppender(name, layout, filters, target);
+        return new ConsoleAppender(name, layout, filters, getManager(target));
+    }
+
+    private static OutputStreamManager getManager(Target target) {
+        String type = target.name();
+        OutputStream os = target == Target.SYSTEM_OUT ? System.out : System.err;
+        OutputStreamManager manager = OutputStreamManager.getManager(target.name(), factory,
+            new FactoryData(os, type));
+        return manager;
+    }
+
+    private static class FactoryData {
+        OutputStream os;
+        String type;
+
+        public FactoryData(OutputStream os, String type) {
+            this.os = os;
+            this.type = type;
+        }
+    }
+
+    private static class ConsoleManagerFactory implements ManagerFactory<OutputStreamManager, FactoryData> {
+
+        public OutputStreamManager createManager(FactoryData data) {
+            return new OutputStreamManager(data.os, data.type);
+        }
     }
 
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java Mon Mar 21 23:47:06 2011
@@ -68,7 +68,7 @@ public class DefaultErrorHandler impleme
             logger.error(msg, t);
         }
         lastException = current;
-        if (!appender.suppressException() && t != null) {
+        if (!appender.isExceptionSuppressed() && t != null) {
             throw new AppenderRuntimeException(msg, t);
         }
     }
@@ -85,7 +85,7 @@ public class DefaultErrorHandler impleme
             logger.error(msg, t);
         }
         lastException = current;
-        if (!appender.suppressException() && t != null) {
+        if (!appender.isExceptionSuppressed() && t != null) {
             throw new AppenderRuntimeException(msg, t);
         }
     }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java Mon Mar 21 23:47:06 2011
@@ -34,23 +34,40 @@ import java.io.OutputStream;
 @Plugin(name="File",type="Core",elementType="appender",printObject=true)
 public class FileAppender extends OutputStreamAppender {
 
-    public static final String FILE_NAME = "fileName";
-    public static final String APPEND = "append";
     public final String fileName;
 
-    public FileAppender(String name, Layout layout, Filters filters, OutputStream os, String filename) {
-        super(name, layout, filters, os);
+    public FileAppender(String name, Layout layout, Filters filters, FileManager manager, String filename,
+                        boolean handleException, boolean immediateFlush) {
+        super(name, layout, filters, handleException, immediateFlush, manager);
         this.fileName = filename;
     }
 
     @PluginFactory
     public static FileAppender createAppender(@PluginAttr("fileName") String fileName,
                                               @PluginAttr("append") String append,
+                                              @PluginAttr("locking") String locking,
                                               @PluginAttr("name") String name,
+                                              @PluginAttr("immediateFlush") String immediateFlush,
+                                              @PluginAttr("suppressExceptions") String suppress,
+                                              @PluginAttr("bufferedIO") String bufferedIO,
                                               @PluginElement("layout") Layout layout,
                                               @PluginElement("filters") Filters filters) {
 
         boolean isAppend = append == null ? true : Boolean.valueOf(append);
+        boolean isLocking = locking == null ? false : Boolean.valueOf(locking);
+        boolean isBuffered = bufferedIO == null ? true : Boolean.valueOf(bufferedIO);;
+        if (isLocking) {
+            logger.warn("Locking and buffering are mutually exclusive. No buffereing will occur for " + fileName);
+            isBuffered = false;
+        }
+        boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);;
+        if (isBuffered) {
+            logger.warn("Immediate flush and buffering are mutually exclusive. Imeddiate flush will not occur for " +
+                fileName);
+            isFlush = false;
+        }
+
+        boolean handleExceptions = locking == null ? true : Boolean.valueOf(suppress);
 
         if (name == null) {
             logger.error("No name provided for FileAppender");
@@ -62,12 +79,10 @@ public class FileAppender extends Output
             return null;
         }
 
-        try {
-            OutputStream os = new FileOutputStream(fileName, isAppend);
-            return new FileAppender(name, layout, filters, os, fileName);
-        } catch (FileNotFoundException ex) {
-            logger.error("Unable to open file " + fileName, ex);
+        FileManager manager = FileManager.getFileManager(fileName, isAppend, isLocking, isBuffered);
+        if (manager == null) {
             return null;
         }
+        return new FileAppender(name, layout, filters, manager, fileName, handleExceptions, isFlush);
     }
 }

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java?rev=1084027&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/FileManager.java Mon Mar 21 23:47:06 2011
@@ -0,0 +1,160 @@
+/*
+ * 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.appender;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+
+/**
+ *
+ */
+public class FileManager extends OutputStreamManager {
+
+    /**
+     * Allow subclasses access to the status logger without creating another instance.
+     */
+    protected static final Logger logger = StatusLogger.getLogger();
+
+    private boolean isAppend;
+    private boolean isLocking;
+    private CompressionType type = null;
+
+
+    private static ManagerFactory factory = new FileManagerFactory();
+
+    public static FileManager getFileManager(String fileName, boolean append, boolean locking, boolean bufferedIO) {
+
+        if (locking && bufferedIO) {
+            locking = false;
+        }
+        return (FileManager) getManager(fileName, factory, new FactoryData(fileName, append, locking, bufferedIO));
+    }
+
+    public FileManager(String fileName, OutputStream os, boolean append, boolean locking) {
+        super(os, fileName);
+        this.isAppend = append;
+        this.isLocking = locking;
+    }
+
+    @Override
+    public void release() {
+        super.release();
+        if (!isOpen() && type != null) {
+            doCompress();
+        }
+    }
+
+    protected synchronized void write(byte[] bytes, int offset, int length)  {
+
+        if (isLocking) {
+            FileChannel channel = ((FileOutputStream)getOutputStream()).getChannel();
+            try {
+                /* Lock the whole file. This could be optimized to only lock from the current file
+                   position. Note that locking may be advisory on some systems and mandatory on others,
+                   so locking just from the current position would allow reading on systems where
+                   locking is mandatory.  Also, Java 6 will throw an exception if the region of the
+                   file is already locked by another FileChannel in the same JVM. Hopefully, that will
+                   be avoided since every file should have a single file manager - unless two different
+                   files strings are configured that somehow map to the same file.*/
+                FileLock lock = channel.lock(0, Long.MAX_VALUE, false);
+                try {
+                    super.write(bytes, offset, length);
+                } finally {
+                    lock.release();
+                }
+            } catch (IOException ex) {
+                throw new AppenderRuntimeException("Unable to obtain lock on " + getName(), ex);
+            }
+
+        } else {
+            super.write(bytes, offset, length);
+        }
+    }
+
+
+    public String getFileName() {
+        return getName();
+    }
+
+    public boolean isAppend() {
+        return isAppend;
+    }
+
+    public boolean isLocking() {
+        return isLocking;
+    }
+
+    public void setCompressionType(CompressionType type) {
+        this.type = type;
+    }
+
+    public CompressionType getCompressionType() {
+        return this.type;
+    }
+
+    private void doCompress() {
+
+    }
+
+    private static class FactoryData {
+        String fileName;
+        boolean append;
+        boolean locking;
+        boolean bufferedIO;
+
+        public FactoryData(String fileName, boolean append, boolean locking, boolean bufferedIO) {
+            this.fileName = fileName;
+            this.append = append;
+            this.locking = locking;
+            this.bufferedIO = bufferedIO;
+        }
+    }
+
+    private static class FileManagerFactory implements ManagerFactory<FileManager, FactoryData> {
+
+        public FileManager createManager(FactoryData data) {
+            File file = new File(data.fileName);
+            final File parent = file.getParentFile();
+            if (null != parent && !parent.exists()) {
+                parent.mkdirs();
+            }
+
+            OutputStream os;
+            try {
+                os = new FileOutputStream(data.fileName, data.append);
+                if (data.bufferedIO) {
+                    os = new BufferedOutputStream(os);
+                }
+                return new FileManager(data.fileName, os, data.append, data.locking);
+            } catch (FileNotFoundException ex) {
+                logger.error("FileManager (" + data.fileName + ") " + ex);
+            }
+            return null;
+        }
+    }
+
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ListAppender.java Mon Mar 21 23:47:06 2011
@@ -32,7 +32,7 @@ import java.util.List;
  * This appender is primarily used for testing. Use in a real environment is discouraged as the
  * List could eventually grow to cause an OutOfMemoryError.
  */
- @Plugin(name="List",type="Core",elementType="appender",printObject=true)
+@Plugin(name="List",type="Core",elementType="appender",printObject=true)
 public class ListAppender extends AppenderBase {
 
     private List<LogEvent> events = new ArrayList<LogEvent>();

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ManagerFactory.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ManagerFactory.java?rev=1084027&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ManagerFactory.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/ManagerFactory.java Mon Mar 21 23:47:06 2011
@@ -0,0 +1,9 @@
+package org.apache.logging.log4j.core.appender;
+
+/**
+ *
+ */
+public interface ManagerFactory<F, T> {
+
+    F createManager(T data);
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java Mon Mar 21 23:47:06 2011
@@ -24,6 +24,9 @@ import org.apache.logging.log4j.core.fil
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
  * Writes the byte output stream. The stream will already have been encoded.
@@ -44,10 +47,11 @@ public abstract class OutputStreamAppend
      */
     protected boolean immediateFlush = true;
 
-    /**
-     * This is the OutputStream where we will write to.
-     */
-    protected InternalOutputStream os;
+    private volatile OutputStreamManager manager;
+
+    private ReadWriteLock rwLock = new ReentrantReadWriteLock();
+    private Lock readLock = rwLock.readLock();
+    private Lock writeLock = rwLock.writeLock();
 
     /**
      * Instantiate a WriterAppender and set the output destination to a
@@ -55,11 +59,34 @@ public abstract class OutputStreamAppend
      * as its {@link java.io.OutputStream}.
      * @param name The name of the Appender.
      * @param layout The layout to format the message.
-     * @param os The OutputStream.
+     * @param manager The OutputStreamManager.
      */
-    public OutputStreamAppender(String name, Layout layout, Filters filters, OutputStream os) {
-        super(name, filters, layout);
-        this.setOutputStream(os);
+    public OutputStreamAppender(String name, Layout layout, Filters filters, boolean handleException,
+                                boolean immediateFlush, OutputStreamManager manager) {
+        super(name, filters, layout, handleException);
+        if (layout != null) {
+            manager.setHeader(layout.getHeader());
+            manager.setFooter(layout.getFooter());
+        }
+        this.manager = manager;
+        this.immediateFlush = immediateFlush;
+    }
+
+    protected OutputStreamManager getManager() {
+        return manager;
+    }
+
+    protected void replaceManager(OutputStreamManager newManager) {
+
+        writeLock.lock();
+        try {
+            OutputStreamManager old = manager;
+            manager = newManager;
+            old.release();
+        } finally {
+            writeLock.unlock();
+        }
+
     }
 
     /**
@@ -92,8 +119,8 @@ public abstract class OutputStreamAppend
         if (getLayout() == null) {
             logger.error("No layout set for the appender named [" + getName() + "].");
         }
-        if (this.os == null) {
-            logger.error("No OutputStream set for the appender named [" + getName() + "].");
+        if (manager == null) {
+            logger.error("No OutputStreamManager set for the appender named [" + getName() + "].");
         }
         super.start();
     }
@@ -101,63 +128,9 @@ public abstract class OutputStreamAppend
     @Override
     public void stop() {
         super.stop();
-        os.close();
+        manager.release();
     }
 
-
-    /**
-     * <p/>
-     * <p>If the output stream exists and is writable then write a log
-     * statement to the output stream. Otherwise, write a single warning
-     * message to <code>System.err</code>.
-     * <p/>
-     * <p>The format of the output will depend on this appender's
-     * layout.
-     */
-    public void append(LogEvent event) {
-
-        if (!isStarted()) {
-            return;
-        }
-        subAppend(event);
-    }
-
-
-
-    /**
-     * Close this appender instance. The underlying stream or writer is
-     * also closed.
-     * <p/>
-     * <p>Closed appenders cannot be reused.
-     *
-     * @see #setOutputStream
-     */
-    public void close() {
-        reset();
-    }
-
-    /**
-     * <p>Sets the OutputStream where the log output will go. The
-     * specified OutputStream must be opened by the user and be
-     * writable.
-     * <p/>
-     * <p>The <code>java.io.OutputStream</code> will be closed when the
-     * appender instance is closed.
-     * <p/>
-     * <p/>
-     * <p><b>WARNING:</b> Logging to an unopened Writer will fail.
-     *
-     * @param os An already opened OutputStream.
-     */
-    public synchronized void setOutputStream(OutputStream os) {
-        InternalOutputStream prev = this.os;
-        this.os = new InternalOutputStream(os);
-        if (prev != null) {
-            prev.close();
-        }
-    }
-
-
     /**
      * Actual writing occurs here.
      * <p/>
@@ -165,15 +138,21 @@ public abstract class OutputStreamAppend
      * override this method.
      * @param event The LogEvent.
      */
-    protected void subAppend(LogEvent event) {
-        this.os.write(getLayout().format(event));
-
-        if (this.immediateFlush) {
-            this.os.flush();
+    public void append(LogEvent event) {
+        readLock.lock();
+        try {
+            manager.write(getLayout().format(event));
+            if (this.immediateFlush) {
+                manager.flush();
+            }
+        } catch (AppenderRuntimeException ex) {
+            error("Unable to write to stream " + manager.getName() + " for appender " + getName());
+            throw ex;
+        } finally {
+            readLock.unlock();
         }
     }
 
-
     /**
      * The WriterAppender requires a layout. Hence, this method returns
      * <code>true</code>.
@@ -181,111 +160,4 @@ public abstract class OutputStreamAppend
     public boolean requiresLayout() {
         return true;
     }
-
-    /**
-     * Clear internal references to the writer and other variables.
-     * <p/>
-     * Subclasses can override this method for an alternate closing
-     * behavior.
-     */
-    protected synchronized void reset() {
-        InternalOutputStream os = this.os;
-        if (os != null) {
-            this.os = null;
-            os.close();
-        }
-    }
-
-
-    /**
-     * Write a footer as produced by the embedded layout's {@link
-     * org.apache.logging.log4j.core.Layout#getFooter} method.
-     */
-    protected void writeFooter(OutputStream os) {
-        Layout layout = getLayout();
-        if (layout != null) {
-            byte[] b = layout.getFooter();
-            if (b != null && os != null) {
-                try {
-                    os.write(b);
-                    os.flush();
-                } catch (IOException ioe) {
-                    logger.error("Failed to write footer for appender " + getName(), ioe);
-                }
-            }
-        }
-    }
-
-    /**
-     * Write a header as produced by the embedded layout's {@link
-     * org.apache.logging.log4j.core.Layout#getHeader} method.
-     */
-    protected void writeHeader(OutputStream os) {
-        Layout layout = getLayout();
-        if (layout != null) {
-            byte[] b = layout.getHeader();
-            if (b != null && os != null) {
-                try {
-                    os.write(b);
-                } catch (IOException ioe) {
-                    logger.error("Failed to write footer for appender " + getName(), ioe);
-                }
-            }
-        }
-    }
-
-    private class InternalOutputStream extends OutputStream {
-
-        private final OutputStream os;
-
-        public InternalOutputStream(OutputStream os) {
-            writeHeader(os);
-            this.os = os;
-        }
-
-        @Override
-        public void close() {
-            writeFooter(os);
-            try {
-                if (os != System.out && os != System.err) {
-                    os.close();
-                }
-            } catch (IOException ioe) {
-                logger.error("Error closing writer for " + getName(), ioe);
-            }
-
-        }
-
-        @Override
-        public void flush() {
-            try {
-                os.flush();
-            } catch (IOException ioe) {
-                getHandler().error("Error flushing appender " + getName(), ioe);
-            }
-        }
-
-        @Override
-        public void write(byte[] bytes, int i, int i1) {
-            try {
-                os.write(bytes, i, i1);
-            } catch (IOException ioe) {
-                getHandler().error("Error writing to appender " + getName(), ioe);
-            }
-        }
-
-        @Override
-        public void write(byte[] bytes) {
-            write(bytes, 0, bytes.length);
-        }
-
-        @Override
-        public void write(int i) {
-            try {
-                os.write(i);
-            }  catch (IOException ioe) {
-                getHandler().error("Error writing to appender " + getName(), ioe);
-            }
-        }
-    }
 }

Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java?rev=1084027&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamManager.java Mon Mar 21 23:47:06 2011
@@ -0,0 +1,177 @@
+/*
+ * 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.appender;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Lifecycle;
+import org.apache.logging.log4j.internal.StatusLogger;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Manage an OutputStream so that it can be shared by multiple Appenders and will
+ * allow appenders to reconfigure without requiring a new stream.
+ */
+public class OutputStreamManager {
+
+    // Need to lock that map instead of using a ConcurrentMap due to stop removing the
+    // manager from the map and closing the stream, requiring the whole stop method to be locked.
+    private static Map<String, OutputStreamManager> map = new HashMap<String, OutputStreamManager>();
+
+    private static Lock lock = new ReentrantLock();
+
+    /**
+     * Allow subclasses access to the status logger without creating another instance.
+     */
+    protected static final Logger logger = StatusLogger.getLogger();
+
+    private OutputStream os;
+    private String name;
+
+    private int count;
+
+    private byte[] header = null;
+
+    private byte[] footer = null;
+
+    public StringBuilder buffer = new StringBuilder();
+
+    public static OutputStreamManager getManager(String name, ManagerFactory<OutputStreamManager, Object> factory,
+                                                 Object data) {
+        lock.lock();
+        try {
+            OutputStreamManager manager = map.get(name);
+            if (manager == null) {
+                manager = factory.createManager(data);
+                map.put(name, manager);
+            }
+            manager.count++;
+            //System.out.println("Using manager " + name + " " + manager.count);
+            return manager;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public static boolean hasManager(String name) {
+        lock.lock();
+        try {
+            return map.containsKey(name);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public OutputStreamManager(OutputStream os, String streamName) {
+        this.os = os;
+        this.name = streamName;
+    }
+
+    public synchronized void setHeader(byte[] header) {
+        if (header == null) {
+            this.header = header;
+        }
+    }
+
+    public synchronized void setFooter(byte[] footer) {
+        if (footer == null) {
+            this.footer = footer;
+        }
+    }
+
+    public void release() {
+        lock.lock();
+        try {
+            --count;
+            //System.out.println("Released " + name + " " + count);
+            if (count <= 0) {
+                map.remove(name);
+                if (footer != null) {
+                    write(footer);
+                }
+                close();
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    public boolean isOpen() {
+        return count > 0;
+    }
+
+    protected OutputStream getOutputStream() {
+        return os;
+    }
+
+    /**
+     * Some output streams synchronize writes while others do not. Synchronizing here insures that
+     * log events won't be intertwined.
+     * @param bytes The serialized Log event.
+     * @param offset The offset into the byte array.
+     * @param length The number of bytes to write.
+     * @throws AppenderRuntimeException if an error occurs.
+     */
+    protected synchronized void write(byte[] bytes, int offset, int length)  {
+        //System.out.println("write " + count);
+        try {
+            os.write(bytes, offset, length);
+        } catch (IOException ex) {
+            String msg = "Error writing to stream " + name;
+            throw new AppenderRuntimeException(msg, ex);
+        }
+    }
+
+    /**
+     * Some output streams synchronize writes while others do not. Synchronizing here insures that
+     * log events won't be intertwined.
+     * @param bytes The serialized Log event.
+     * @throws AppenderRuntimeException if an error occurs.
+     */
+    protected void write(byte[] bytes)  {
+        write(bytes, 0, bytes.length);
+    }
+
+    protected void close() {
+        if (os == System.out || os == System.err) {
+            return;
+        }
+        try {
+            os.close();
+        } catch (IOException ex) {
+            logger.error("Unable to close stream " + name + ". " + ex);
+        }
+    }
+
+    public void flush() {
+        try {
+            os.flush();
+        } catch (IOException ex) {
+            String msg = "Error flushing stream " + name;
+            throw new AppenderRuntimeException(msg, ex);
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+}

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java Mon Mar 21 23:47:06 2011
@@ -24,9 +24,8 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.filter.Filters;
 
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  *
@@ -34,54 +33,110 @@ import java.io.OutputStream;
 @Plugin(name="RollingFile",type="Core",elementType="appender",printObject=true)
 public class RollingFileAppender extends OutputStreamAppender {
 
-    public static final String FILE_NAME = "fileName";
-    public static final String APPEND = "append";
-    public final String fileName;
-
-    public RollingFileAppender(String name, Layout layout, Filters filters, OutputStream os, String filename) {
-        super(name, layout, filters, os);
-        this.fileName = filename;
+    public final String filePattern;
+    private final RolloverStrategy[] strategies;
+    private final Lock lock = new ReentrantLock();
+    private final boolean bufferedIO;
+
+    public RollingFileAppender(String name, Layout layout, RolloverStrategy[] strategies,
+                               Filters filters, FileManager manager, String filePattern,
+                               CompressionType type, boolean handleException, boolean immediateFlush,
+                               boolean isBuffered) {
+        super(name, layout, filters, handleException, immediateFlush, manager);
+        this.filePattern = filePattern;
+        this.strategies = strategies;
+        manager.setCompressionType(type);
+        this.bufferedIO = isBuffered;
     }
 
     /**
-     * Actual writing occurs here.
-     * <p/>
-     * <p>Most subclasses of <code>OutputStreamAppender</code> will need to
-     * override this method.
+     * Write the log entry rolling over the file when required.
+
      * @param event The LogEvent.
      */
     @Override
-    protected void subAppend(LogEvent event) {
+    public void append(LogEvent event) {
 
-        super.subAppend(event);
+        boolean rollover;
+        lock.lock();
+        try {
+            for (RolloverStrategy strategy : strategies) {
+                rollover = strategy.checkStrategy(event);
+                if (rollover) {
+                    performRollover();
+                    break;
+                }
+            }
+        } finally {
+            lock.unlock();
+        }
+        super.append(event);
     }
 
+    private void performRollover() {
+       // List<String> fileNames = getFileNames();
+       // renameFiles(fileNames);
+        String fileName = "";
+        FileManager mgr = (FileManager) getManager();
+        FileManager manager = FileManager.getFileManager(fileName, mgr.isAppend(), mgr.isLocking(), bufferedIO);
+        manager.setCompressionType(mgr.getCompressionType());
+        replaceManager(manager);
+    }
+
+
 
     @PluginFactory
-    public static RollingFileAppender createAppender(@PluginAttr("fileName") String fileName,
+    public static RollingFileAppender createAppender(@PluginAttr("filePattern") String filePattern,
                                               @PluginAttr("append") String append,
                                               @PluginAttr("name") String name,
+                                              @PluginAttr("compress") String compress,
+                                              @PluginAttr("bufferedIO") String bufferedIO,
+                                              @PluginAttr("immediateFlush") String immediateFlush,
+                                              @PluginElement("strategies") RolloverStrategy[] strategies,
                                               @PluginElement("layout") Layout layout,
-                                              @PluginElement("filters") Filters filters) {
+                                              @PluginElement("filters") Filters filters,
+                                              @PluginAttr("suppressExceptions") String suppress) {
 
         boolean isAppend = append == null ? true : Boolean.valueOf(append);
+        boolean handleExceptions = suppress == null ? true : Boolean.valueOf(suppress);
+        boolean isBuffered = bufferedIO == null ? true : Boolean.valueOf(bufferedIO);;
+        boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);;
+        if (isBuffered) {
+            logger.warn("Immediate flush and buffering are mutually exclusive. Immediate flush will not occur for appender " +
+                 name);
+            isFlush = false;
+        }
+        CompressionType type = CompressionType.NONE;
 
         if (name == null) {
             logger.error("No name provided for FileAppender");
             return null;
         }
 
-        if (fileName == null) {
-            logger.error("No filename provided for FileAppender with name "  + name);
+        if (filePattern == null) {
+            logger.error("No filename pattern provided for FileAppender with name "  + name);
             return null;
         }
 
-        try {
-            OutputStream os = new FileOutputStream(fileName, isAppend);
-            return new RollingFileAppender(name, layout, filters, os, fileName);
-        } catch (FileNotFoundException ex) {
-            logger.error("Unable to open file " + fileName, ex);
+        if (strategies == null) {
+            logger.error("At least one RolloverStrategy must be provided");
             return null;
         }
+
+        if (compress != null) {
+            CompressionType t = CompressionType.valueOf(compress.toUpperCase());
+            if (t != null) {
+                type = t;
+            }
+        }
+
+        String fileName = "";
+        FileManager manager = FileManager.getFileManager(fileName, isAppend, false, isBuffered);
+        if (manager == null) {
+            return null;
+        }
+
+        return new RollingFileAppender(name, layout, strategies, filters, manager, filePattern, type, handleExceptions,
+            isFlush, isBuffered);
     }
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RolloverStrategy.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RolloverStrategy.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RolloverStrategy.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/appender/RolloverStrategy.java Mon Mar 21 23:47:06 2011
@@ -16,9 +16,17 @@
  */
 package org.apache.logging.log4j.core.appender;
 
+import org.apache.logging.log4j.core.LogEvent;
+
 /**
  *
  */
-public interface RolloverStrategy
-{
+public interface RolloverStrategy {
+
+    /**
+     * Check the RolloverStrategy to determine if a rollover should occur.
+     * @param event The LogEvent.
+     * @return true if a rollover should occur.
+     */
+    boolean checkStrategy(LogEvent event);
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/AppenderControl.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/AppenderControl.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/AppenderControl.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/AppenderControl.java Mon Mar 21 23:47:06 2011
@@ -53,10 +53,10 @@ public class AppenderControl {
             recursive.set(this);
 
             if (appender instanceof Lifecycle) {
-                if (!((Lifecycle)appender).isStarted()) {
+                if (!appender.isStarted()) {
                     appender.getHandler().error("Attempted to append to non-started appender " + appender.getName());
 
-                    if (!appender.suppressException()) {
+                    if (!appender.isExceptionSuppressed()) {
                         throw new AppenderRuntimeException("Attempted to append to non-started appender " + appender.getName());
                     }
                 }
@@ -80,12 +80,12 @@ public class AppenderControl {
                 appender.append(event);
             } catch (RuntimeException ex) {
                 appender.getHandler().error("An exception occurred processing Appender " + appender.getName(), ex);
-                if (!appender.suppressException()) {
+                if (!appender.isExceptionSuppressed()) {
                     throw ex;
                 }
             } catch (Exception ex) {
                 appender.getHandler().error("An exception occurred processing Appender " + appender.getName(), ex);
-                if (!appender.suppressException()) {
+                if (!appender.isExceptionSuppressed()) {
                     throw new AppenderRuntimeException(ex);
                 }
             }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/Configuration.java Mon Mar 21 23:47:06 2011
@@ -13,6 +13,8 @@ import java.util.Map;
  */
 public interface Configuration {
 
+    String getName();
+
     LoggerConfig getLoggerConfig(String name);
 
     Map<String, Appender> getAppenders();

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfiguration.java Mon Mar 21 23:47:06 2011
@@ -30,9 +30,11 @@ public class DefaultConfiguration extend
     private static final String CONSOLE = "CONSOLE";;
     private static final String DEFAULT_LEVEL = "org.apache.logging.log4j.level";
     private static final String EMPTY_STRING = "";
+    public static final String DEFAULT_NAME = "Default";
 
     public DefaultConfiguration() {
 
+        setName(DEFAULT_NAME);
         Appender appender = new ConsoleAppender("Console", new BasicLayout());
         addAppender(appender);
         LoggerConfig root = getRootLogger();

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/config/XMLConfiguration.java Mon Mar 21 23:47:06 2011
@@ -88,6 +88,9 @@ public class XMLConfiguration extends Ba
         } catch (ParserConfigurationException pex) {
             logger.error("Error parsing " + source.getSystemId(), pex);
         }
+        if (getName() == null) {
+            setName(source.getSystemId());
+        }
     }
 
     public void setup() {

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filterable.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filterable.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filterable.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filterable.java Mon Mar 21 23:47:06 2011
@@ -26,18 +26,18 @@ import java.util.Iterator;
  *
  */
 public class Filterable {
-    private volatile Filters filters = new Filters(null);
+    private volatile Filters filters = Filters.EMPTY_FILTERS;
 
     public synchronized void addFilter(Filter filter) {
-        filters = Filters.addFilter(filters, filter);
+        filters = filters.addFilter(filter);
     }
 
     public synchronized void removeFilter(Filter filter) {
-        filters = Filters.removeFilter(filters, filter);
+        filters = filters.removeFilter(filter);
     }
 
     public synchronized void clearFilters() {
-        filters = new Filters(null);
+        filters = Filters.EMPTY_FILTERS;
     }
 
     public Iterator<Filter> getFilters() {
@@ -75,7 +75,7 @@ public class Filterable {
     }
 
     protected synchronized void setFilters(Filters newFilters) {
-        filters = newFilters == null ? new Filters(null) : newFilters;
+        filters = newFilters == null ? Filters.EMPTY_FILTERS : newFilters;
     }
 
     protected boolean isFiltered(LogEvent event) {

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/filter/Filters.java Mon Mar 21 23:47:06 2011
@@ -35,27 +35,33 @@ public class Filters implements Iterable
 
     private final List<Filter> filters;
     private final boolean hasFilters;
+    public static final Filters EMPTY_FILTERS = new Filters();
 
-    public Filters(List<Filter> filters) {
+    private Filters() {
+        this.filters = new ArrayList<Filter>();
+        this.hasFilters = false;
+    }
+
+    private Filters(List<Filter> filters) {
         if (filters == null) {
-            this.filters = new ArrayList<Filter>();
+            this.filters = Collections.unmodifiableList(new ArrayList<Filter>());
             this.hasFilters = false;
             return;
         }
-        this.filters = new ArrayList<Filter>(filters);
+        this.filters = Collections.unmodifiableList(filters);
         this.hasFilters = this.filters.size() > 0;
     }
 
-    public static Filters addFilter(Filters f, Filter filter) {
-        Filters newFilters = new Filters(f.filters);
-        newFilters.filters.add(filter);
-        return  newFilters;
+    public Filters addFilter(Filter filter) {
+        List<Filter> filters = new ArrayList<Filter>(this.filters);
+        filters.add(filter);
+        return new Filters(Collections.unmodifiableList(filters));
     }
 
-    public static Filters removeFilter(Filters f, Filter filter) {
-        Filters newFilters = new Filters(f.filters);
-        newFilters.filters.remove(filter);
-        return  newFilters;
+    public Filters removeFilter(Filter filter) {
+        List<Filter> filters = new ArrayList<Filter>(this.filters);
+        filters.remove(filter);
+        return new Filters(Collections.unmodifiableList(filters));
     }
 
     public Iterator<Filter> iterator() {
@@ -63,7 +69,7 @@ public class Filters implements Iterable
     }
 
     public List<Filter> getFilters() {
-        return Collections.unmodifiableList(filters);
+        return filters;
     }
 
     public boolean hasFilters() {

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java?rev=1084027&r1=1084026&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java Mon Mar 21 23:47:06 2011
@@ -22,8 +22,8 @@ import org.apache.logging.log4j.core.con
 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.helpers.OptionConverter;
-import org.apache.logging.log4j.core.layout.pattern.PatternConverter;
-import org.apache.logging.log4j.core.layout.pattern.PatternParser;
+import org.apache.logging.log4j.core.pattern.PatternConverter;
+import org.apache.logging.log4j.core.pattern.PatternParser;
 
 import java.nio.charset.Charset;
 import java.util.List;
@@ -403,6 +403,13 @@ public class PatternLayout extends Layou
         "%r [%t] %p %c %x - %m%n";
 
     /**
+     * A simple pattern.
+     * Current value is <b>%d [%t] %p %c - %m%n</b>.
+     */
+    public static final String SIMPLE_CONVERSION_PATTERN =
+        "%d [%t] %p %c - %m%n";
+
+    /**
      * Initial converter for pattern.
      */
     private List<PatternConverter> converters;
@@ -499,12 +506,12 @@ public class PatternLayout extends Layou
     @PluginFactory
     public static PatternLayout createLayout(@PluginAttr("pattern") String pattern,
                                              @PluginAttr("charset") String charset) {
-        Charset c = Charset.defaultCharset();
+        Charset c = Charset.isSupported("UTF-8") ? Charset.forName("UTF-8") : Charset.defaultCharset();
         if (charset != null) {
             if (Charset.isSupported(charset)) {
                 c = Charset.forName(charset);
             } else {
-                logger.error("Charset " + charset + " is not supported for layout, using default.");
+                logger.error("Charset " + charset + " is not supported for layout, using " + c.displayName());
             }
         }
         if (pattern != null) {

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/CachedDateFormat.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/CachedDateFormat.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/CachedDateFormat.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/CachedDateFormat.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import java.text.DateFormat;
 import java.text.FieldPosition;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ClassNamePatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
@@ -57,16 +57,13 @@ public final class ClassNamePatternConve
      * @param toAppendTo string buffer to which class name will be appended.
      */
     public void format(final LogEvent event, final StringBuilder toAppendTo) {
-        final int initialLength = toAppendTo.length();
 
         StackTraceElement element = event.getSource();
 
         if (element == null) {
             toAppendTo.append(NA);
         } else {
-            toAppendTo.append(element.getClassName());
+            toAppendTo.append(abbreviate(element.getClassName()));
         }
-
-        abbreviate(initialLength, toAppendTo);
     }
 }

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ConverterKeys.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ConverterKeys.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ConverterKeys.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/ConverterKeys.java Mon Mar 21 23:47:06 2011
@@ -1,4 +1,4 @@
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/DatePatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileDatePatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileLocationPatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileLocationPatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileLocationPatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FileLocationPatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FormattingInfo.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FormattingInfo.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FormattingInfo.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FormattingInfo.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 
 /**

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FullLocationPatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FullLocationPatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FullLocationPatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/FullLocationPatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/IntegerPatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/IntegerPatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/IntegerPatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/IntegerPatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LevelPatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LevelPatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LevelPatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LevelPatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.LogEvent;

Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineLocationPatternConverter.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineLocationPatternConverter.java?rev=1084027&r1=1074871&r2=1084027&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineLocationPatternConverter.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/pattern/LineLocationPatternConverter.java Mon Mar 21 23:47:06 2011
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.logging.log4j.core.layout.pattern;
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.plugins.Plugin;



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org