Save This Page
Home » SLF4J-1.5.8 » 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   
   19   
   20   package org.apache.log4j;
   21   
   22   import java.io.IOException;
   23   import java.io.Writer;
   24   import java.io.File;
   25   import org.apache.log4j.helpers.OptionConverter;
   26   import org.apache.log4j.helpers.LogLog;
   27   import org.apache.log4j.helpers.CountingQuietWriter;
   28   import org.apache.log4j.spi.LoggingEvent;
   29   
   30   /**
   31      RollingFileAppender extends FileAppender to backup the log files when
   32      they reach a certain size.
   33   
   34      @author Heinz Richter
   35      @author Ceki Gülcü
   36   
   37   */
   38   public class RollingFileAppender extends FileAppender {
   39   
   40     /**
   41        The default maximum file size is 10MB.
   42     */
   43     protected long maxFileSize = 10*1024*1024;
   44   
   45     /**
   46        There is one backup file by default.
   47      */
   48     protected int  maxBackupIndex  = 1;
   49   
   50     private long nextRollover = 0;
   51   
   52     /**
   53        The default constructor simply calls its {@link
   54        FileAppender#FileAppender parents constructor}.  */
   55     public
   56     RollingFileAppender() {
   57       super();
   58     }
   59   
   60     /**
   61       Instantiate a RollingFileAppender and open the file designated by
   62       <code>filename</code>. The opened filename will become the ouput
   63       destination for this appender.
   64   
   65       <p>If the <code>append</code> parameter is true, the file will be
   66       appended to. Otherwise, the file desginated by
   67       <code>filename</code> will be truncated before being opened.
   68     */
   69     public
   70     RollingFileAppender(Layout layout, String filename, boolean append)
   71                                         throws IOException {
   72       super(layout, filename, append);
   73     }
   74   
   75     /**
   76        Instantiate a FileAppender and open the file designated by
   77       <code>filename</code>. The opened filename will become the output
   78       destination for this appender.
   79   
   80       <p>The file will be appended to.  */
   81     public
   82     RollingFileAppender(Layout layout, String filename) throws IOException {
   83       super(layout, filename);
   84     }
   85   
   86     /**
   87        Returns the value of the <b>MaxBackupIndex</b> option.
   88      */
   89     public
   90     int getMaxBackupIndex() {
   91       return maxBackupIndex;
   92     }
   93   
   94    /**
   95       Get the maximum size that the output file is allowed to reach
   96       before being rolled over to backup files.
   97   
   98       @since 1.1
   99    */
  100     public
  101     long getMaximumFileSize() {
  102       return maxFileSize;
  103     }
  104   
  105     /**
  106        Implements the usual roll over behaviour.
  107   
  108        <p>If <code>MaxBackupIndex</code> is positive, then files
  109        {<code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code>}
  110        are renamed to {<code>File.2</code>, ...,
  111        <code>File.MaxBackupIndex</code>}. Moreover, <code>File</code> is
  112        renamed <code>File.1</code> and closed. A new <code>File</code> is
  113        created to receive further log output.
  114   
  115        <p>If <code>MaxBackupIndex</code> is equal to zero, then the
  116        <code>File</code> is truncated with no backup files created.
  117   
  118      */
  119     public // synchronization not necessary since doAppend is alreasy synched
  120     void rollOver() {
  121       File target;
  122       File file;
  123   
  124       if (qw != null) {
  125           long size = ((CountingQuietWriter) qw).getCount();
  126           LogLog.debug("rolling over count=" + size);
  127           //   if operation fails, do not roll again until
  128           //      maxFileSize more bytes are written
  129           nextRollover = size + maxFileSize;
  130       }
  131       LogLog.debug("maxBackupIndex="+maxBackupIndex);
  132   
  133       boolean renameSucceeded = true;
  134       // If maxBackups <= 0, then there is no file renaming to be done.
  135       if(maxBackupIndex > 0) {
  136         // Delete the oldest file, to keep Windows happy.
  137         file = new File(fileName + '.' + maxBackupIndex);
  138         if (file.exists())
  139          renameSucceeded = file.delete();
  140   
  141         // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}
  142         for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) {
  143   	file = new File(fileName + "." + i);
  144   	if (file.exists()) {
  145   	  target = new File(fileName + '.' + (i + 1));
  146   	  LogLog.debug("Renaming file " + file + " to " + target);
  147   	  renameSucceeded = file.renameTo(target);
  148   	}
  149         }
  150   
  151       if(renameSucceeded) {
  152         // Rename fileName to fileName.1
  153         target = new File(fileName + "." + 1);
  154   
  155         this.closeFile(); // keep windows happy.
  156   
  157         file = new File(fileName);
  158         LogLog.debug("Renaming file " + file + " to " + target);
  159         renameSucceeded = file.renameTo(target);
  160         //
  161         //   if file rename failed, reopen file with append = true
  162         //
  163         if (!renameSucceeded) {
  164             try {
  165               this.setFile(fileName, true, bufferedIO, bufferSize);
  166             }
  167             catch(IOException e) {
  168               LogLog.error("setFile("+fileName+", true) call failed.", e);
  169             }
  170         }
  171       }
  172       }
  173   
  174       //
  175       //   if all renames were successful, then
  176       //
  177       if (renameSucceeded) {
  178       try {
  179         // This will also close the file. This is OK since multiple
  180         // close operations are safe.
  181         this.setFile(fileName, false, bufferedIO, bufferSize);
  182         nextRollover = 0;
  183       }
  184       catch(IOException e) {
  185         LogLog.error("setFile("+fileName+", false) call failed.", e);
  186       }
  187       }
  188     }
  189   
  190     public
  191     synchronized
  192     void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
  193                                                                    throws IOException {
  194       super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
  195       if(append) {
  196         File f = new File(fileName);
  197         ((CountingQuietWriter) qw).setCount(f.length());
  198       }
  199     }
  200   
  201   
  202     /**
  203        Set the maximum number of backup files to keep around.
  204   
  205        <p>The <b>MaxBackupIndex</b> option determines how many backup
  206        files are kept before the oldest is erased. This option takes
  207        a positive integer value. If set to zero, then there will be no
  208        backup files and the log file will be truncated when it reaches
  209        <code>MaxFileSize</code>.
  210      */
  211     public
  212     void setMaxBackupIndex(int maxBackups) {
  213       this.maxBackupIndex = maxBackups;
  214     }
  215   
  216     /**
  217        Set the maximum size that the output file is allowed to reach
  218        before being rolled over to backup files.
  219   
  220        <p>This method is equivalent to {@link #setMaxFileSize} except
  221        that it is required for differentiating the setter taking a
  222        <code>long</code> argument from the setter taking a
  223        <code>String</code> argument by the JavaBeans {@link
  224        java.beans.Introspector Introspector}.
  225   
  226        @see #setMaxFileSize(String)
  227    */
  228     public
  229     void setMaximumFileSize(long maxFileSize) {
  230       this.maxFileSize = maxFileSize;
  231     }
  232   
  233   
  234     /**
  235        Set the maximum size that the output file is allowed to reach
  236        before being rolled over to backup files.
  237   
  238        <p>In configuration files, the <b>MaxFileSize</b> option takes an
  239        long integer in the range 0 - 2^63. You can specify the value
  240        with the suffixes "KB", "MB" or "GB" so that the integer is
  241        interpreted being expressed respectively in kilobytes, megabytes
  242        or gigabytes. For example, the value "10KB" will be interpreted
  243        as 10240.
  244      */
  245     public
  246     void setMaxFileSize(String value) {
  247       maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);
  248     }
  249   
  250     protected
  251     void setQWForFiles(Writer writer) {
  252        this.qw = new CountingQuietWriter(writer, errorHandler);
  253     }
  254   
  255     /**
  256        This method differentiates RollingFileAppender from its super
  257        class.
  258   
  259        @since 0.9.0
  260     */
  261     protected
  262     void subAppend(LoggingEvent event) {
  263       super.subAppend(event);
  264       if(fileName != null && qw != null) {
  265           long size = ((CountingQuietWriter) qw).getCount();
  266           if (size >= maxFileSize && size >= nextRollover) {
  267               rollOver();
  268           }
  269       }
  270      }
  271   }

Save This Page
Home » SLF4J-1.5.8 » org.apache » log4j » [javadoc | source]