[logback-dev] [GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, encoder, created. v0.9.18-29-ge5b5e16

added by portage for gitosis-gentoo git-noreply at pixie.qos.ch
Thu Feb 18 17:13:21 CET 2010


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".

The branch, encoder has been created
        at  e5b5e16ad145327257be746e23153ac14e7bccad (commit)

- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=e5b5e16ad145327257be746e23153ac14e7bccad
http://github.com/ceki/logback/commit/e5b5e16ad145327257be746e23153ac14e7bccad

commit e5b5e16ad145327257be746e23153ac14e7bccad
Author: Ceki Gulcu <ceki at qos.ch>
Date:   Thu Feb 18 17:09:48 2010 +0100

    WriteAppender and sub-classes now expect to work with an Encoder. The
    code compiles but the test do NOT pass. To be considered as ongoing work.

diff --git a/logback-access/src/main/java/ch/qos/logback/access/PatternEncoder.java b/logback-access/src/main/java/ch/qos/logback/access/PatternEncoder.java
new file mode 100644
index 0000000..f27a561
--- /dev/null
+++ b/logback-access/src/main/java/ch/qos/logback/access/PatternEncoder.java
@@ -0,0 +1,16 @@
+package ch.qos.logback.access;
+
+import ch.qos.logback.access.spi.AccessEvent;
+import ch.qos.logback.core.pattern.PatternEncoderBase;
+
+
+public class PatternEncoder extends PatternEncoderBase<AccessEvent> {
+
+  public void start() {
+    layout = new PatternLayout();
+    layout.setContext(context);
+    layout.setPattern(getPattern());
+    layout.start();
+  }
+   
+}
\ No newline at end of file
diff --git a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixture.java b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixture.java
index d6f10bd..e667fad 100644
--- a/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixture.java
+++ b/logback-access/src/test/java/ch/qos/logback/access/jetty/JettyFixture.java
@@ -26,7 +26,7 @@ import org.mortbay.jetty.Request;
 import org.mortbay.jetty.handler.AbstractHandler;
 import org.mortbay.util.ByteArrayISO8859Writer;
 
-import ch.qos.logback.access.PatternLayout;
+import ch.qos.logback.access.PatternEncoder;
 import ch.qos.logback.access.spi.AccessEvent;
 import ch.qos.logback.access.testUtil.NotifyingListAppender;
 import ch.qos.logback.core.ConsoleAppender;
@@ -59,10 +59,10 @@ public class JettyFixture extends JettyFixtureBase {
     ConsoleAppender<AccessEvent> console = new ConsoleAppender<AccessEvent>();
     console.setContext(requestLogImpl);
     console.setName("console");
-    PatternLayout layout = new PatternLayout();
+    PatternEncoder layout = new PatternEncoder();
     layout.setContext(requestLogImpl);
     layout.setPattern("%date %server %clientHost");
-    console.setLayout(layout);
+    console.setEncoder(layout);
     layout.start();
     console.start();
 
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
index 6d7a9ce..5bb119f 100644
--- a/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java
@@ -15,6 +15,7 @@ package ch.qos.logback.classic;
 
 import org.slf4j.LoggerFactory;
 
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.ConsoleAppender;
 import ch.qos.logback.core.status.InfoStatus;
@@ -43,12 +44,12 @@ public class BasicConfigurator {
     ConsoleAppender<ILoggingEvent> ca = new ConsoleAppender<ILoggingEvent>();
     ca.setContext(lc);
     ca.setName("console");
-    PatternLayout pl = new PatternLayout();
+    PatternEncoder pl = new PatternEncoder();
     pl.setContext(lc);
     pl.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
     pl.start();
 
-    ca.setLayout(pl);
+    ca.setEncoder(pl);
     ca.start();
     Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
     rootLogger.addAppender(ca);
diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternEncoder.java b/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternEncoder.java
new file mode 100644
index 0000000..aea9f4a
--- /dev/null
+++ b/logback-classic/src/main/java/ch/qos/logback/classic/encoder/PatternEncoder.java
@@ -0,0 +1,16 @@
+package ch.qos.logback.classic.encoder;
+
+import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.pattern.PatternEncoderBase;
+
+public class PatternEncoder extends PatternEncoderBase<ILoggingEvent> {
+
+  public void start() {
+    layout = new PatternLayout();
+    layout.setContext(context);
+    layout.setPattern(getPattern());
+    layout.start();
+  }
+   
+}
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
index e7b9f6a..f1ee47c 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
@@ -30,10 +30,10 @@ import org.junit.Ignore;
 import org.junit.Test;
 import org.xml.sax.EntityResolver;
 
+import ch.qos.logback.classic.ClassicTestConstants;
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.ClassicTestConstants;
 import ch.qos.logback.classic.joran.JoranConfigurator;
 import ch.qos.logback.classic.spi.DummyThrowableProxy;
 import ch.qos.logback.classic.spi.ILoggingEvent;
@@ -43,7 +43,6 @@ import ch.qos.logback.classic.spi.ThrowableProxy;
 import ch.qos.logback.classic.util.TeztConstants;
 import ch.qos.logback.core.CoreConstants;
 import ch.qos.logback.core.joran.spi.JoranException;
-import ch.qos.logback.core.read.ListAppender;
 import ch.qos.logback.core.testUtil.StringListAppender;
 import ch.qos.logback.core.util.StatusPrinter;
 
@@ -58,17 +57,14 @@ public class HTMLLayoutTest {
     lc = new LoggerContext();
     lc.setName("default");
 
-    ListAppender<ILoggingEvent> appender = new ListAppender<ILoggingEvent>();
-    appender.setContext(lc);
     layout = new HTMLLayout();
     layout.setThrowableRenderer(new DefaultThrowableRenderer());
     layout.setContext(lc);
     layout.setPattern("%level%thread%msg");
     layout.start();
-    appender.setLayout(layout);
+
     root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
-    root.addAppender(appender);
-    appender.start();
+
   }
 
   @After
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThrouhput.java b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThrouhput.java
index 4590a0d..fa2c7eb 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThrouhput.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/issue/lbclassic135/LoggingToFileThrouhput.java
@@ -15,7 +15,7 @@ package ch.qos.logback.classic.issue.lbclassic135;
 
 import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.FileAppender;
 import ch.qos.logback.core.contention.ThreadedThroughputCalculator;
@@ -51,14 +51,14 @@ public class LoggingToFileThrouhput {
   static Logger buildLoggerContext(LoggerContext lc) {
     Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
 
-    PatternLayout patternLayout = new PatternLayout();
+    PatternEncoder patternLayout = new PatternEncoder();
     patternLayout.setContext(lc);
     patternLayout.setPattern("%d %l [%t] - %msg%n");
     patternLayout.start();
     FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
     fileAppender.setContext(lc);
     fileAppender.setFile("target/lbclassic135.log");
-    fileAppender.setLayout(patternLayout);
+    fileAppender.setEncoder(patternLayout);
     fileAppender.setAppend(false);
     fileAppender.start();
     root.addAppender(fileAppender);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
index c499534..159d904 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/FileAppenderPerf.java
@@ -16,7 +16,7 @@ package ch.qos.logback.classic.multiJVM;
 import org.slf4j.Logger;
 
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.FileAppender;
 import ch.qos.logback.core.testUtil.RandomUtil;
@@ -33,12 +33,12 @@ public class FileAppenderPerf {
 
     FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
 
-    PatternLayout patternLayout = new PatternLayout();
+    PatternEncoder patternLayout = new PatternEncoder();
     patternLayout.setPattern("%5p %c - %m%n");
     patternLayout.setContext(loggerContext);
     patternLayout.start();
 
-    fa.setLayout(patternLayout);
+    fa.setEncoder(patternLayout);
     fa.setFile(filename);
     fa.setAppend(false);
     fa.setImmediateFlush(true);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
index 9a029c1..b33a635 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeFileAppender.java
@@ -16,7 +16,7 @@ package ch.qos.logback.classic.multiJVM;
 import org.slf4j.Logger;
 
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.FileAppender;
 
@@ -58,12 +58,12 @@ public class SafeModeFileAppender {
 
     FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
 
-    PatternLayout patternLayout = new PatternLayout();
+    PatternEncoder patternLayout = new PatternEncoder();
     patternLayout.setPattern(stamp + " %5p - %m%n");
     patternLayout.setContext(loggerContext);
     patternLayout.start();
 
-    fa.setLayout(patternLayout);
+    fa.setEncoder(patternLayout);
     fa.setFile(filename);
     fa.setAppend(true);
     fa.setImmediateFlush(true);
diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
index 0878bbf..367e1f2 100644
--- a/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
+++ b/logback-classic/src/test/java/ch/qos/logback/classic/multiJVM/SafeModeRollingFileAppender.java
@@ -16,7 +16,7 @@ package ch.qos.logback.classic.multiJVM;
 import org.slf4j.Logger;
 
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.rolling.RollingFileAppender;
 import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
@@ -61,12 +61,12 @@ public class SafeModeRollingFileAppender {
     LoggerContext loggerContext = new LoggerContext();
 
     RollingFileAppender<ILoggingEvent> rfa = new RollingFileAppender<ILoggingEvent>();
-    PatternLayout patternLayout = new PatternLayout();
+    PatternEncoder patternLayout = new PatternEncoder();
     patternLayout.setPattern(stamp + " %5p - %-50m%n");
     patternLayout.setContext(loggerContext);
     patternLayout.start();
 
-    rfa.setLayout(patternLayout);
+    rfa.setEncoder(patternLayout);
     
     rfa.setAppend(true);
     rfa.setImmediateFlush(true);
diff --git a/logback-core/src/main/java/ch/qos/logback/core/Appender.java b/logback-core/src/main/java/ch/qos/logback/core/Appender.java
index 856e387..e951877 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/Appender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Appender.java
@@ -33,16 +33,6 @@ public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E
   void doAppend(E event) throws LogbackException;
 
   /**
-   * Set the {@link Layout} for this appender.
-   */
-  public void setLayout(Layout<E> layout);
-
-  /**
-   * Returns this appenders layout.
-   */
-  public Layout<E> getLayout();
-
-  /**
    * Set the name of this appender. The name is used by other components to
    * identify this appender.
    * 
diff --git a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
index 4183767..b6939bf 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java
@@ -32,12 +32,6 @@ import ch.qos.logback.core.status.WarnStatus;
 abstract public class AppenderBase<E> extends ContextAwareBase implements
     Appender<E> {
 
-  /**
-   * The layout variable does not need to be set depending on the appender. Some
-   * appenders do not need a layout.
-   */
-  protected Layout<E> layout;
-
   protected boolean started = false;
 
   /**
@@ -144,19 +138,4 @@ abstract public class AppenderBase<E> extends ContextAwareBase implements
     return fai.getFilterChainDecision(event);
   }
 
-  /**
-   * Returns the layout of this appender. The returned value may be null if this
-   * appender does not have a layout.
-   */
-  public Layout<E> getLayout() {
-    return layout;
-  }
-
-  /**
-   * Set the layout for this appender. Note that some appenders have their own
-   * (fixed) layouts or do not use any.
-   */
-  public void setLayout(Layout<E> layout) {
-    this.layout = layout;
-  }
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java b/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
index 1c52db7..24d31fe 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/ConsoleAppender.java
@@ -74,9 +74,9 @@ public class ConsoleAppender<E> extends WriterAppender<E> {
 
     public void start() {
       if (target.equals(SYSTEM_OUT)) {
-        setWriter(createWriter(System.out));
+        setWriter(System.out);
       } else {
-        setWriter(createWriter(System.err));
+        setWriter(System.err);
       }
       super.start();
     }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java b/logback-core/src/main/java/ch/qos/logback/core/Encoder.java
similarity index 57%
copy from logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
copy to logback-core/src/main/java/ch/qos/logback/core/Encoder.java
index 8e1d504..87a7350 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/Encoder.java
@@ -11,16 +11,18 @@
  * under the terms of the GNU Lesser General Public License version 2.1
  * as published by the Free Software Foundation.
  */
-package ch.qos.logback.core.appender;
+package ch.qos.logback.core;
 
-import java.io.Writer;
+import java.io.IOException;
+import java.io.OutputStream;
 
-import ch.qos.logback.core.WriterAppender;
+import ch.qos.logback.core.spi.ContextAware;
+import ch.qos.logback.core.spi.LifeCycle;
 
-public class DummyAppender<E> extends WriterAppender<E> {
-
-  DummyAppender(Writer writer) {
-    this.setWriter(writer);
-  }
+public interface Encoder<E> extends ContextAware, LifeCycle {
+  
+  void doEncode(E event, OutputStream os) throws IOException;
 
+  void close(OutputStream os) throws IOException;
+  
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java b/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
index 2b915d2..c76aef0 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/FileAppender.java
@@ -13,11 +13,9 @@
  */
 package ch.qos.logback.core;
 
-import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.Writer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 
@@ -192,11 +190,11 @@ public class FileAppender<E> extends WriterAppender<E> {
     if (prudent) {
       fileChannel = fileOutputStream.getChannel();
     }
-    Writer w = createWriter(fileOutputStream);
-    if (bufferedIO) {
-      w = new BufferedWriter(w, bufferSize);
-    }
-    setWriter(w);
+//    Writer w = createWriter(fileOutputStream);
+//    if (bufferedIO) {
+//      w = new BufferedWriter(w, bufferSize);
+//    }
+    setWriter(fileOutputStream);
   }
 
   public boolean isBufferedIO() {
@@ -238,7 +236,7 @@ public class FileAppender<E> extends WriterAppender<E> {
     this.append = append;
   }
 
-  final private void safeWrite(String s) throws IOException {
+  final private void safeWrite(E event) throws IOException {
     FileLock fileLock = null;
     try {
       fileLock = fileChannel.lock();
@@ -247,7 +245,7 @@ public class FileAppender<E> extends WriterAppender<E> {
       if (size != position) {
         fileChannel.position(size);
       }
-      super.writerWrite(s, true);
+      super.writeOut(event);
     } finally {
       if (fileLock != null) {
         fileLock.release();
@@ -256,11 +254,11 @@ public class FileAppender<E> extends WriterAppender<E> {
   }
 
   @Override
-  protected void writerWrite(String s, boolean flush) throws IOException {
+  protected void writeOut(E event) throws IOException {
     if (prudent && fileChannel != null) {
-      safeWrite(s);
+      safeWrite(event);
     } else {
-      super.writerWrite(s, flush);
+      super.writeOut(event);
     }
   }
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
index 6a258d7..8c9efe3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java
@@ -31,8 +31,6 @@ import ch.qos.logback.core.status.WarnStatus;
 abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase implements
     Appender<E> {
 
-  protected Layout<E> layout;
-  
   protected boolean started = false;
 
   // using a ThreadLocal instead of a boolean add 75 nanoseconds per
@@ -146,12 +144,4 @@ abstract public class UnsynchronizedAppenderBase<E> extends ContextAwareBase imp
   public FilterReply getFilterChainDecision(E event) {
     return fai.getFilterChainDecision(event);
   }
-
-  public Layout<E> getLayout() {
-    return layout;
-  }
-
-  public void setLayout(Layout<E> layout) {
-    this.layout = layout;
-  }
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/WriterAppender.java b/logback-core/src/main/java/ch/qos/logback/core/WriterAppender.java
index d4e66d6..c1f36e4 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/WriterAppender.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/WriterAppender.java
@@ -16,7 +16,6 @@ package ch.qos.logback.core;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.Writer;
 
 import ch.qos.logback.core.status.ErrorStatus;
 
@@ -31,6 +30,8 @@ import ch.qos.logback.core.status.ErrorStatus;
  */
 public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
 
+  protected Encoder<E> encoder;
+  
   /**
    * Immediate flush means that the underlying writer or output stream will be
    * flushed at the end of each append operation. Immediate flush is slower but
@@ -54,9 +55,9 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
   private String encoding;
 
   /**
-   * This is the {@link Writer Writer} where we will write to.
+   * This is the {@link OutputStream outputStream} where we will write to.
    */
-  private Writer writer;
+  private OutputStream outputStream;
 
   /**
    * The default constructor does nothing.
@@ -94,14 +95,14 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
    */
   public void start() {
     int errors = 0;
-    if (this.layout == null) {
+    if (this.encoder == null) {
       addStatus(new ErrorStatus("No layout set for the appender named \""
           + name + "\".", this));
       errors++;
     }
 
-    if (this.writer == null) {
-      addStatus(new ErrorStatus("No writer set for the appender named \""
+    if (this.outputStream == null) {
+      addStatus(new ErrorStatus("No output stream set for the appender named \""
           + name + "\".", this));
       errors++;
     }
@@ -136,12 +137,12 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
    * Close the underlying {@link java.io.Writer}.
    */
   protected void closeWriter() {
-    if (this.writer != null) {
+    if (this.outputStream != null) {
       try {
         // before closing we have to output out layout's footer
         writeFooter();
-        this.writer.close();
-        this.writer = null;
+        this.outputStream.close();
+        this.outputStream = null;
       } catch (IOException e) {
         addStatus(new ErrorStatus("Could not close writer for WriterAppener.",
             this, e));
@@ -160,7 +161,6 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
     OutputStreamWriter retval = null;
 
     String enc = getEncoding();
-
     try {
       if (enc != null) {
         retval = new OutputStreamWriter(os, enc);
@@ -185,25 +185,7 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
   }
 
   void writeHeader() {
-    if (layout != null && (this.writer != null)) {
-      try {
-        StringBuilder sb = new StringBuilder();
-        appendIfNotNull(sb, layout.getFileHeader());
-        appendIfNotNull(sb, layout.getPresentationHeader());
-        if (sb.length() > 0) {
-          sb.append(CoreConstants.LINE_SEPARATOR);
-          // If at least one of file header or presentation header were not
-          // null, then append a line separator.
-          // This should be useful in most cases and should not hurt.
-          writerWrite(sb.toString(), true);
-        }
-
-      } catch (IOException ioe) {
-        this.started = false;
-        addStatus(new ErrorStatus("Failed to write header for appender named ["
-            + name + "].", this, ioe));
-      }
-    }
+    
   }
 
   private void appendIfNotNull(StringBuilder sb, String s) {
@@ -213,14 +195,10 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
   }
 
   void writeFooter() {
-    if (layout != null && this.writer != null) {
+    if (encoder != null && this.outputStream != null) {
       try {
         StringBuilder sb = new StringBuilder();
-        appendIfNotNull(sb, layout.getPresentationFooter());
-        appendIfNotNull(sb, layout.getFileFooter());
-        if (sb.length() > 0) {
-          writerWrite(sb.toString(), true); // force flush
-        }
+        encoder.close(outputStream);
       } catch (IOException ioe) {
         this.started = false;
         addStatus(new ErrorStatus("Failed to write footer for appender named ["
@@ -238,21 +216,19 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
    * @param writer
    *          An already opened Writer.
    */
-  public synchronized void setWriter(Writer writer) {
+  public synchronized void setWriter(OutputStream outputStream) {
     // close any previously opened writer
     closeWriter();
 
-    this.writer = writer;
+    this.outputStream = outputStream;
     writeHeader();
   }
 
-  protected void writerWrite(String s, boolean flush) throws IOException {
-    this.writer.write(s);
-    if (flush) {
-      this.writer.flush();
-    }
+  
+  void writeOut(E event) throws IOException {
+    this.encoder.doEncode(event, outputStream);
   }
-
+  
   /**
    * Actual writing occurs here.
    * <p>
@@ -266,10 +242,7 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
       return;
     }
     try {
-      String output = this.layout.doLayout(event);
-      synchronized (this) {
-        writerWrite(output, this.immediateFlush);
-      }
+      writeOut(event);
     } catch (IOException ioe) {
       // as soon as an exception occurs, move to non-started state
       // and add a single ErrorStatus to the SM.
@@ -277,4 +250,14 @@ public class WriterAppender<E> extends UnsynchronizedAppenderBase<E> {
       addStatus(new ErrorStatus("IO failure in appender", this, ioe));
     }
   }
+
+  public Encoder<E> getEncoder() {
+    return encoder;
+  }
+
+  public void setEncoder(Encoder<E> encoder) {
+    this.encoder = encoder;
+  }
+  
+  
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java
new file mode 100644
index 0000000..6d53222
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EncoderBase.java
@@ -0,0 +1,22 @@
+package ch.qos.logback.core.encoder;
+
+import ch.qos.logback.core.Encoder;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+abstract public class EncoderBase<E> extends ContextAwareBase implements Encoder<E> {
+
+  protected boolean started;
+  
+
+  public boolean isStarted() {
+    return started;
+  }
+  
+  public void start() {
+    started = true;
+  }
+
+  public void stop() {
+    started = false;
+  }
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/html/LayoutWrappingEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/html/LayoutWrappingEncoder.java
new file mode 100644
index 0000000..8f99398
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/html/LayoutWrappingEncoder.java
@@ -0,0 +1,44 @@
+package ch.qos.logback.core.html;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import ch.qos.logback.core.Encoder;
+import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+public class LayoutWrappingEncoder<E> extends ContextAwareBase implements Encoder<E>  {
+
+  boolean started;
+  protected Layout<E> layout;
+  
+  public Layout<E> getLayout() {
+    return layout;
+  }
+
+  public void setLayout(Layout<E> layout) {
+    this.layout = layout;
+  }
+
+  public void close(OutputStream os) throws IOException {
+  }
+
+  public void doEncode(E event, OutputStream os) throws IOException {
+    String txt = layout.doLayout(event);
+    os.write(txt.getBytes());
+    os.flush();
+  }
+
+  public boolean isStarted() {
+    return false;
+  }
+
+  public void start() {
+    started = true;
+  }
+
+  public void stop() {
+  }
+
+
+}
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
index 37744f1..b2be4b5 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
@@ -54,7 +54,9 @@ import ch.qos.logback.core.util.OptionHelper;
 public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
 
   protected Layout<E> subjectLayout;
-
+  
+  protected Layout<E> layout;
+  
   private List<String> to = new ArrayList<String>();
   private String from;
   private String subjectStr = null;
@@ -435,4 +437,12 @@ public abstract class SMTPAppenderBase<E> extends AppenderBase<E> {
     this.charsetEncoding = charsetEncoding;
   }
 
+  public Layout<E> getLayout() {
+    return layout;
+  }
+
+  public void setLayout(Layout<E> layout) {
+    this.layout = layout;
+  }
+
 }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
index 8c0d660..551de9e 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SyslogAppenderBase.java
@@ -33,6 +33,7 @@ public abstract class SyslogAppenderBase<E> extends AppenderBase<E> {
   final static String SYSLOG_LAYOUT_URL = CoreConstants.CODES_URL + "#syslog_layout";
   final static int MSG_SIZE_LIMIT = 256*1024;
   
+  Layout<E> layout;
   String facilityStr;
   String syslogHost;
   protected String suffixPattern;
@@ -206,12 +207,10 @@ public abstract class SyslogAppenderBase<E> extends AppenderBase<E> {
   }
 
 
-  @Override
   public Layout<E> getLayout() {
     return layout;
   }
 
-  @Override
   public void setLayout(Layout<E> layout) {
     addWarn("The layout of a SyslogAppender cannot be set directly. See also "+SYSLOG_LAYOUT_URL);
   }
diff --git a/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternEncoderBase.java b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternEncoderBase.java
new file mode 100644
index 0000000..a3bfc16
--- /dev/null
+++ b/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternEncoderBase.java
@@ -0,0 +1,45 @@
+package ch.qos.logback.core.pattern;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import ch.qos.logback.core.Encoder;
+import ch.qos.logback.core.spi.ContextAwareBase;
+
+public class PatternEncoderBase<E> extends ContextAwareBase implements Encoder<E> {
+
+  boolean started;
+  protected PatternLayoutBase<E> layout;
+  String pattern;
+  
+  public void close(OutputStream os) throws IOException {
+  }
+
+  public void doEncode(E event, OutputStream os) throws IOException {
+    String txt = layout.doLayout(event);
+    os.write(txt.getBytes());
+    os.flush();
+  }
+
+  public boolean isStarted() {
+    return false;
+  }
+
+  public void start() {
+    started = true;
+  }
+
+  public void stop() {
+  }
+
+  public String getPattern() {
+    return pattern;
+  }
+
+  public void setPattern(String pattern) {
+    this.pattern = pattern;
+  }
+
+  
+
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
index e58a758..e4216c2 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
@@ -14,7 +14,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.testUtil.Env;
 import ch.qos.logback.core.testUtil.RandomUtil;
 import ch.qos.logback.core.util.StatusPrinter;
@@ -60,7 +60,7 @@ public class FileAppenderResilienceTest {
         + "]");
 
     fa.setName("FILE");
-    fa.setLayout(new EchoLayout<Object>());
+    fa.setEncoder(new EchoEncoder<Object>());
     fa.setFile(logfileStr);
     fa.start();
   }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/WriterAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/WriterAppenderTest.java
index c560a27..e25d9d7 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/WriterAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/WriterAppenderTest.java
@@ -14,15 +14,15 @@
 package ch.qos.logback.core;
 
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertTrue;
 
-import java.io.StringWriter;
-import java.io.Writer;
+import java.io.ByteArrayOutputStream;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import ch.qos.logback.core.html.LayoutWrappingEncoder;
 import ch.qos.logback.core.pattern.parser.SamplePatternLayout;
 
 public class WriterAppenderTest {
@@ -85,7 +85,7 @@ public class WriterAppenderTest {
   public void headerFooterCheck(String fileHeader, String presentationHeader, String presentationFooter, String fileFooter) {
     WriterAppender<Object> wa = new WriterAppender<Object>();
     wa.setContext(context);
-    Writer sw = new StringWriter();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
  
     SamplePatternLayout<Object> spl = new SamplePatternLayout<Object>();
     spl.setContext(context);
@@ -96,13 +96,16 @@ public class WriterAppenderTest {
     spl.setFileFooter(fileFooter);
   
     spl.start();
+    LayoutWrappingEncoder<Object> encoder = new LayoutWrappingEncoder<Object>();
+    encoder.setLayout(spl);
+    encoder.setContext(context);
     
-    wa.setLayout(spl);
-    wa.setWriter(sw);
+    wa.setEncoder(encoder);
+    wa.setWriter(baos);
     wa.start();
     
     wa.stop();
-    String result = sw.toString();
+    String result = baos.toString();
 
     String expectedHeader = emtptyIfNull(fileHeader) + emtptyIfNull(presentationHeader);
     assertTrue(result, result.startsWith(expectedHeader));
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
index e10888f..2f98da8 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/ConsoleAppenderTest.java
@@ -25,8 +25,9 @@ import org.junit.Test;
 import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.ConsoleAppender;
 import ch.qos.logback.core.CoreConstants;
+import ch.qos.logback.core.encoder.DummyEncoder;
+import ch.qos.logback.core.encoder.NopEncoder;
 import ch.qos.logback.core.layout.DummyLayout;
-import ch.qos.logback.core.layout.NopLayout;
 import ch.qos.logback.core.util.TeeOutputStream;
 
 
@@ -63,7 +64,7 @@ public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
 
   protected Appender<Object> getConfiguredAppender() {
     ConsoleAppender<Object> ca = new ConsoleAppender<Object>();
-    ca.setLayout(new NopLayout<Object>());
+    ca.setEncoder(new NopEncoder<Object>());
     ca.start();
     return ca;
   }
@@ -71,7 +72,7 @@ public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
   @org.junit.Test
   public void testBasic() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
-    ca.setLayout(new DummyLayout<Object>());
+    ca.setEncoder(new DummyEncoder<Object>());
     ca.start();
     ca.doAppend(new Object());
     assertEquals(DummyLayout.DUMMY, tee.toString());
@@ -80,9 +81,9 @@ public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
   @org.junit.Test
   public void testOpen() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
-    DummyLayout<Object> dummyLayout = new DummyLayout<Object>();
-    dummyLayout.setFileHeader("open");
-    ca.setLayout(dummyLayout);
+    DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
+    dummyEncoder.setFileHeader("open");
+    ca.setEncoder(dummyEncoder);
     ca.start();
     ca.doAppend(new Object());
     ca.stop();
@@ -92,9 +93,9 @@ public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
   @Test
   public void testClose() {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
-    DummyLayout<Object> dummyLayout = new DummyLayout<Object>();
-    dummyLayout.setFileFooter("CLOSED");
-    ca.setLayout(dummyLayout);
+    DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
+    dummyEncoder.setFileFooter("CLOSED");
+    ca.setEncoder(dummyEncoder);
     ca.start();
     ca.doAppend(new Object());
     ca.stop();
@@ -106,9 +107,10 @@ public class ConsoleAppenderTest extends AbstractAppenderTest<Object> {
   @Test  
   public void testUTF16BE() throws UnsupportedEncodingException {
     ConsoleAppender<Object> ca = (ConsoleAppender<Object>) getAppender();
-    ca.setLayout(new DummyLayout<Object>());
+    DummyEncoder<Object> dummyEncoder = new DummyEncoder<Object>();
     String encodingName = "UTF-16BE";
-    ca.setEncoding(encodingName);
+    dummyEncoder.setEncodingName(encodingName);
+    ca.setEncoder(dummyEncoder);
     ca.start();
     ca.doAppend(new Object());
 
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
index 8e1d504..d2f0c82 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
@@ -13,14 +13,14 @@
  */
 package ch.qos.logback.core.appender;
 
-import java.io.Writer;
+import java.io.OutputStream;
 
 import ch.qos.logback.core.WriterAppender;
 
 public class DummyAppender<E> extends WriterAppender<E> {
 
-  DummyAppender(Writer writer) {
-    this.setWriter(writer);
+  DummyAppender(OutputStream os) {
+    this.setWriter(os);
   }
 
 }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
index fafc4cf..b728166 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppenderTest.java
@@ -15,37 +15,37 @@ package ch.qos.logback.core.appender;
 
 import static org.junit.Assert.assertEquals;
 
-import java.io.StringWriter;
+import java.io.ByteArrayOutputStream;
 
 import org.junit.Test;
 
 import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.encoder.DummyEncoder;
 import ch.qos.logback.core.layout.DummyLayout;
-import ch.qos.logback.core.layout.NopLayout;
 
 
-public class DummyAppenderTest {
+public class DummyAppenderTest extends AbstractAppenderTest<Object> {
 
+  ByteArrayOutputStream baos = new ByteArrayOutputStream();
   
   protected Appender<Object> getAppender() {
-    return new DummyAppender<Object>(new StringWriter());
+    return new DummyAppender<Object>(baos);
   }
   
   protected Appender<Object> getConfiguredAppender() {
-    DummyAppender<Object> da = new DummyAppender<Object>(new StringWriter());
-    da.setLayout(new NopLayout<Object>());
+    DummyAppender<Object> da = new DummyAppender<Object>(baos);
+    da.setEncoder(new DummyEncoder<Object>());
     da.start();
     return da;
   }
 
   @Test
   public void testBasic() {
-    StringWriter sw = new StringWriter();
-    DummyAppender<Object> da = new DummyAppender<Object>(sw);
-    da.setLayout(new DummyLayout<Object>());
+    DummyAppender<Object> da = new DummyAppender<Object>(baos);
+    da.setEncoder(new DummyEncoder<Object>());
     da.start();
     da.doAppend(new Object());
-    assertEquals(DummyLayout.DUMMY, sw.getBuffer().toString());
+    assertEquals(DummyLayout.DUMMY, baos.toString());
   }
   
 }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
index 38ef9dd..b0fcdcf 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/appender/FileAppenderTest.java
@@ -27,8 +27,8 @@ import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
 import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.layout.DummyLayout;
-import ch.qos.logback.core.layout.NopLayout;
+import ch.qos.logback.core.encoder.DummyEncoder;
+import ch.qos.logback.core.encoder.NopEncoder;
 import ch.qos.logback.core.status.Status;
 import ch.qos.logback.core.status.StatusManager;
 import ch.qos.logback.core.util.CoreTestConstants;
@@ -45,7 +45,7 @@ public class FileAppenderTest extends AbstractAppenderTest<Object> {
 
   protected Appender<Object> getConfiguredAppender() {
     FileAppender<Object> appender = new FileAppender<Object>();
-    appender.setLayout(new NopLayout<Object>());
+    appender.setEncoder(new NopEncoder<Object>());
     appender.setFile(CoreTestConstants.OUTPUT_DIR_PREFIX+"temp.log");
     appender.setName("test");
     appender.setContext(context);
@@ -58,7 +58,7 @@ public class FileAppenderTest extends AbstractAppenderTest<Object> {
     String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + "temp.log";
 
     FileAppender<Object> appender = new FileAppender<Object>();
-    appender.setLayout(new DummyLayout<Object>());
+    appender.setEncoder(new DummyEncoder<Object>());
     appender.setAppend(false);
     appender.setFile(filename);
     appender.setName("smoke");
@@ -78,7 +78,7 @@ public class FileAppenderTest extends AbstractAppenderTest<Object> {
         + "/testing.txt";
     File file = new File(filename);
     FileAppender<Object> appender = new FileAppender<Object>();
-    appender.setLayout(new DummyLayout<Object>());
+    appender.setEncoder(new DummyEncoder<Object>());
     appender.setAppend(false);
     appender.setFile(filename);
     appender.setName("testCreateParentFolders");
@@ -100,7 +100,7 @@ public class FileAppenderTest extends AbstractAppenderTest<Object> {
     String filename = CoreTestConstants.OUTPUT_DIR_PREFIX + diff + "testing.txt";
     File file = new File(filename);
     FileAppender<Object> appender = new FileAppender<Object>();
-    appender.setLayout(new DummyLayout<Object>());
+    appender.setEncoder(new DummyEncoder<Object>());
     appender.setFile(filename);
     appender.setName("testPrudentMode");
     appender.setContext(context);
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java
new file mode 100644
index 0000000..2e82951
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/DummyEncoder.java
@@ -0,0 +1,79 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.encoder;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import ch.qos.logback.core.CoreConstants;
+
+public class DummyEncoder<E> extends EncoderBase<E> {
+
+  public static final String DUMMY = "dummy" + CoreConstants.LINE_SEPARATOR;
+  String val = DUMMY;
+  String fileHeader;
+  String fileFooter;
+  String encodingName;
+
+  public String getEncodingName() {
+    return encodingName;
+  }
+
+  public void setEncodingName(String encodingName) {
+    this.encodingName = encodingName;
+  }
+
+  public DummyEncoder() {
+  }
+
+  public DummyEncoder(String val) {
+    this.val = val;
+  }
+
+  public void doEncode(E event, OutputStream os) throws IOException {
+    if (encodingName == null) {
+      os.write(val.getBytes());
+    } else {
+      os.write(val.getBytes(encodingName));
+    }
+  }
+
+  public void close(OutputStream os) throws IOException {
+    if(fileFooter == null) {
+      return;
+    }
+    if (encodingName == null) {
+      os.write(fileFooter.getBytes());
+    } else {
+      os.write(fileFooter.getBytes(encodingName));
+    }
+  }
+
+  public String getFileHeader() {
+    return fileHeader;
+  }
+
+  public void setFileHeader(String fileHeader) {
+    this.fileHeader = fileHeader;
+  }
+
+  public String getFileFooter() {
+    return fileFooter;
+  }
+
+  public void setFileFooter(String fileFooter) {
+    this.fileFooter = fileFooter;
+  }
+
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/EchoEncoder.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/EchoEncoder.java
new file mode 100644
index 0000000..90c4b0c
--- /dev/null
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/EchoEncoder.java
@@ -0,0 +1,42 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ *   or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package ch.qos.logback.core.encoder;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import ch.qos.logback.core.CoreConstants;
+
+public class EchoEncoder<E> extends EncoderBase<E> {
+
+  String fileHeader;
+  String fileFooter;
+
+  public EchoEncoder() {
+  }
+
+  public void doEncode(E event, OutputStream os) throws IOException {
+    String val = event + CoreConstants.LINE_SEPARATOR;
+    os.write(val.getBytes());
+  }
+
+  public void close(OutputStream os) throws IOException {
+    if (fileFooter == null) {
+      return;
+    }
+    os.write(fileFooter.getBytes());
+  }
+
+
+}
diff --git a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
similarity index 62%
copy from logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
copy to logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
index 8e1d504..8132f79 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/appender/DummyAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/NopEncoder.java
@@ -11,16 +11,17 @@
  * under the terms of the GNU Lesser General Public License version 2.1
  * as published by the Free Software Foundation.
  */
-package ch.qos.logback.core.appender;
+package ch.qos.logback.core.encoder;
 
-import java.io.Writer;
+import java.io.IOException;
+import java.io.OutputStream;
 
-import ch.qos.logback.core.WriterAppender;
-
-public class DummyAppender<E> extends WriterAppender<E> {
-
-  DummyAppender(Writer writer) {
-    this.setWriter(writer);
+public class NopEncoder<E> extends EncoderBase<E> {
+  
+  public void close(OutputStream os) throws IOException {
   }
 
+  public void doEncode(E event, OutputStream os) throws IOException {
+    
+  }
 }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
index aa4a968..3a1d898 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/MultiThreadedRollingTest.java
@@ -30,10 +30,10 @@ import org.junit.Test;
 
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.Encoder;
 import ch.qos.logback.core.contention.MultiThreadedHarness;
 import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.status.StatusChecker;
 import ch.qos.logback.core.testUtil.Env;
 import ch.qos.logback.core.testUtil.RandomUtil;
@@ -46,7 +46,7 @@ public class MultiThreadedRollingTest {
   final static int TOTAL_DURATION = 2000;
   RunnableWithCounterAndDone[] runnableArray;
 
-  Layout<Object> layout;
+  Encoder<Object> encoder;
   Context context = new ContextBase();
 
   static String VERIFY_SH = "verify.sh";
@@ -62,7 +62,7 @@ public class MultiThreadedRollingTest {
 
   @Before
   public void setUp() throws Exception {
-    layout = new EchoLayout<Object>();
+    encoder = new EchoEncoder<Object>();
     File outputDir = new File(outputDirStr);
     outputDir.mkdirs();
 
@@ -71,7 +71,7 @@ public class MultiThreadedRollingTest {
     scriptOS = openScript();
 
     rfa.setName("rolling");
-    rfa.setLayout(layout);
+    rfa.setEncoder(encoder);
     rfa.setContext(context);
     rfa.setFile(outputDirStr + "output.log");
 
@@ -256,8 +256,8 @@ public class MultiThreadedRollingTest {
 
     StatusChecker checker = new StatusChecker(context.getStatusManager());
     if (!checker.isErrorFree()) {
-      fail("errors reported");
       StatusPrinter.print(context);
+      fail("errors reported");
     }
   }
 
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenamingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenamingTest.java
index 34660d4..b08df19 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RenamingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RenamingTest.java
@@ -24,8 +24,8 @@ import org.junit.Test;
 
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.Layout;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.Encoder;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.util.Compare;
 import ch.qos.logback.core.util.CoreTestConstants;
 
@@ -39,12 +39,12 @@ import ch.qos.logback.core.util.CoreTestConstants;
  */
 public class RenamingTest {
 
-  Layout<Object> layout;
+  Encoder<Object> encoder;
   Context context = new ContextBase();
 
   @Before
   public void setUp() throws Exception {
-    layout = new EchoLayout<Object>();
+    encoder = new EchoEncoder<Object>();
 
     File target = new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "test.log");
     target.mkdirs();
@@ -55,7 +55,7 @@ public class RenamingTest {
   public void testRename() throws Exception {
 
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
-    rfa.setLayout(layout);
+    rfa.setEncoder(encoder);
     rfa.setContext(context);
 
     // rollover by the second
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
index 4b4cdf9..e4cbc01 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/RollingFileAppenderTest.java
@@ -26,7 +26,7 @@ import ch.qos.logback.core.Appender;
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
 import ch.qos.logback.core.appender.AbstractAppenderTest;
-import ch.qos.logback.core.layout.DummyLayout;
+import ch.qos.logback.core.encoder.DummyEncoder;
 import ch.qos.logback.core.status.Status;
 import ch.qos.logback.core.status.StatusChecker;
 import ch.qos.logback.core.status.StatusManager;
@@ -48,7 +48,7 @@ public class RollingFileAppenderTest extends AbstractAppenderTest<Object> {
     // noStartTest fails if the context is set in setUp
     // rfa.setContext(context);
 
-    rfa.setLayout(new DummyLayout<Object>());
+    rfa.setEncoder(new DummyEncoder<Object>());
     rfa.setName("test");
     tbrp.setContext(context);
     tbrp.setParent(rfa);
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
index 8b2fbca..633e1db 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/ScaffoldingForRollingTests.java
@@ -29,7 +29,7 @@ import java.util.concurrent.TimeoutException;
 
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.rolling.helper.FileFilterUtil;
 import ch.qos.logback.core.testUtil.FileToBufferUtil;
 import ch.qos.logback.core.testUtil.RandomUtil;
@@ -51,7 +51,7 @@ public class ScaffoldingForRollingTests {
   int diff = RandomUtil.getPositiveInt();
   protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff
       + "/";
-  EchoLayout<Object> layout = new EchoLayout<Object>();
+  EchoEncoder<Object> encoder = new EchoEncoder<Object>();
   Context context = new ContextBase();
   protected List<String> expectedFilenameList = new ArrayList<String>();
 
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
index cfc1841..5a0bffc 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFNATP_Test.java
@@ -43,7 +43,7 @@ public class SizeAndTimeBasedFNATP_Test extends
 
   void initRFA(RollingFileAppender<Object> rfa, String filename) {
     rfa.setContext(context);
-    rfa.setLayout(layout);
+    rfa.setEncoder(encoder);
     if (filename != null) {
       rfa.setFile(filename);
     }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
index 453123a..0653905 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
@@ -23,9 +23,8 @@ import org.junit.Test;
 
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.Layout;
-import ch.qos.logback.core.layout.DummyLayout;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.DummyEncoder;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.util.CoreTestConstants;
 
 /**
@@ -69,9 +68,8 @@ public class SizeBasedRollingTest extends ScaffoldingForRollingTests {
     // We purposefully use the \n as the line separator.
     // This makes the regression test system independent.
     Context context = new ContextBase();
-    Layout<Object> layout = new DummyLayout<Object>();
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
-    rfa.setLayout(layout);
+    rfa.setEncoder(new DummyEncoder<Object>());
     rfa.setContext(new ContextBase());
 
     FixedWindowRollingPolicy fwrp = new FixedWindowRollingPolicy();
@@ -99,10 +97,9 @@ public class SizeBasedRollingTest extends ScaffoldingForRollingTests {
   public void smoke() throws Exception {
     Context context = new ContextBase();
 
-    EchoLayout<Object> layout = new EchoLayout<Object>();
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
     rfa.setName("ROLLING");
-    rfa.setLayout(layout);
+    rfa.setEncoder(new EchoEncoder<Object>());
     rfa.setContext(context);
     // make the .log show first
     rfa.setFile(randomOutputDir + "a-sizeBased-smoke.log");
@@ -143,9 +140,8 @@ public class SizeBasedRollingTest extends ScaffoldingForRollingTests {
   @Test
   public void test3() throws Exception {
     Context context = new ContextBase();
-    EchoLayout<Object> layout = new EchoLayout<Object>();
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
-    rfa.setLayout(layout);
+    rfa.setEncoder(new EchoEncoder<Object>());
     rfa.setContext(context);
     rfa.setFile(randomOutputDir + "a-sbr-test3.log");
 
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
index 4c5b87b..f76cac4 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingTest.java
@@ -65,7 +65,7 @@ public class TimeBasedRollingTest extends ScaffoldingForRollingTests {
 
   void initRFA(RollingFileAppender<Object> rfa, String filename) {
     rfa.setContext(context);
-    rfa.setLayout(layout);
+    rfa.setEncoder(encoder);
     if (filename != null) {
       rfa.setFile(filename);
     }
diff --git a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java
index f433523..f034a3d 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithArchiveRemovalTest.java
@@ -35,14 +35,14 @@ import org.junit.Test;
 
 import ch.qos.logback.core.Context;
 import ch.qos.logback.core.ContextBase;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.testUtil.RandomUtil;
 import ch.qos.logback.core.util.CoreTestConstants;
 
 public class TimeBasedRollingWithArchiveRemovalTest {
 
   Context context = new ContextBase();
-  EchoLayout<Object> layout = new EchoLayout<Object>();
+  EchoEncoder<Object> encoder = new EchoEncoder<Object>();
 
   static final String MONTHLY_DATE_PATTERN = "yyyy-MM";
   static final String MONTHLY_CROLOLOG_DATE_PATTERN = "yyyy/MM";
@@ -174,7 +174,7 @@ public class TimeBasedRollingWithArchiveRemovalTest {
 
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
     rfa.setContext(context);
-    rfa.setLayout(layout);
+    rfa.setEncoder(encoder);
     // rfa.setFile(Constants.OUTPUT_DIR_PREFIX + "clean.txt");
     TimeBasedRollingPolicy<Object> tbrp = new TimeBasedRollingPolicy<Object>();
     tbrp.setContext(context);
diff --git a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
index dd822ed..300fedd 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/spi/AppenderAttachableImplTest.java
@@ -14,10 +14,10 @@
 package ch.qos.logback.core.spi;
 
 
-import static org.junit.Assert.*;
-import ch.qos.logback.core.appender.NOPAppender;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.layout.NopLayout;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Iterator;
 
@@ -25,6 +25,9 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.appender.NOPAppender;
+
 /**
  * This test case verifies all the methods of AppenderAttableImpl work properly.
  *
@@ -49,12 +52,10 @@ public class AppenderAttachableImplTest {
   public void testAddAppender() throws Exception {
     TestEvent event = new TestEvent();
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     ta = new NOPAppender<TestEvent>();
     ta.setName("test");
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     int size = aai.appendLoopOnAppenders(event);
@@ -64,12 +65,10 @@ public class AppenderAttachableImplTest {
   @Test
   public void testIteratorForAppenders() throws Exception {
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
     tab.setName("test");
-    tab.setLayout(new NopLayout<TestEvent>());
     tab.start();
     aai.addAppender(tab);
     Iterator<Appender<TestEvent>> iter = aai.iteratorForAppenders();
@@ -85,14 +84,12 @@ public class AppenderAttachableImplTest {
   @Test
   public void getGetAppender() throws Exception {
     NOPAppender<TestEvent> test = new NOPAppender<TestEvent>();
-    test.setLayout(new NopLayout<TestEvent>());
     test.setName("test");
     test.start();
     aai.addAppender(test);
     
     NOPAppender<TestEvent> testOther = new NOPAppender<TestEvent>();
     testOther.setName("testOther");
-    testOther.setLayout(new NopLayout<TestEvent>());
     testOther.start();
     aai.addAppender(testOther);
     
@@ -110,12 +107,10 @@ public class AppenderAttachableImplTest {
   @Test
   public void testIsAttached() throws Exception {
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
     tab.setName("test");
-    tab.setLayout(new NopLayout<TestEvent>());
     tab.start();
     aai.addAppender(tab);
     assertTrue("Appender is not attached", aai.isAttached(ta));
@@ -125,12 +120,10 @@ public class AppenderAttachableImplTest {
   @Test
   public void testDetachAndStopAllAppenders() throws Exception {
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
     tab.setName("test");
-    tab.setLayout(new NopLayout<TestEvent>());
     tab.start();
     aai.addAppender(tab);
     assertTrue("Appender was not started", tab.isStarted());
@@ -142,12 +135,10 @@ public class AppenderAttachableImplTest {
   @Test
   public void testDetachAppender() throws Exception {
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
     tab.setName("test");
-    tab.setLayout(new NopLayout<TestEvent>());
     tab.start();
     aai.addAppender(tab);
     assertTrue("Appender not detached", aai.detachAppender(tab));
@@ -159,12 +150,10 @@ public class AppenderAttachableImplTest {
   public void testDetachAppenderByName() throws Exception {
     NOPAppender<TestEvent> ta = new NOPAppender<TestEvent>();
     ta.setName("test1");
-    ta.setLayout(new NopLayout<TestEvent>());
     ta.start();
     aai.addAppender(ta);
     NOPAppender<TestEvent> tab = new NOPAppender<TestEvent>();
     tab.setName("test");
-    tab.setLayout(new NopLayout<TestEvent>());
     tab.start();
     aai.addAppender(tab);
    
diff --git a/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java b/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
index bd51887..5d8420c 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/testUtil/StringListAppender.java
@@ -47,12 +47,10 @@ public class StringListAppender<E> extends AppenderBase<E> {
     strList.add(res);
   }
 
-  @Override
   public Layout<E> getLayout() {
     return layout;
   }
 
-  @Override
   public void setLayout(Layout<E> layout) {
     this.layout = layout;
   }
diff --git a/logback-examples/src/main/java/chapter11/TrivialLogbackAppender.java b/logback-examples/src/main/java/chapter11/TrivialLogbackAppender.java
index 38616b4..9ddfab6 100644
--- a/logback-examples/src/main/java/chapter11/TrivialLogbackAppender.java
+++ b/logback-examples/src/main/java/chapter11/TrivialLogbackAppender.java
@@ -13,15 +13,28 @@
  */
 package chapter11;
 
+import java.io.IOException;
+
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.AppenderBase;
 
 public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {
 
+  PatternEncoder encoder;
+  
+  public PatternEncoder getEncoder() {
+    return encoder;
+  }
+
+  public void setEncoder(PatternEncoder encoder) {
+    this.encoder = encoder;
+  }
+
   @Override
   public void start() {
-    if (this.layout == null) {
-      addError("No layout set for the appender named [" + name + "].");
+    if (this.encoder == null) {
+      addError("No encoder set for the appender named [" + name + "].");
       return;
     }
     super.start();
@@ -31,9 +44,13 @@ public class TrivialLogbackAppender extends AppenderBase<ILoggingEvent> {
   protected void append(ILoggingEvent loggingevent) {
     // note that AppenderBase.doAppend will invoke this method only if
     // this appender was successfully started.
-    
-    String s = this.layout.doLayout(loggingevent);
-    System.out.println(s);
+    try {
+      this.encoder.doEncode(loggingevent, System.out);
+    } catch (IOException e) {
+      // we can't do much with the exception except halting
+      super.stop();
+      addError("Failed to write to the console");
+    }
   }
 
 }
diff --git a/logback-examples/src/main/java/chapter4/CountingConsoleAppender.java b/logback-examples/src/main/java/chapter4/CountingConsoleAppender.java
index fd29e5d..1df11e9 100644
--- a/logback-examples/src/main/java/chapter4/CountingConsoleAppender.java
+++ b/logback-examples/src/main/java/chapter4/CountingConsoleAppender.java
@@ -13,6 +13,9 @@
  */
 package chapter4;
 
+import java.io.IOException;
+
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.AppenderBase;
 
@@ -22,6 +25,8 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
   int counter = 0;
   int limit = DEFAULT_LIMIT;
   
+  PatternEncoder encoder;
+  
   public CountingConsoleAppender() {
   }
 
@@ -35,7 +40,7 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
   
   @Override
   public void start() {
-    if (this.layout == null) {
+    if (this.encoder == null) {
       addError("No layout set for the appender named ["+ name +"].");
       return;
     }
@@ -48,9 +53,22 @@ public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
       return;
     }
     // output the events as formatted by our layout
-    System.out.print(this.layout.doLayout(event));
+    try {
+      this.encoder.doEncode(event, System.out);
+    } catch (IOException e) {
+    }
 
     // prepare for next event
     counter++;
   }
+
+  public PatternEncoder getEncoder() {
+    return encoder;
+  }
+
+  public void setEncoder(PatternEncoder encoder) {
+    this.encoder = encoder;
+  }
+  
+  
 }
diff --git a/logback-examples/src/main/java/chapter4/ExitWoes1.java b/logback-examples/src/main/java/chapter4/ExitWoes1.java
index ebaf133..a265137 100644
--- a/logback-examples/src/main/java/chapter4/ExitWoes1.java
+++ b/logback-examples/src/main/java/chapter4/ExitWoes1.java
@@ -15,7 +15,6 @@ package chapter4;
 
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 
 import org.slf4j.LoggerFactory;
 
@@ -23,7 +22,7 @@ import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.WriterAppender;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 
 public class ExitWoes1 {
 
@@ -32,10 +31,10 @@ public class ExitWoes1 {
     lc.reset(); // we want to override the default-config.
     WriterAppender<ILoggingEvent> writerAppender = new WriterAppender<ILoggingEvent>();
     writerAppender.setContext(lc);
-    writerAppender.setLayout(new EchoLayout<ILoggingEvent>());
+    writerAppender.setEncoder(new EchoEncoder<ILoggingEvent>());
 
     OutputStream os = new FileOutputStream("exitWoes1.log");
-    writerAppender.setWriter(new OutputStreamWriter(os));
+    writerAppender.setWriter(os);
     writerAppender.setImmediateFlush(false);
     writerAppender.start();
     Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
diff --git a/logback-examples/src/main/java/chapter4/ExitWoes2.java b/logback-examples/src/main/java/chapter4/ExitWoes2.java
index a03d0ab..ab2b89c 100644
--- a/logback-examples/src/main/java/chapter4/ExitWoes2.java
+++ b/logback-examples/src/main/java/chapter4/ExitWoes2.java
@@ -15,7 +15,6 @@ package chapter4;
 
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 
 import org.slf4j.LoggerFactory;
 
@@ -23,7 +22,7 @@ import ch.qos.logback.classic.Logger;
 import ch.qos.logback.classic.LoggerContext;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.WriterAppender;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 import ch.qos.logback.core.util.StatusPrinter;
 
 public class ExitWoes2 {
@@ -33,10 +32,10 @@ public class ExitWoes2 {
     lc.reset();//this is to cancel default-config.
     WriterAppender<ILoggingEvent> writerAppender = new WriterAppender<ILoggingEvent>();
     writerAppender.setContext(lc);
-    writerAppender.setLayout(new EchoLayout<ILoggingEvent>());
+    writerAppender.setEncoder(new EchoEncoder<ILoggingEvent>());
 
     OutputStream os = new FileOutputStream("exitWoes2.log");
-    writerAppender.setWriter(new OutputStreamWriter(os));
+    writerAppender.setWriter(os);
     writerAppender.setImmediateFlush(false);
     writerAppender.start();
     Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
diff --git a/logback-examples/src/main/java/chapter4/IO.java b/logback-examples/src/main/java/chapter4/IO.java
index 9010f7e..015bbff 100644
--- a/logback-examples/src/main/java/chapter4/IO.java
+++ b/logback-examples/src/main/java/chapter4/IO.java
@@ -16,10 +16,10 @@ package chapter4;
 import org.slf4j.Logger;
 
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.FileAppender;
-import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.encoder.EchoEncoder;
 
 public class IO extends Thread {
   static String msgLong = "ABCDEGHIJKLMNOPQRSTUVWXYZabcdeghijklmnopqrstuvwxyz1234567890";
@@ -47,11 +47,13 @@ public class IO extends Thread {
     FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
 
     if (longMessage) {
-      PatternLayout pa = new PatternLayout();
+      PatternEncoder pa = new PatternEncoder();
       pa.setPattern("%r %5p %c [%t] - %m%n");
-      fa.setLayout(pa);
+      pa.setContext(context);
+      pa.start();
+      fa.setEncoder(pa);
     } else {
-      fa.setLayout(new EchoLayout<ILoggingEvent>());
+      fa.setEncoder(new EchoEncoder<ILoggingEvent>());
     }
 
     fa.setFile(getName() + ".log");
diff --git a/logback-examples/src/main/java/chapter5/PatternSample.java b/logback-examples/src/main/java/chapter5/PatternSample.java
index 6ae46b6..6c7ec82 100644
--- a/logback-examples/src/main/java/chapter5/PatternSample.java
+++ b/logback-examples/src/main/java/chapter5/PatternSample.java
@@ -16,7 +16,7 @@ package chapter5;
 import org.slf4j.LoggerFactory;
 
 import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.ConsoleAppender;
 
@@ -25,13 +25,13 @@ public class PatternSample {
   static public void main(String[] args) throws Exception {
     Logger rootLogger = (Logger) LoggerFactory.getLogger("root");
     
-    PatternLayout layout = new PatternLayout();
+    PatternEncoder layout = new PatternEncoder();
     layout.setPattern("%-5level [%thread]: %message%n");
     layout.start();
     
     ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
     appender.setContext(rootLogger.getLoggerContext());
-    appender.setLayout(layout);
+    appender.setEncoder(layout);
     appender.start();
     
     rootLogger.addAppender(appender);
diff --git a/logback-examples/src/main/java/chapter7/SimpleMDC.java b/logback-examples/src/main/java/chapter7/SimpleMDC.java
index 59a5684..304b7c3 100644
--- a/logback-examples/src/main/java/chapter7/SimpleMDC.java
+++ b/logback-examples/src/main/java/chapter7/SimpleMDC.java
@@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
 
 import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.encoder.PatternEncoder;
 import ch.qos.logback.classic.joran.JoranConfigurator;
 import ch.qos.logback.classic.spi.ILoggingEvent;
 import ch.qos.logback.core.ConsoleAppender;
@@ -63,13 +63,13 @@ public class SimpleMDC {
     LoggerContext loggerContext = (LoggerContext) LoggerFactory
         .getILoggerFactory();
     loggerContext.reset();
-    PatternLayout layout = new PatternLayout();
+    PatternEncoder layout = new PatternEncoder();
     layout.setContext(loggerContext);
     layout.setPattern("%X{first} %X{last} - %m%n");
     layout.start();
     ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<ILoggingEvent>();
     appender.setContext(loggerContext);
-    appender.setLayout(layout);
+    appender.setEncoder(layout);
     appender.start();
     // cast root logger to c.q.logback.classic.Logger so that we can attach
     // an appender to it

-----------------------------------------------------------------------


hooks/post-receive
-- 
Logback: the generic, reliable, fast and flexible logging framework.


More information about the logback-dev mailing list