/ org.apache.log4j / source-bundle / org / apache / log4j / ConsoleAppender.java
ConsoleAppender.java
  1  /*
  2   * Copyright 1999-2005 The Apache Software Foundation.
  3   * 
  4   * Licensed under the Apache License, Version 2.0 (the "License");
  5   * you may not use this file except in compliance with the License.
  6   * You may obtain a copy of the License at
  7   * 
  8   *      http://www.apache.org/licenses/LICENSE-2.0
  9   * 
 10   * Unless required by applicable law or agreed to in writing, software
 11   * distributed under the License is distributed on an "AS IS" BASIS,
 12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13   * See the License for the specific language governing permissions and
 14   * limitations under the License.
 15   */
 16  
 17  package org.apache.log4j;
 18  
 19  import java.io.IOException;
 20  import java.io.OutputStream;
 21  import org.apache.log4j.helpers.LogLog;
 22  
 23  /**
 24    * ConsoleAppender appends log events to <code>System.out</code> or
 25    * <code>System.err</code> using a layout specified by the user. The
 26    * default target is <code>System.out</code>.
 27    *
 28    * @author Ceki G&uuml;lc&uuml; 
 29    * @author Curt Arnold
 30    * @since 1.1 */
 31  public class ConsoleAppender extends WriterAppender {
 32  
 33    public static final String SYSTEM_OUT = "System.out";
 34    public static final String SYSTEM_ERR = "System.err";
 35  
 36    protected String target = SYSTEM_OUT;
 37  
 38    /**
 39     *  Determines if the appender honors reassignments of System.out
 40     *  or System.err made after configuration.
 41     */
 42    private boolean follow = false;
 43  
 44    /**
 45      * Constructs an unconfigured appender.
 46      */
 47    public ConsoleAppender() {
 48    }
 49  
 50      /**
 51       * Creates a configured appender.
 52       *
 53       * @param layout layout, may not be null.
 54       */
 55    public ConsoleAppender(Layout layout) {
 56      this(layout, SYSTEM_OUT);
 57    }
 58  
 59      /**
 60       *   Creates a configured appender.
 61       * @param layout layout, may not be null.
 62       * @param target target, either "System.err" or "System.out".
 63       */
 64    public ConsoleAppender(Layout layout, String target) {
 65      setLayout(layout);
 66      setTarget(target);
 67      activateOptions();
 68    }
 69  
 70    /**
 71     *  Sets the value of the <b>Target</b> option. Recognized values
 72     *  are "System.out" and "System.err". Any other value will be
 73     *  ignored.  
 74     * */
 75    public
 76    void setTarget(String value) {
 77      String v = value.trim();
 78  
 79      if (SYSTEM_OUT.equalsIgnoreCase(v)) {
 80        target = SYSTEM_OUT;
 81      } else if (SYSTEM_ERR.equalsIgnoreCase(v)) {
 82        target = SYSTEM_ERR;
 83      } else {
 84        targetWarn(value);
 85      }
 86    }
 87  
 88    /**
 89     * Returns the current value of the <b>Target</b> property. The
 90     * default value of the option is "System.out".
 91     *
 92     * See also {@link #setTarget}.
 93     * */
 94    public
 95    String getTarget() {
 96      return target;
 97    }
 98    
 99    /**
100     *  Sets whether the appender honors reassignments of System.out
101     *  or System.err made after configuration.
102     *  @param newValue if true, appender will use value of System.out or
103     *  System.err in force at the time when logging events are appended.
104     *  @since 1.2.13
105     */
106    public final void setFollow(final boolean newValue) {
107       follow = newValue;
108    }
109    
110    /**
111     *  Gets whether the appender honors reassignments of System.out
112     *  or System.err made after configuration.
113     *  @return true if appender will use value of System.out or
114     *  System.err in force at the time when logging events are appended.
115     *  @since 1.2.13
116     */
117    public final boolean getFollow() {
118        return follow;
119    }
120  
121    void targetWarn(String val) {
122      LogLog.warn("["+val+"] should be System.out or System.err.");
123      LogLog.warn("Using previously set target, System.out by default.");
124    }
125  
126    /**
127      *   Prepares the appender for use.
128      */
129     public void activateOptions() {
130          if (follow) {
131              if (target.equals(SYSTEM_ERR)) {
132                 setWriter(createWriter(new SystemErrStream()));
133              } else {
134                 setWriter(createWriter(new SystemOutStream()));
135              }
136          } else {
137              if (target.equals(SYSTEM_ERR)) {
138                 setWriter(createWriter(System.err));
139              } else {
140                 setWriter(createWriter(System.out));
141              }
142          }
143  
144          super.activateOptions();
145    }
146    
147    /**
148     *  {@inheritDoc}
149     */
150    protected
151    final
152    void closeWriter() {
153       if (follow) {
154          super.closeWriter();
155       }
156    }
157    
158  
159      /**
160       * An implementation of OutputStream that redirects to the
161       * current System.err.
162       *
163       */
164      private static class SystemErrStream extends OutputStream {
165          public SystemErrStream() {
166          }
167  
168          public void close() {
169          }
170  
171          public void flush() {
172              System.err.flush();
173          }
174  
175          public void write(final byte[] b) throws IOException {
176              System.err.write(b);
177          }
178  
179          public void write(final byte[] b, final int off, final int len)
180              throws IOException {
181              System.err.write(b, off, len);
182          }
183  
184          public void write(final int b) throws IOException {
185              System.err.write(b);
186          }
187      }
188  
189      /**
190       * An implementation of OutputStream that redirects to the
191       * current System.out.
192       *
193       */
194      private static class SystemOutStream extends OutputStream {
195          public SystemOutStream() {
196          }
197  
198          public void close() {
199          }
200  
201          public void flush() {
202              System.out.flush();
203          }
204  
205          public void write(final byte[] b) throws IOException {
206              System.out.write(b);
207          }
208  
209          public void write(final byte[] b, final int off, final int len)
210              throws IOException {
211              System.out.write(b, off, len);
212          }
213  
214          public void write(final int b) throws IOException {
215              System.out.write(b);
216          }
217      }
218  
219  }