[ 
http://jira.qos.ch/browse/LBCORE-143?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ceki Gulcu resolved LBCORE-143.
-------------------------------

    Fix Version/s: 0.9.19
       Resolution: Fixed

Fixed in http://github.com/ceki/logback/commit/3faa7d8bc51

I also added your name as an author to ConsoleAppender and 
ConsoleOutputStreamWrapper. 



> ConsoleAppender should always write to current System.out / System.err. The 
> underlying outputstream should not be bind statically.
> ----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: LBCORE-143
>                 URL: http://jira.qos.ch/browse/LBCORE-143
>             Project: logback-core
>          Issue Type: Bug
>          Components: Appender
>    Affects Versions: 0.9.18
>            Reporter: tomliliu
>            Assignee: Logback dev list
>             Fix For: 0.9.19
>
>         Attachments: ConsoleAppender.java
>
>
> Hi logback-dev,
> ConsoleAppender does not work nicely with JUnit.
> Symptom: when running junit tests with logback (default configuration, no 
> logback configuration is provided), only the first test case's output was 
> captured, the subsequent test cases' output were not captured by junit.
> The problem is that console appender binds itself to stdout / stderr 
> statically.
> Illustrate what happens:
> Junit run test 1 -> System.out is set to test1.out -> Logback auto configure 
> -> Console appender is bind to System.out, which is test1.out
> Junit run test 2 -> System.out is set to test2.out -> Console appender is 
> still bind to test1.out -> The output of subsequent test cases are not 
> correctly redirected.
> The ConsoleAppender's behavior is not correct as it should always write to 
> current System.out / System.err.
> I worked out a simple fix and hope it will be useful:
> /**
>  * Logback: the generic, reliable, fast and flexible logging framework.
>  * 
>  * Copyright (C) 2000-2009, QOS.ch
>  * 
>  * This library is free software, you can redistribute it and/or modify it 
> under
>  * the terms of the GNU Lesser General Public License as published by the Free
>  * Software Foundation.
>  */
> package ch.qos.logback.core;
> import java.io.IOException;
> import java.io.OutputStream;
> import ch.qos.logback.core.status.Status;
> import ch.qos.logback.core.status.WarnStatus;
> /**
>  * ConsoleAppender appends log events to <code>System.out</code> or 
> <code>System.err</code> using a layout specified by
>  * the user. The default target is <code>System.out</code>.
>  * 
>  * For more information about this appender, please refer to the online 
> manual at
>  * http://logback.qos.ch/manual/appenders.html#ConsoleAppender
>  * 
>  * @author Ceki G&uuml;lc&uuml;
>  */
> public class ConsoleAppender<E> extends WriterAppender<E> {
>     public static final String SYSTEM_OUT = "System.out";
>     public static final String SYSTEM_ERR = "System.err";
>     
>     protected String target = SYSTEM_OUT;
>     private interface OutputStreamProvider {
>         OutputStream getOutputStream();
>     }
>     
>     private static class SysoutProvider implements OutputStreamProvider {
>         @Override
>         public OutputStream getOutputStream() {
>             return System.out;
>         }
>     }
>     
>     private static class SyserrProvider implements OutputStreamProvider {
>         @Override
>         public OutputStream getOutputStream() {
>             return System.err;
>         }
>     }
>     
>     private static class WrapperOutputStream extends OutputStream {
>         
>         private final OutputStreamProvider provider;
>         WrapperOutputStream(OutputStreamProvider provider) {
>             this.provider = provider;
>         }
>         
>         @Override
>         public void write(int b) throws IOException {
>             provider.getOutputStream().write(b);
>         }
>         @Override
>         public void write(byte[] b, int off, int len) throws IOException {
>             provider.getOutputStream().write(b, off, len);
>         }
>         @Override
>         public void write(byte[] b) throws IOException {
>             provider.getOutputStream().write(b);
>         }
>         @Override
>         public void close() throws IOException {
>             provider.getOutputStream().close();
>         }
>         @Override
>         public void flush() throws IOException {
>             provider.getOutputStream().flush();
>         }
>     }
>     /**
>      * As in most logback components, the default constructor does nothing.
>      */
>     public ConsoleAppender() {
>     }
>     /**
>      * Sets the value of the <b>Target</b> option. Recognized values are 
> "System.out" and "System.err". Any other value
>      * will be ignored.
>      */
>     public void setTarget(String value) {
>         String v = value.trim();
>         if (SYSTEM_OUT.equalsIgnoreCase(v)) {
>             target = SYSTEM_OUT;
>         } else if (SYSTEM_ERR.equalsIgnoreCase(v)) {
>             target = SYSTEM_ERR;
>         } else {
>             targetWarn(value);
>         }
>     }
>     /**
>      * Returns the current value of the <b>Target</b> property. The default 
> value of the option is "System.out".
>      * 
>      * See also {...@link #setTarget}.
>      */
>     public String getTarget() {
>         return target;
>     }
>     void targetWarn(String val) {
>         Status status = new WarnStatus("[" + val + " should be System.out or 
> System.err.", this);
>         status.add(new WarnStatus("Using previously set target, System.out by 
> default.", this));
>         addStatus(status);
>     }
>     public void start() {
>         if (target.equals(SYSTEM_OUT)) {
>             setWriter(createWriter(new WrapperOutputStream(new 
> SysoutProvider())));
>         } else {
>             setWriter(createWriter(new WrapperOutputStream(new 
> SyserrProvider())));
>         }
>         super.start();
>     }
>     /**
>      * This method overrides the parent {...@link WriterAppender#closeWriter} 
> implementation because the console stream is
>      * not ours to close.
>      */
>     protected final void closeWriter() {
>         writeFooter();
>     }
> }
>  

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        
_______________________________________________
logback-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/logback-dev

Reply via email to