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 }