View Javadoc

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