Save This Page
Home » slf4j-1.5.5 » org.apache » log4j » [javadoc | source]
    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.Writer;
   22   import java.io.FileOutputStream;
   23   import java.io.BufferedWriter;
   24   import java.io.FileNotFoundException;
   25   import java.io.File;
   26   
   27   import org.apache.log4j.spi.ErrorCode;
   28   import org.apache.log4j.helpers.QuietWriter;
   29   import org.apache.log4j.helpers.LogLog;
   30   
   31   // Contibutors: Jens Uwe Pipka <jens.pipka@gmx.de>
   32   //              Ben Sandee
   33   
   34   /**
   35    *  FileAppender appends log events to a file.
   36    *
   37    *  <p>Support for <code>java.io.Writer</code> and console appending
   38    *  has been deprecated and then removed. See the replacement
   39    *  solutions: {@link WriterAppender} and {@link ConsoleAppender}.
   40    *
   41    * @author Ceki G&uuml;lc&uuml; 
   42    * */
   43   public class FileAppender extends WriterAppender {
   44   
   45     /** Controls file truncatation. The default value for this variable
   46      * is <code>true</code>, meaning that by default a
   47      * <code>FileAppender</code> will append to an existing file and not
   48      * truncate it.
   49      *
   50      * <p>This option is meaningful only if the FileAppender opens the
   51      * file.
   52      */
   53     protected boolean fileAppend = true;
   54   
   55     /**
   56        The name of the log file. */
   57     protected String fileName = null;
   58   
   59     /**
   60        Do we do bufferedIO? */
   61     protected boolean bufferedIO = false;
   62   
   63     /**
   64      * Determines the size of IO buffer be. Default is 8K. 
   65      */
   66     protected int bufferSize = 8*1024;
   67   
   68   
   69     /**
   70        The default constructor does not do anything.
   71     */
   72     public
   73     FileAppender() {
   74     }
   75   
   76     /**
   77       Instantiate a <code>FileAppender</code> and open the file
   78       designated by <code>filename</code>. The opened filename will
   79       become the output destination for this appender.
   80   
   81       <p>If the <code>append</code> parameter is true, the file will be
   82       appended to. Otherwise, the file designated by
   83       <code>filename</code> will be truncated before being opened.
   84   
   85       <p>If the <code>bufferedIO</code> parameter is <code>true</code>,
   86       then buffered IO will be used to write to the output file.
   87   
   88     */
   89     public
   90     FileAppender(Layout layout, String filename, boolean append, boolean bufferedIO,
   91   	       int bufferSize) throws IOException {
   92       this.layout = layout;
   93       this.setFile(filename, append, bufferedIO, bufferSize);
   94     }
   95   
   96     /**
   97       Instantiate a FileAppender and open the file designated by
   98       <code>filename</code>. The opened filename will become the output
   99       destination for this appender.
  100   
  101       <p>If the <code>append</code> parameter is true, the file will be
  102       appended to. Otherwise, the file designated by
  103       <code>filename</code> will be truncated before being opened.
  104     */
  105     public
  106     FileAppender(Layout layout, String filename, boolean append)
  107                                                                throws IOException {
  108       this.layout = layout;
  109       this.setFile(filename, append, false, bufferSize);
  110     }
  111   
  112     /**
  113        Instantiate a FileAppender and open the file designated by
  114       <code>filename</code>. The opened filename will become the output
  115       destination for this appender.
  116   
  117       <p>The file will be appended to.  */
  118     public
  119     FileAppender(Layout layout, String filename) throws IOException {
  120       this(layout, filename, true);
  121     }
  122   
  123     /**
  124        The <b>File</b> property takes a string value which should be the
  125        name of the file to append to.
  126   
  127        <p><font color="#DD0044"><b>Note that the special values
  128        "System.out" or "System.err" are no longer honored.</b></font>
  129   
  130        <p>Note: Actual opening of the file is made when {@link
  131        #activateOptions} is called, not when the options are set.  */
  132     public void setFile(String file) {
  133       // Trim spaces from both ends. The users probably does not want
  134       // trailing spaces in file names.
  135       String val = file.trim();
  136       fileName = val;
  137     }
  138   
  139     /**
  140         Returns the value of the <b>Append</b> option.
  141      */
  142     public
  143     boolean getAppend() {
  144       return fileAppend;
  145     }
  146   
  147   
  148     /** Returns the value of the <b>File</b> option. */
  149     public
  150     String getFile() {
  151       return fileName;
  152     }
  153   
  154     /**
  155        If the value of <b>File</b> is not <code>null</code>, then {@link
  156        #setFile} is called with the values of <b>File</b>  and
  157        <b>Append</b> properties.
  158   
  159        @since 0.8.1 */
  160     public
  161     void activateOptions() {
  162       if(fileName != null) {
  163         try {
  164   	setFile(fileName, fileAppend, bufferedIO, bufferSize);
  165         }
  166         catch(java.io.IOException e) {
  167   	errorHandler.error("setFile("+fileName+","+fileAppend+") call failed.",
  168   			   e, ErrorCode.FILE_OPEN_FAILURE);
  169         }
  170       } else {
  171         //LogLog.error("File option not set for appender ["+name+"].");
  172         LogLog.warn("File option not set for appender ["+name+"].");
  173         LogLog.warn("Are you using FileAppender instead of ConsoleAppender?");
  174       }
  175     }
  176   
  177    /**
  178        Closes the previously opened file.
  179     */
  180     protected
  181     void closeFile() {
  182       if(this.qw != null) {
  183         try {
  184   	this.qw.close();
  185         }
  186         catch(java.io.IOException e) {
  187   	// Exceptionally, it does not make sense to delegate to an
  188   	// ErrorHandler. Since a closed appender is basically dead.
  189   	LogLog.error("Could not close " + qw, e);
  190         }
  191       }
  192     }
  193   
  194     /**
  195        Get the value of the <b>BufferedIO</b> option.
  196   
  197        <p>BufferedIO will significatnly increase performance on heavily
  198        loaded systems.
  199   
  200     */
  201     public
  202     boolean getBufferedIO() {
  203       return this.bufferedIO;
  204     }
  205   
  206   
  207     /**
  208        Get the size of the IO buffer.
  209     */
  210     public
  211     int getBufferSize() {
  212       return this.bufferSize;
  213     }
  214   
  215   
  216   
  217     /**
  218        The <b>Append</b> option takes a boolean value. It is set to
  219        <code>true</code> by default. If true, then <code>File</code>
  220        will be opened in append mode by {@link #setFile setFile} (see
  221        above). Otherwise, {@link #setFile setFile} will open
  222        <code>File</code> in truncate mode.
  223   
  224        <p>Note: Actual opening of the file is made when {@link
  225        #activateOptions} is called, not when the options are set.
  226      */
  227     public
  228     void setAppend(boolean flag) {
  229       fileAppend = flag;
  230     }
  231   
  232     /**
  233        The <b>BufferedIO</b> option takes a boolean value. It is set to
  234        <code>false</code> by default. If true, then <code>File</code>
  235        will be opened and the resulting {@link java.io.Writer} wrapped
  236        around a {@link BufferedWriter}.
  237   
  238        BufferedIO will significatnly increase performance on heavily
  239        loaded systems.
  240   
  241     */
  242     public
  243     void setBufferedIO(boolean bufferedIO) {
  244       this.bufferedIO = bufferedIO;
  245       if(bufferedIO) {
  246         immediateFlush = false;
  247       }
  248     }
  249   
  250   
  251     /**
  252        Set the size of the IO buffer.
  253     */
  254     public
  255     void setBufferSize(int bufferSize) {
  256       this.bufferSize = bufferSize;
  257     }
  258   
  259     /**
  260       <p>Sets and <i>opens</i> the file where the log output will
  261       go. The specified file must be writable.
  262   
  263       <p>If there was already an opened file, then the previous file
  264       is closed first.
  265   
  266       <p><b>Do not use this method directly. To configure a FileAppender
  267       or one of its subclasses, set its properties one by one and then
  268       call activateOptions.</b>
  269   
  270       @param fileName The path to the log file.
  271       @param append   If true will append to fileName. Otherwise will
  272           truncate fileName.  */
  273     public
  274     synchronized
  275     void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
  276                                                               throws IOException {
  277       LogLog.debug("setFile called: "+fileName+", "+append);
  278   
  279       // It does not make sense to have immediate flush and bufferedIO.
  280       if(bufferedIO) {
  281         setImmediateFlush(false);
  282       }
  283   
  284       reset();
  285       FileOutputStream ostream = null;
  286       try {
  287             //
  288             //   attempt to create file
  289             //
  290             ostream = new FileOutputStream(fileName, append);
  291       } catch(FileNotFoundException ex) {
  292             //
  293             //   if parent directory does not exist then
  294             //      attempt to create it and try to create file
  295             //      see bug 9150
  296             //
  297             String parentName = new File(fileName).getParent();
  298             if (parentName != null) {
  299                File parentDir = new File(parentName);
  300                if(!parentDir.exists() && parentDir.mkdirs()) {
  301                   ostream = new FileOutputStream(fileName, append);
  302                } else {
  303                   throw ex;
  304                }
  305             } else {
  306                throw ex;
  307             }
  308       }
  309       Writer fw = createWriter(ostream);
  310       if(bufferedIO) {
  311         fw = new BufferedWriter(fw, bufferSize);
  312       }
  313       this.setQWForFiles(fw);
  314       this.fileName = fileName;
  315       this.fileAppend = append;
  316       this.bufferedIO = bufferedIO;
  317       this.bufferSize = bufferSize;
  318       writeHeader();
  319       LogLog.debug("setFile ended");
  320     }
  321   
  322   
  323     /**
  324        Sets the quiet writer being used.
  325   
  326        This method is overriden by {@link RollingFileAppender}.
  327      */
  328     protected
  329     void setQWForFiles(Writer writer) {
  330        this.qw = new QuietWriter(writer, errorHandler);
  331     }
  332   
  333   
  334     /**
  335        Close any previously opened file and call the parent's
  336        <code>reset</code>.  */
  337     protected
  338     void reset() {
  339       closeFile();
  340       this.fileName = null;
  341       super.reset();
  342     }
  343   }
  344   

Save This Page
Home » slf4j-1.5.5 » org.apache » log4j » [javadoc | source]