You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-cvs@jakarta.apache.org by ce...@apache.org on 2001/02/13 18:37:54 UTC

cvs commit: jakarta-log4j/org/apache/log4j/varia Makefile

ceki        01/02/13 09:37:53

  Modified:    docs     HISTORY
               org/apache/log4j AppenderSkeleton.java
                        BasicConfigurator.java FileAppender.java Makefile
                        PropertyConfigurator.java RollingFileAppender.java
               org/apache/log4j/examples MyCategory.java
                        MyPatternLayout.java
               org/apache/log4j/net SMTPAppender.java
               org/apache/log4j/net/test Loop.java
               org/apache/log4j/performance NotLogging.java
               org/apache/log4j/test CategoryWrapper.java
                        ConfigurationFileParsing.java Makefile Min.java
                        PatternTest.java ShippedCodeFlagTest.java
                        SysoutConfigurator.java confParsing getOptions
                        pattern shippedCodeFlag
               org/apache/log4j/test/witness getOptions.1
               org/apache/log4j/varia Makefile
  Added:       org/apache/log4j ConsoleAppender.java WriterAppender.java
  Log:
   - The FileAppender has been split into three parts: WriterAppender,
     ConsoleAppender and FileAppender. ConsoleAppender takes over the
     console logging functionality of FileAppender. [**]
  
  Revision  Changes    Path
  1.19      +7 -0      jakarta-log4j/docs/HISTORY
  
  Index: HISTORY
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/docs/HISTORY,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- HISTORY	2001/02/12 17:00:12	1.18
  +++ HISTORY	2001/02/13 17:37:00	1.19
  @@ -31,10 +31,17 @@
   
      perl -p -i.bak -e "s/configuration/log4j:configuration/;" file1.xml .. fileN.xml
   
  + - The FileAppender has been split into three parts: WriterAppender,
  +   ConsoleAppender and FileAppender. ConsoleAppender takes over the
  +   console logging functionality of FileAppender. [**]
  +
    - Appenders and Layouts now get to see the raw message object in LoggingEvent 
      not just its rendered form. The access modifiers of some LoggingEvent fields 
      were changed so that they can be accessed in less error-prone ways. Thanks to 
      Jim Cakalic and Anders Kristens for their valuable advice. [*]
  +
  + - Removed org/apache/log4j/varia/ResilientFileAppender.java which was
  +   bogus to begin with. [*]
   
    - XMLLayout will now mark some output as <![CDATA .. [[> so that it
      does not get interpreted by the XML parser. This was suggested by
  
  
  
  1.7       +2 -2      jakarta-log4j/org/apache/log4j/AppenderSkeleton.java
  
  Index: AppenderSkeleton.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/AppenderSkeleton.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AppenderSkeleton.java	2001/02/02 21:46:13	1.6
  +++ AppenderSkeleton.java	2001/02/13 17:37:04	1.7
  @@ -236,12 +236,12 @@
         @since 0.9.0
     */
     public
  +  synchronized
     void setErrorHandler(ErrorHandler eh) {
       if(eh == null) {
         // We do not throw exception here since the cause is probably a
         // bad config file.
  -      LogLog.error(
  -              "It is forbidden to set a null ErrorHandler. Ignoring directive.");
  +      LogLog.warn("You have tried to set a null error-handler.");
       } else {
         this.errorHandler = eh;
       }
  
  
  
  1.9       +2 -2      jakarta-log4j/org/apache/log4j/BasicConfigurator.java
  
  Index: BasicConfigurator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/BasicConfigurator.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BasicConfigurator.java	2001/01/22 22:11:24	1.8
  +++ BasicConfigurator.java	2001/02/13 17:37:05	1.9
  @@ -125,8 +125,8 @@
     public
     void configure() {
       Category root = Category.getRoot();
  -    root.addAppender(new FileAppender(
  -	new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN), System.out));
  +    root.addAppender(new ConsoleAppender(
  +           new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));
     }
   
     /**
  
  
  
  1.8       +29 -239   jakarta-log4j/org/apache/log4j/FileAppender.java
  
  Index: FileAppender.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/FileAppender.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- FileAppender.java	2001/01/26 13:27:45	1.7
  +++ FileAppender.java	2001/02/13 17:37:05	1.8
  @@ -30,7 +30,7 @@
   
      @author Ceki G&uuml;lc&uuml;
      */
  -public class FileAppender extends AppenderSkeleton {
  +public class FileAppender extends WriterAppender {
   
     /**
        A string constant used in naming the option for setting the
  @@ -42,19 +42,7 @@
     */
     public static final String FILE_OPTION = "File";
   
  -  /**
  -     A string constant used in naming the option for immediate
  -     flushing of the output stream at the end of each append
  -     operation. Current value of this string constant is
  -     <b>ImmediateFlush</b>.
   
  -     <p>Note that all option keys are case sensitive.
  -     
  -     @since 0.9.1
  -  */
  -  public static final String IMMEDIATE_FLUSH_OPTION = "ImmediateFlush";
  -
  -
     /**
        A string constant used in naming the option that determines whether 
        the output file will be truncated or appended to. Current value
  @@ -76,73 +64,19 @@
     */
     protected boolean fileAppend = true;
   
  -
     /**
  -     Immediate flush means that the undelying writer or stream will be
  -     flushed at the end of each append operation. Immediate flush is
  -     slower but ensures that each append request is actually
  -     written. If <code>immediateFlush</code> is set to
  -     <code>false</code>, then there is a good chance that the last few
  -     logs events are not actually written to persistent media when the
  -     application crashes.
  -
  -     <p>The <code>immediateFlush</code> variable is set to
  -     <code>true</code> by default.
  -
  -     @since 0.9.1 */
  -  protected boolean immediateFlush = true;
  -
  -  /**
  -     This is the {@link QuietWriter quietWriter} where we will write
  -     to. 
  -  */
  -  protected QuietWriter qw;
  -
  -  /**
  -     {@link TracerPrintWriter} is specialized in optimized printing
  -     of stack traces (obtained from throwables) to a Writer. 
  -  */
  -  protected TracerPrintWriter tp;
  -  
  -  /**
        The name of the log file. */
     protected String fileName = null;
   
   
     /**
  -     Is the QuietWriter ours or was it created and passed by the user?
  +     The default constructor does not do anything. 
     */
  -  protected boolean qwIsOurs = false;
  -  
  -  /**
  -     The default constructor does no longer set a default layout nor a
  -     default output target.  */
     public
     FileAppender() {
     }
   
     /**
  -     Instantiate a FileAppender and set the output destination to a
  -     new {@link OutputStreamWriter} initialized with <code>os</code>
  -     as its {@link OutputStream}.  */
  -  public
  -  FileAppender(Layout layout, OutputStream os) {
  -    this(layout, new OutputStreamWriter(os));
  -  }
  -  
  -  /**
  -     Instantiate a FileAppender and set the output destination to
  -     <code>writer</code>.
  -
  -     <p>The <code>writer</code> must have been opened by the user.  */
  -  public
  -  FileAppender(Layout layout, Writer writer) {
  -    this.layout = layout;
  -    this.setWriter(writer);
  -  }                    
  -
  -
  -  /**
       Instantiate a FileAppender and open the file designated by
       <code>filename</code>. The opened filename will become the ouput
       destination for this appender.
  @@ -187,116 +121,36 @@
         }
       }
     }
  -
  -
  -  /**
  -     This method called by {@link AppenderSkeleton#doAppend}
  -     method. 
  -
  -     <p>If the output stream exists an is writable then write a log
  -     statement to the output stream. Otherwise, write a single warning
  -     message to <code>System.err</code>.
  -
  -     <p>The format of the output will depend on this appender's
  -     layout.
  -     
  -  */
  -  public
  -  void append(LoggingEvent event) {
  -
  -    // Reminder: the nesting of calls is:
  -    //
  -    //    doAppend()
  -    //      - check threshold
  -    //      - filter
  -    //      - append();
  -    //        - checkEntryConditions();
  -    //        - subAppend();
  -
  -    if(!checkEntryConditions()) {
  -      return;
  -    }
  -    subAppend(event);
  -   } 
  -
  -  /**
  -     This method determines if there is a sense in attempting to append.
  -     
  -     <p>It checks whether there is a set output target and also if
  -     there is a set layout. If these checks fail, then the boolean
  -     value <code>false</code> is returned. */
  -  protected
  -  boolean checkEntryConditions() {
  -    if(this.qw == null) {
  -      errorHandler.error("No output target set for appender named \""+ 
  -			name+"\".");
  -      return false;
  -    }
  -    
  -    if(this.layout == null) {
  -      errorHandler.error("No layout set for appender named \""+ name+"\".");
  -      return false;
  -    }
  -    return true;
  -  }
  -
  -
  -  /**
  -     Will close the stream opened by a previos {@link #setFile}
  -     call. If the writer is owned by the user it remains untouched.
  -
  -     @see #setFile
  -     @see #setWriter
  -     @since 0.8.4
  -  */
  -  public
  -  void close() {
  -    this.closed = true;
  -    reset();
  -  }
  -
   
  -  
  -  /**
  -     Close this.writer if opened by setFile or FileAppend(filename..)
  + /**
  +     Close the file opened previously.
     */
     protected
  -  void closeWriterIfOurs() {
  -    if(this.qwIsOurs && this.qw != null) {
  +  void closeFile() {
  +    if(this.qw != null) {
  +      LogLog.warn("--------------");
  +      writeFooter();
         try {
   	this.qw.close();
         }
         catch(java.io.IOException e) {
  -	LogLog.error("Could not close output stream " + qw, e);
  +	LogLog.error("Could not close " + qw, e);
         }
  -    }      
  +    }
     }
  -
  + 
     /**
        Retuns the option names for this component, namely the string
        array {{@link #FILE_OPTION}, {@link #APPEND_OPTION}} in addition
  -     to the options of its super class {@link AppenderSkeleton}.  */
  +     to the options of its super class {@link WriterAppender}.  */
     public
     String[] getOptionStrings() {
       return OptionConverter.concatanateArrays(super.getOptionStrings(),
  -          new String[] {FILE_OPTION, APPEND_OPTION, IMMEDIATE_FLUSH_OPTION});
  +          new String[] {FILE_OPTION, APPEND_OPTION});
     }
   
   
     /**
  -     Set the {@link ErrorHandler} for this FileAppender and also the
  -     undelying {@link QuietWriter} if any. */
  -  public
  -  synchronized 
  -  void setErrorHandler(ErrorHandler eh) {
  -    this.errorHandler = eh;
  -    if(this.qwIsOurs && this.qw != null) {
  -      this.qw.setErrorHandler(eh);
  -    }    
  -  }
  -
  -  
  -  /**
       <p>Sets and <i>opens</i> the file where the log output will
       go. The specified file must be writable. 
   
  @@ -318,7 +172,7 @@
       this.tp = new TracerPrintWriter(qw);
       this.fileName = fileName;
       this.fileAppend = append;
  -    this.qwIsOurs = true;
  +    writeHeader();
     }
   
     /**
  @@ -371,11 +225,6 @@
         // Trim spaces from both ends. The users probably does not want 
         // trailing spaces in file names.
         fileName = value.trim();
  -      if(fileName.equalsIgnoreCase("System.out")) {
  -	setWriter(new OutputStreamWriter(System.out));
  -      } else if(fileName.equalsIgnoreCase("System.err")) {
  -	setWriter(new OutputStreamWriter(System.err));
  -      }
       }
       else if (key.equalsIgnoreCase(APPEND_OPTION)) {
         fileAppend = OptionConverter.toBoolean(value, fileAppend);
  @@ -384,6 +233,17 @@
         immediateFlush = OptionConverter.toBoolean(value, immediateFlush);
       }
     }
  +
  +  /**
  +     Sets the quiet writer being used.
  +     
  +     This method is overriden by {@link RollingFileAppender}.
  +   */
  +  protected
  +  void setQWForFiles(Writer writer) {
  +     this.qw = new QuietWriter(writer, errorHandler);
  +  }
  +
     
     public
     String getOption(String key) {
  @@ -397,82 +257,12 @@
         return super.getOption(key);
       }
     }
  -  
  -  /**
  -    <p>Sets the Writer where the log output will go. The
  -    specified Writer must be opened by the user and be
  -    writable.
  -
  -
  -    <p>If there was already an opened stream opened through the {@link
  -    #setFile setFile} method, then the previous stream is closed
  -    first. If the stream was opened by the user and passed to this
  -    method, then the previous stream remains untouched. It is the
  -    user's responsability to close it.
  -
  -    <p><b>WARNING:</b> Logging to an unopened Writer will fail.
  -    <p>  
  -    @param Writer An already opened Writer.
  -    @return Writer The previously attached Writer.
  -  */
  -  public
  -  synchronized
  -  void setWriter(Writer writer) {
  -    reset();
  -    this.qw = new QuietWriter(writer, errorHandler);
  -    this.tp = new TracerPrintWriter(qw);
  -    this.qwIsOurs = false;    
  -  }
  -
  -  protected
  -  void setQWForFiles(Writer writer) {
  -     this.qw = new QuietWriter(writer, errorHandler);
  -  }
  -
  -  /**
  -     Actual writing occurs here.
  -
  -     <p>Most sub-classes of <code>FileAppender</code> will need to
  -     override this method.
  -
  -     @since 0.9.0 */
  -  protected
  -  void subAppend(LoggingEvent event) {
  -    this.qw.write(this.layout.format(event));
  -
  -    if(layout.ignoresThrowable()) {
  -      if(event.throwable != null) {
  -	event.throwable.printStackTrace(this.tp);
  -      }
  -      // in case we received this event from a remote client    
  -      else {
  -	String tInfo = event.getThrowableInformation();
  -	if (tInfo != null) 
  -	  this.qw.write(tInfo);
  -      }
  -    }
  - 
  -    if(this.immediateFlush) {
  -      this.qw.flush();
  -    } 
  -  }
   
  -  /**
  -     The FileAppender requires a layout. Hence, this method returns
  -     <code>true</code>.
  -
  -     @since 0.8.4 */
  -  public
  -  boolean requiresLayout() {
  -    return true;
  -  }
  -
     protected
     void reset() {
  -     closeWriterIfOurs();
  -     this.fileName = null;
  -     this.qw = null;
  -     this.tp = null;    
  +    closeFile();
  +    this.fileName = null;
  +    super.reset();    
     }
  -  
   }
  +
  
  
  
  1.4       +2 -0      jakarta-log4j/org/apache/log4j/Makefile
  
  Index: Makefile
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/Makefile,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Makefile	2000/12/20 15:57:24	1.3
  +++ Makefile	2001/02/13 17:37:06	1.4
  @@ -20,6 +20,8 @@
   	Layout.java \
   	Appender.java \
   	Priority.java\
  +	WriterAppender.java\
  +	ConsoleAppender.java\
   
   SUBDIRS :=helpers spi or xml net nt varia test performance examples gui
   
  
  
  
  1.15      +2 -2      jakarta-log4j/org/apache/log4j/PropertyConfigurator.java
  
  Index: PropertyConfigurator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/PropertyConfigurator.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- PropertyConfigurator.java	2001/02/06 15:11:37	1.14
  +++ PropertyConfigurator.java	2001/02/13 17:37:07	1.15
  @@ -587,8 +587,6 @@
       appender.setName(appenderName);
   
       if(appender instanceof OptionHandler) {
  -      configureOptionHandler((OptionHandler) appender, prefix + ".", props);
  -      LogLog.debug("Parsed \"" + appenderName +"\" options.");
         if(appender.requiresLayout()) {
   	Layout layout = (Layout) OptionConverter.instantiateByKey(props, 
   								  layoutPrefix,
  @@ -601,6 +599,8 @@
   	  LogLog.debug("End of parsing for \"" + appenderName +"\".");      
   	}
         }
  +      configureOptionHandler((OptionHandler) appender, prefix + ".", props);
  +      LogLog.debug("Parsed \"" + appenderName +"\" options.");
       }
       registryPut(appender);
       return appender;
  
  
  
  1.3       +3 -27     jakarta-log4j/org/apache/log4j/RollingFileAppender.java
  
  Index: RollingFileAppender.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/RollingFileAppender.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- RollingFileAppender.java	2000/12/14 21:07:19	1.2
  +++ RollingFileAppender.java	2001/02/13 17:37:07	1.3
  @@ -61,32 +61,6 @@
       super();
     }
   
  - /**
  -    Instantiate a RollingFileAppender and set the output destination to a
  -     new {@link OutputStreamWriter} initialized with <code>os</code>
  -     as its {@link OutputStream}.  
  -     
  -     @deprecated This constructor does not allow to roll files and
  -     will disappear in the near future.  */
  -  public
  -  RollingFileAppender(Layout layout, OutputStream os) {
  -    super(layout, os);
  -  }
  -  
  -  /**
  -     Instantiate a RollingFileAppender and set the output destination
  -     to <code>writer</code>.
  -
  -     <p>The <code>writer</code> must have been opened by the user.  
  -
  -     @deprecated This constructor does not allow to roll files and will
  -     disappear in the near future.  */
  -  public
  -  RollingFileAppender(Layout layout, Writer writer) {
  -    super(layout, writer);
  -  }                    
  -
  -
     /**
       Instantiate a RollingFileAppender and open the file designated by
       <code>filename</code>. The opened filename will become the ouput
  @@ -173,7 +147,9 @@
   
         // Rename fileName to fileName.1
         target = new File(fileName + "." + 1);
  -      this.closeWriterIfOurs(); // keep windows happy. 
  +
  +      this.closeFile(); // keep windows happy. 
  +
         file = new File(fileName);
         file.renameTo(target);
       }
  
  
  
  1.1                  jakarta-log4j/org/apache/log4j/ConsoleAppender.java
  
  Index: ConsoleAppender.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software
   * License version 1.1, a copy of which has been included with this
   * distribution in the LICENSE.APL file.  */
  
  package org.apache.log4j;
  
  import java.io.OutputStreamWriter;
  import org.apache.log4j.helpers.LogLog;
  import org.apache.log4j.helpers.OptionConverter;
  
  /**
     ConsoleAppender appends log events to <code>Syste.errm</code> or
     m<code>System.outm</code> using a layout specified by the user.
  
     @author Ceki G&uuml;lc&uuml;
     @since 1.1 */
  public class ConsoleAppender extends WriterAppender {
  
    public static final String SYSTEM_OUT = "System.out";
    public static final String SYSTEM_ERR = "System.err";
  
    public static final String TARGET_OPTION = "Target";
  
  
    protected String target = "SYSTEM_ERR";
  
    /**
       The default constructor does nothing.
     */
    public ConsoleAppender() {    
    }
  
    public ConsoleAppender(Layout layout) {
      this(layout, SYSTEM_ERR);
    }
  
    public ConsoleAppender(Layout layout, String target) {
      this.layout = layout;
      if(SYSTEM_OUT.equals(target)) {
        setWriter(new OutputStreamWriter(System.out));	
      } else {
        if(!SYSTEM_ERR.equalsIgnoreCase(target)) {
  	targetWarn(target);
        }
        setWriter(new OutputStreamWriter(System.err));
      }
    }
  
   
    public
    void activateOptions() {
      if(target.equals(SYSTEM_OUT)) {
        setWriter(new OutputStreamWriter(System.out));
      } else {
        setWriter(new OutputStreamWriter(System.err));
      }
    }
  
    /**
       Retuns the option names for this component, namely the string
       array {{@link #TARGET_OPTION} and the options of its super class
       {@link WriterAppender}.  */
    public
    String[] getOptionStrings() {
      return OptionConverter.concatanateArrays(super.getOptionStrings(),
            new String[] {TARGET_OPTION});
    }
  
    /**
       Set ConsoleAppender specific options.
            
       The <b>Target</b> option is recognized on top of options
       for the super class {@link WriterAppender}.
       
    */
    public
    void setOption(String key, String value) {
      if(value == null) return;
      super.setOption(key, value);
      
      if (key.equalsIgnoreCase(TARGET_OPTION)) {
        String v = value.trim();
        if(SYSTEM_OUT.equalsIgnoreCase(v)) {
  	target = SYSTEM_OUT;
        } else {
  	if(!SYSTEM_ERR.equalsIgnoreCase(v)) {
  	  targetWarn(value);
  	}  
        }
      }
    }
    
    
    void targetWarn(String val) {
      LogLog.warn("["+val+"] should be one of System.out or System.err.");
      LogLog.warn("Reverting to System.err.");
    }
  }
  
  
  
  1.1                  jakarta-log4j/org/apache/log4j/WriterAppender.java
  
  Index: WriterAppender.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software
   * License version 1.1, a copy of which has been included with this
   * distribution in the LICENSE.APL file.  */
  
  package org.apache.log4j;
  
  import java.io.IOException;
  import java.io.Writer;
  import java.io.FileWriter;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  
  import org.apache.log4j.spi.ErrorHandler;
  import org.apache.log4j.spi.ErrorCode;
  import org.apache.log4j.spi.LoggingEvent;
  import org.apache.log4j.helpers.OptionConverter;
  import org.apache.log4j.helpers.QuietWriter;
  import org.apache.log4j.helpers.LogLog;
  import org.apache.log4j.helpers.TracerPrintWriter;
  
  // Contibutors: Jens Uwe Pipka <je...@gmx.de>
  
  /**
     WriterAppender appends log events to a {@link java.io.Writer} or an
     {@link java.io.OutputStream} depending on the user's choice.
  
     @author Ceki G&uuml;lc&uuml;
     @since 1.1 */
  public class WriterAppender extends AppenderSkeleton {
  
    /**
       A string constant used in naming the option for immediate
       flushing of the output stream at the end of each append
       operation. Current value of this string constant is
       <b>ImmediateFlush</b>.
  
       <p>Note that all option keys are case sensitive.     
    */
    public static final String IMMEDIATE_FLUSH_OPTION = "ImmediateFlush";
  
    /**
       Immediate flush means that the undelying writer or output stream
       will be flushed at the end of each append operation. Immediate
       flush is slower but ensures that each append request is actually
       written. If <code>immediateFlush</code> is set to
       <code>false</code>, then there is a good chance that the last few
       logs events are not actually written to persistent media if and
       when the application crashes.
  
       <p>The <code>immediateFlush</code> variable is set to
       <code>true</code> by default.
  
    */
    protected boolean immediateFlush = true;
  
    /**
       This is the {@link QuietWriter quietWriter} where we will write
       to. 
    */
    protected QuietWriter qw;
  
    /**
       {@link TracerPrintWriter} is specialized in optimized printing
       of stack traces (obtained from throwables) to a Writer. 
    */
    protected TracerPrintWriter tp;
    
    
    /**
       This default constructor does nothing.  */
    public
    WriterAppender() {
    }
  
    /**
       Instantiate a WriterAppender and set the output destination to a
       new {@link OutputStreamWriter} initialized with <code>os</code>
       as its {@link OutputStream}.  */
    public
    WriterAppender(Layout layout, OutputStream os) {
      this(layout, new OutputStreamWriter(os));
    }
    
    /**
       Instantiate a WriterAppender and set the output destination to
       <code>writer</code>.
  
       <p>The <code>writer</code> must have been previously opened by
       the user.  */
    public
    WriterAppender(Layout layout, Writer writer) {
      this.layout = layout;
      this.setWriter(writer);
    }
  
  
    /**
       Does nothing.
    */
    public
    void activateOptions() {    
    }
  
  
    /**
       This method called by {@link AppenderSkeleton#doAppend}
       method. 
  
       <p>If the output stream exists an is writable then write a log
       statement to the output stream. Otherwise, write a single warning
       message to <code>System.err</code>.
  
       <p>The format of the output will depend on this appender's
       layout.
       
    */
    public
    void append(LoggingEvent event) {
  
      // Reminder: the nesting of calls is:
      //
      //    doAppend()
      //      - check threshold
      //      - filter
      //      - append();
      //        - checkEntryConditions();
      //        - subAppend();
  
      if(!checkEntryConditions()) {
        return;
      }
      subAppend(event);
     } 
  
    /**
       This method determines if there is a sense in attempting to append.
       
       <p>It checks whether there is a set output target and also if
       there is a set layout. If these checks fail, then the boolean
       value <code>false</code> is returned. */
    protected
    boolean checkEntryConditions() {
      if(this.qw == null) {
        errorHandler.error("No output target set for appender named \""+ 
  			name+"\".");
        return false;
      }
      
      if(this.layout == null) {
        errorHandler.error("No layout set for appender named \""+ name+"\".");
        return false;
      }
      return true;
    }
  
  
    /**
       Will close the stream opened by a previos {@link #setFile}
       call. If the writer is owned by the user it remains untouched.
  
       @see #setFile
       @see #setWriter
       @since 0.8.4
    */
    public
    synchronized
    void close() {
      if(this.closed)
        return;
      this.closed = true;
      writeFooter();
      reset();
    }
  
    public
    String getOption(String key) {
      if (key.equalsIgnoreCase(IMMEDIATE_FLUSH_OPTION)) {
        return immediateFlush ? "true" : "false";
      } else {
        return super.getOption(key);
      }
    }
  
  
    /**
       Retuns the option names for this component, namely the string
       array {{@link #FILE_OPTION}, {@link #APPEND_OPTION}} in addition
       to the options of its super class {@link AppenderSkeleton}.  */
    public
    String[] getOptionStrings() {
      return OptionConverter.concatanateArrays(super.getOptionStrings(),
             new String[] {IMMEDIATE_FLUSH_OPTION});
    }
  
  
  
    /**
       Set the {@link ErrorHandler} for this FileAppender and also the
       undelying {@link QuietWriter} if any. */
    public
    synchronized 
    void setErrorHandler(ErrorHandler eh) {
      if(eh == null) {
        LogLog.warn("You have tried to set a null error-handler.");
      } else {
        this.errorHandler = eh;
        if(this.qw != null) {
  	this.qw.setErrorHandler(eh);
        }
      }    
    }
    
    
    /**
       Set WriterAppender specific options.
            
       The <b>ImmediateFlush</b> option is recognized on top of options
       for the super class {@link AppenderSkeleton}.
    */
    public
    void setOption(String key, String value) {
      if(value == null) return;
      super.setOption(key, value);
      
      if (key.equalsIgnoreCase(IMMEDIATE_FLUSH_OPTION)) {
        immediateFlush = OptionConverter.toBoolean(value, immediateFlush);
      }
    }
  
    
    /**
      <p>Sets the Writer where the log output will go. The
      specified Writer must be opened by the user and be
      writable.
  
  
      <p>If there was already an opened stream opened through the {@link
      #setFile setFile} method, then the previous stream is closed
      first. If the stream was opened by the user and passed to this
      method, then the previous stream remains untouched. It is the
      user's responsability to close it.
  
      <p><b>WARNING:</b> Logging to an unopened Writer will fail.
      <p>  
      @param Writer An already opened Writer.
      @return Writer The previously attached Writer.
    */
    public
    synchronized
    void setWriter(Writer writer) {
      reset();
      this.qw = new QuietWriter(writer, errorHandler);
      this.tp = new TracerPrintWriter(qw);
      writeHeader();
    }
  
  
    /**
       Actual writing occurs here.
  
       <p>Most sub-classes of <code>FileAppender</code> will need to
       override this method.
  
       @since 0.9.0 */
    protected
    void subAppend(LoggingEvent event) {
      this.qw.write(this.layout.format(event));
  
      if(layout.ignoresThrowable()) {
        if(event.throwable != null) {
  	event.throwable.printStackTrace(this.tp);
        }
        // in case we received this event from a remote client    
        else {
  	String tInfo = event.getThrowableInformation();
  	if (tInfo != null) 
  	  this.qw.write(tInfo);
        }
      }
   
      if(this.immediateFlush) {
        this.qw.flush();
      } 
    }
  
    /**
       The WriterAppender requires a layout. Hence, this method returns
       <code>true</code>.
    */
    public
    boolean requiresLayout() {
      return true;
    }
  
  
    /**
       Clerar internal references to the writer and other variables.
     */
    protected
    void reset() {
       this.qw = null;
       this.tp = null;    
    }  
  
    protected
    void writeFooter() {
      if(layout != null) {
        String f = layout.getFooter();
        if(f != null && this.qw != null)
  	this.qw.write(f);
      }
    }
  
    protected 
    void writeHeader() {
      if(layout != null) {
        String h = layout.getHeader();
        if(h != null && this.qw != null)
  	this.qw.write(h);
      }
    }
  }
  
  
  
  1.5       +1 -1      jakarta-log4j/org/apache/log4j/examples/MyCategory.java
  
  Index: MyCategory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/examples/MyCategory.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- MyCategory.java	2001/02/03 22:39:22	1.4
  +++ MyCategory.java	2001/02/13 17:37:15	1.5
  @@ -51,7 +51,7 @@
         // goes to System.out.
         Category root = Category.getRoot();
         Layout layout = new PatternLayout("%p [%t] %c - %m%n");
  -      root.addAppender(new FileAppender(layout, System.out));
  +      root.addAppender(new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT));
       }
       else if(args.length == 1) {
         if(args[0].endsWith("xml")) {
  
  
  
  1.3       +1 -1      jakarta-log4j/org/apache/log4j/examples/MyPatternLayout.java
  
  Index: MyPatternLayout.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/examples/MyPatternLayout.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MyPatternLayout.java	2000/12/14 21:07:34	1.2
  +++ MyPatternLayout.java	2001/02/13 17:37:15	1.3
  @@ -47,7 +47,7 @@
     static void main(String[] args) {
       Layout layout = new MyPatternLayout("[counter=%.10#] - %m%n");
       Category cat = Category.getInstance("some.cat");
  -    cat.addAppender(new FileAppender(layout, System.out));
  +    cat.addAppender(new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT));
       cat.debug("Hello, log");
       cat.info("Hello again...");    
     }
  
  
  
  1.15      +3 -0      jakarta-log4j/org/apache/log4j/net/SMTPAppender.java
  
  Index: SMTPAppender.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/net/SMTPAppender.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- SMTPAppender.java	2001/02/06 17:43:10	1.14
  +++ SMTPAppender.java	2001/02/13 17:37:18	1.15
  @@ -153,6 +153,9 @@
     }
   
   
  +  /**
  +     Activate the specified options, such as the smtp host, the
  +     recipient, from, etc. */
     public
     void activateOptions() {
       Properties props = System.getProperties();
  
  
  
  1.3       +1 -1      jakarta-log4j/org/apache/log4j/net/test/Loop.java
  
  Index: Loop.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/net/test/Loop.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Loop.java	2000/12/14 21:07:58	1.2
  +++ Loop.java	2001/02/13 17:37:22	1.3
  @@ -33,7 +33,7 @@
   
       SocketAppender sa = new SocketAppender(host, port);
       Layout layout = new PatternLayout("%5p [%t] %x %c - %m\n");
  -    FileAppender so = new FileAppender(layout, System.out);
  +    Appender so = new ConsoleAppender(layout, "System.out");
       root.addAppender(sa);
       root.addAppender(so);
   
  
  
  
  1.4       +2 -2      jakarta-log4j/org/apache/log4j/performance/NotLogging.java
  
  Index: NotLogging.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/performance/NotLogging.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NotLogging.java	2001/01/22 22:11:31	1.3
  +++ NotLogging.java	2001/02/13 17:37:25	1.4
  @@ -7,7 +7,7 @@
   import org.apache.log4j.Category;
   import org.apache.log4j.BasicConfigurator;
   import org.apache.log4j.SimpleLayout;
  -import org.apache.log4j.FileAppender;
  +import org.apache.log4j.ConsoleAppender;
   import org.apache.log4j.Layout;
   
   import org.apache.log4j.Priority;
  @@ -122,7 +122,7 @@
       }      
   
       
  -    FileAppender appender = new FileAppender(new SimpleLayout(), System.err);
  +    ConsoleAppender appender = new ConsoleAppender(new SimpleLayout());
       
       if("false".equals(args[0]))
         ;       
  
  
  
  1.3       +1 -1      jakarta-log4j/org/apache/log4j/test/CategoryWrapper.java
  
  Index: CategoryWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/CategoryWrapper.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CategoryWrapper.java	2000/12/14 21:08:13	1.2
  +++ CategoryWrapper.java	2001/02/13 17:37:28	1.3
  @@ -23,7 +23,7 @@
     static 
     void main(String argv[]) {    
       Layout layout = new PatternLayout("%p [%t] %C %F - %m\n");
  -    Appender out = new FileAppender(layout, System.out);
  +    Appender out = new ConsoleAppender(layout, ConsoleAppender.SYSTEM_OUT);
       CategoryWrapper w1 = new CategoryWrapper("c1");
       w1.addAppender(out);
       w1.print("hello");
  
  
  
  1.4       +1 -0      jakarta-log4j/org/apache/log4j/test/ConfigurationFileParsing.java
  
  Index: ConfigurationFileParsing.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/ConfigurationFileParsing.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ConfigurationFileParsing.java	2000/12/14 21:08:13	1.3
  +++ ConfigurationFileParsing.java	2001/02/13 17:37:29	1.4
  @@ -24,6 +24,7 @@
         root.debug("Message 1");
         root.debug("Message 2");      
         NDC.pop();
  +      Category.shutdown();
       }
       else {
         Usage("Wrong number of arguments.");
  
  
  
  1.7       +1 -0      jakarta-log4j/org/apache/log4j/test/Makefile
  
  Index: Makefile
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/Makefile,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Makefile	2001/01/24 16:15:27	1.6
  +++ Makefile	2001/02/13 17:37:29	1.7
  @@ -25,6 +25,7 @@
    UnitTestVarSubst.java\
    SocketAppenderTest.java\
    UnitTestOR.java\
  + PrintProperties.java\
   
   SUBDIRS :=
   
  
  
  
  1.3       +2 -2      jakarta-log4j/org/apache/log4j/test/Min.java
  
  Index: Min.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/Min.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Min.java	2000/12/14 21:08:13	1.2
  +++ Min.java	2001/02/13 17:37:30	1.3
  @@ -10,7 +10,7 @@
   import org.apache.log4j.Category;
   import org.apache.log4j.Layout;
   import org.apache.log4j.Appender;
  -import org.apache.log4j.FileAppender;
  +import org.apache.log4j.ConsoleAppender;
   import org.apache.log4j.net.SyslogAppender;
   import org.apache.log4j.SimpleLayout;
   import org.apache.log4j.TTCCLayout;
  @@ -69,7 +69,7 @@
         Usage("Wrong layoutType [" + layoutType +"].");
   
   
  -    appender = new FileAppender(layout, System.out);
  +    appender = new ConsoleAppender(layout, "System.out");
       BasicConfigurator.configure(appender);
     }
   
  
  
  
  1.4       +2 -0      jakarta-log4j/org/apache/log4j/test/PatternTest.java
  
  Index: PatternTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/PatternTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- PatternTest.java	2000/12/14 21:08:13	1.3
  +++ PatternTest.java	2001/02/13 17:37:31	1.4
  @@ -72,5 +72,7 @@
   
       CAT.log(Priority.FATAL, "Message " + ++i, e);
       root.log(Priority.FATAL, "Message " + i, e);    
  +    
  +    Category.shutdown();
     }
   }
  
  
  
  1.4       +3 -3      jakarta-log4j/org/apache/log4j/test/ShippedCodeFlagTest.java
  
  Index: ShippedCodeFlagTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/ShippedCodeFlagTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ShippedCodeFlagTest.java	2001/01/22 22:11:33	1.3
  +++ ShippedCodeFlagTest.java	2001/02/13 17:37:32	1.4
  @@ -5,7 +5,7 @@
   import org.apache.log4j.BasicConfigurator;
   import org.apache.log4j.PropertyConfigurator;
   import org.apache.log4j.SimpleLayout;
  -import org.apache.log4j.FileAppender;
  +import org.apache.log4j.ConsoleAppender;
   	
   public class ShippedCodeFlagTest {
   
  @@ -26,8 +26,8 @@
   		  System.getProperty(BasicConfigurator.DISABLE_OVERRIDE_KEY)
   			  +"].");
       
  -       BasicConfigurator.configure(new FileAppender(new SimpleLayout(),
  -						 System.out));
  +       BasicConfigurator.configure(new ConsoleAppender(new SimpleLayout(),
  +						 ConsoleAppender.SYSTEM_OUT));
        
       }
       else { 
  
  
  
  1.4       +3 -3      jakarta-log4j/org/apache/log4j/test/SysoutConfigurator.java
  
  Index: SysoutConfigurator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/SysoutConfigurator.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SysoutConfigurator.java	2001/01/07 21:10:56	1.3
  +++ SysoutConfigurator.java	2001/02/13 17:37:32	1.4
  @@ -6,7 +6,7 @@
   import org.apache.log4j.spi.Configurator;
   import org.apache.log4j.spi.LoggingEvent;
   import org.apache.log4j.SimpleLayout;
  -import org.apache.log4j.FileAppender;
  +import org.apache.log4j.ConsoleAppender;
   
   /**
    * This configurator simply always adds a FileAppender writing to
  @@ -18,7 +18,7 @@
     void
     doConfigure(java.net.URL url, Hierarchy hierarchy) {
       Category.getRoot().addAppender(
  -        new FileAppender(
  -            new SimpleLayout(), System.out));
  +        new ConsoleAppender(
  +            new SimpleLayout(), ConsoleAppender.SYSTEM_OUT));
     }
   }
  
  
  
  1.4       +4 -5      jakarta-log4j/org/apache/log4j/test/confParsing
  
  Index: confParsing
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/confParsing,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- confParsing	2001/01/05 21:09:04	1.3
  +++ confParsing	2001/02/13 17:37:33	1.4
  @@ -182,10 +182,9 @@
     D_FLAG=""
     echo  "log4j.rootCategory= DEBUG , testAppender" > $LCF
     lecho "log4j.configDebug=false"
  -  lecho "log4j.appender.testAppender=org.apache.log4j.FileAppender"
  +  lecho "log4j.appender.testAppender=org.apache.log4j.ConsoleAppender"
     # Note the spaces
  -  lecho "log4j.appender.testAppender.File=System.out  "
  -  lecho "log4j.appender.testAppender.Append= true"
  +  lecho "log4j.appender.testAppender.Target=System.out  "
     lecho "log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout "
     lecho "log4j.appender.testAppender.layout.ConversionPattern=[%t] %p - %m%n"
     echo -n " ConfigurationParsing test $TEST - "
  @@ -197,8 +196,8 @@
     D_FLAG=""
     echo  "log4j.rootCategory= DEBUG , testAppender" > $LCF
     lecho "log4j.configDebug=false"
  -  lecho "log4j.appender.testAppender=org.apache.log4j.FileAppender"
  -  lecho "log4j.appender.testAppender.File=  System.out  "
  +  lecho "log4j.appender.testAppender=org.apache.log4j.ConsoleAppender"
  +  lecho "log4j.appender.testAppender.Target=  System.out  "
     lecho "log4j.appender.testAppender.Append= true  "
     lecho "log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout"
     lecho "log4j.appender.testAppender.layout.ConversionPattern=[%t] %p - %m%n"
  
  
  
  1.3       +1 -1      jakarta-log4j/org/apache/log4j/test/getOptions
  
  Index: getOptions
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/getOptions,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- getOptions	2001/01/26 14:27:19	1.2
  +++ getOptions	2001/02/13 17:37:34	1.3
  @@ -45,7 +45,7 @@
   
   TEST=1
   if [ $TEST -ge $start ]; then
  -  testGetOptions
  +  testGetOptions 
   fi
   
   rm $LCF
  
  
  
  1.3       +10 -0     jakarta-log4j/org/apache/log4j/test/pattern
  
  Index: pattern
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/pattern,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- pattern	2001/01/05 21:09:07	1.2
  +++ pattern	2001/02/13 17:37:34	1.3
  @@ -184,3 +184,13 @@
     lecho "log4j.appender.testAppender.layout.ConversionPattern=%5p %-4# - %m%n" 
     testPattern NONE
   fi
  +
  +TEST=15
  +if [ $TEST -ge $start ]; then
  +  echo "log4j.rootCategory=DEBUG, testAppender" > $LCF
  +  lecho "log4j.appender.testAppender=org.apache.log4j.FileAppender"
  +  lecho "log4j.appender.testAppender.File=       $TEMP   "
  +  lecho "log4j.appender.testAppender.Append=false"
  +  lecho "log4j.appender.testAppender.layout=org.apache.log4j.HTMLLayout"
  +  testPattern NONE
  +fi
  
  
  
  1.4       +4 -4      jakarta-log4j/org/apache/log4j/test/shippedCodeFlag
  
  Index: shippedCodeFlag
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/shippedCodeFlag,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- shippedCodeFlag	2001/01/05 21:09:10	1.3
  +++ shippedCodeFlag	2001/02/13 17:37:35	1.4
  @@ -29,8 +29,8 @@
   TEST=3
   if [ $TEST -ge $start ]; then
     echo "log4j.rootCategory=,A" > $LCF
  -  lecho "log4j.appender.A=org.apache.log4j.FileAppender"
  -  lecho "log4j.appender.A.File=System.out"
  +  lecho "log4j.appender.A=org.apache.log4j.ConsoleAppender"
  +  lecho "log4j.appender.A.Target=System.out"
     lecho "log4j.appender.A.layout=org.apache.log4j.PatternLayout"
     lecho "log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n"    
     testSCF $LCF 
  @@ -41,8 +41,8 @@
   if [ $TEST -ge $start ]; then
     echo "log4j.disableOverride" > $LCF
     lecho "log4j.rootCategory=,A"
  -  lecho "log4j.appender.A=org.apache.log4j.FileAppender"
  -  lecho "log4j.appender.A.File=System.out"
  +  lecho "log4j.appender.A=org.apache.log4j.ConsoleAppender"
  +  lecho "log4j.appender.A.Target=System.out"
     lecho "log4j.appender.A.layout=org.apache.log4j.PatternLayout"
     lecho "log4j.appender.A.layout.ConversionPattern=%p [%t] %c{2} = %m%n"    
     testSCF $LCF 
  
  
  
  1.3       +1 -1      jakarta-log4j/org/apache/log4j/test/witness/getOptions.1
  
  Index: getOptions.1
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/test/witness/getOptions.1,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- getOptions.1	2001/01/26 14:27:20	1.2
  +++ getOptions.1	2001/02/13 17:37:47	1.3
  @@ -1,7 +1,7 @@
   log4j.appender.f=org.apache.log4j.FileAppender
  +log4j.appender.f.ImmediateFlush=true
   log4j.appender.f.File=temp
   log4j.appender.f.Append=false
  -log4j.appender.f.ImmediateFlush=true
   log4j.appender.f.layout=org.apache.log4j.PatternLayout
   log4j.appender.f.layout.ConversionPattern=%m%n
   log4j.rootCategory=DEBUG, f
  
  
  
  1.4       +0 -1      jakarta-log4j/org/apache/log4j/varia/Makefile
  
  Index: Makefile
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/org/apache/log4j/varia/Makefile,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Makefile	2000/12/19 13:59:21	1.3
  +++ Makefile	2001/02/13 17:37:50	1.4
  @@ -2,7 +2,6 @@
   PKG_DIR :=org/apache/log4j/varia
   DEPTH   :=../../../..
   JSOURCES:=ExternallyRolledFileAppender.java\
  -	  ResilientFileAppender.java\
   	  Roller.java\
   	  DenyAllFilter.java\
   	  StringMatchFilter.java\