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ülcü 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 }