X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Forg%2Fapache%2Flog4j%2FRollingFileAppender.java;fp=srcjar%2Forg%2Fapache%2Flog4j%2FRollingFileAppender.java;h=9cfacc6b75a89ddc75f6805092d9a8c81581d671;hb=2d6292c0377bc6b773c6844a45d3f2c5fac352c7;hp=0000000000000000000000000000000000000000;hpb=954af328a2a6a0055572cd1a09ee035301222574;p=jalview.git diff --git a/srcjar/org/apache/log4j/RollingFileAppender.java b/srcjar/org/apache/log4j/RollingFileAppender.java new file mode 100644 index 0000000..9cfacc6 --- /dev/null +++ b/srcjar/org/apache/log4j/RollingFileAppender.java @@ -0,0 +1,285 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +package org.apache.log4j; + +import java.io.IOException; +import java.io.Writer; +import java.io.File; +import java.io.InterruptedIOException; + +import org.apache.log4j.helpers.OptionConverter; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.CountingQuietWriter; +import org.apache.log4j.spi.LoggingEvent; + +/** + RollingFileAppender extends FileAppender to backup the log files when + they reach a certain size. + + The log4j extras companion includes alternatives which should be considered + for new deployments and which are discussed in the documentation + for org.apache.log4j.rolling.RollingFileAppender. + + + @author Heinz Richter + @author Ceki Gülcü + +*/ +public class RollingFileAppender extends FileAppender { + + /** + The default maximum file size is 10MB. + */ + protected long maxFileSize = 10*1024*1024; + + /** + There is one backup file by default. + */ + protected int maxBackupIndex = 1; + + private long nextRollover = 0; + + /** + The default constructor simply calls its {@link + FileAppender#FileAppender parents constructor}. */ + public + RollingFileAppender() { + super(); + } + + /** + Instantiate a RollingFileAppender and open the file designated by + filename. The opened filename will become the ouput + destination for this appender. + +

If the append parameter is true, the file will be + appended to. Otherwise, the file desginated by + filename will be truncated before being opened. + */ + public + RollingFileAppender(Layout layout, String filename, boolean append) + throws IOException { + super(layout, filename, append); + } + + /** + Instantiate a FileAppender and open the file designated by + filename. The opened filename will become the output + destination for this appender. + +

The file will be appended to. */ + public + RollingFileAppender(Layout layout, String filename) throws IOException { + super(layout, filename); + } + + /** + Returns the value of the MaxBackupIndex option. + */ + public + int getMaxBackupIndex() { + return maxBackupIndex; + } + + /** + Get the maximum size that the output file is allowed to reach + before being rolled over to backup files. + + @since 1.1 + */ + public + long getMaximumFileSize() { + return maxFileSize; + } + + /** + Implements the usual roll over behaviour. + +

If MaxBackupIndex is positive, then files + {File.1, ..., File.MaxBackupIndex -1} + are renamed to {File.2, ..., + File.MaxBackupIndex}. Moreover, File is + renamed File.1 and closed. A new File is + created to receive further log output. + +

If MaxBackupIndex is equal to zero, then the + File is truncated with no backup files created. + + */ + public // synchronization not necessary since doAppend is alreasy synched + void rollOver() { + File target; + File file; + + if (qw != null) { + long size = ((CountingQuietWriter) qw).getCount(); + LogLog.debug("rolling over count=" + size); + // if operation fails, do not roll again until + // maxFileSize more bytes are written + nextRollover = size + maxFileSize; + } + LogLog.debug("maxBackupIndex="+maxBackupIndex); + + boolean renameSucceeded = true; + // If maxBackups <= 0, then there is no file renaming to be done. + if(maxBackupIndex > 0) { + // Delete the oldest file, to keep Windows happy. + file = new File(fileName + '.' + maxBackupIndex); + if (file.exists()) { + renameSucceeded = file.delete(); + } + + // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} + for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) { + file = new File(fileName + "." + i); + if (file.exists()) { + target = new File(fileName + '.' + (i + 1)); + LogLog.debug("Renaming file " + file + " to " + target); + renameSucceeded = file.renameTo(target); + } + } + + if(renameSucceeded) { + // Rename fileName to fileName.1 + target = new File(fileName + "." + 1); + + this.closeFile(); // keep windows happy. + + file = new File(fileName); + LogLog.debug("Renaming file " + file + " to " + target); + renameSucceeded = file.renameTo(target); + // + // if file rename failed, reopen file with append = true + // + if (!renameSucceeded) { + try { + this.setFile(fileName, true, bufferedIO, bufferSize); + } + catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("setFile("+fileName+", true) call failed.", e); + } + } + } + } + + // + // if all renames were successful, then + // + if (renameSucceeded) { + try { + // This will also close the file. This is OK since multiple + // close operations are safe. + this.setFile(fileName, false, bufferedIO, bufferSize); + nextRollover = 0; + } + catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.error("setFile("+fileName+", false) call failed.", e); + } + } + } + + public + synchronized + void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) + throws IOException { + super.setFile(fileName, append, this.bufferedIO, this.bufferSize); + if(append) { + File f = new File(fileName); + ((CountingQuietWriter) qw).setCount(f.length()); + } + } + + + /** + Set the maximum number of backup files to keep around. + +

The MaxBackupIndex option determines how many backup + files are kept before the oldest is erased. This option takes + a positive integer value. If set to zero, then there will be no + backup files and the log file will be truncated when it reaches + MaxFileSize. + */ + public + void setMaxBackupIndex(int maxBackups) { + this.maxBackupIndex = maxBackups; + } + + /** + Set the maximum size that the output file is allowed to reach + before being rolled over to backup files. + +

This method is equivalent to {@link #setMaxFileSize} except + that it is required for differentiating the setter taking a + long argument from the setter taking a + String argument by the JavaBeans {@link + java.beans.Introspector Introspector}. + + @see #setMaxFileSize(String) + */ + public + void setMaximumFileSize(long maxFileSize) { + this.maxFileSize = maxFileSize; + } + + + /** + Set the maximum size that the output file is allowed to reach + before being rolled over to backup files. + +

In configuration files, the MaxFileSize option takes an + long integer in the range 0 - 2^63. You can specify the value + with the suffixes "KB", "MB" or "GB" so that the integer is + interpreted being expressed respectively in kilobytes, megabytes + or gigabytes. For example, the value "10KB" will be interpreted + as 10240. + */ + public + void setMaxFileSize(String value) { + maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1); + } + + protected + void setQWForFiles(Writer writer) { + this.qw = new CountingQuietWriter(writer, errorHandler); + } + + /** + This method differentiates RollingFileAppender from its super + class. + + @since 0.9.0 + */ + protected + void subAppend(LoggingEvent event) { + super.subAppend(event); + if(fileName != null && qw != null) { + long size = ((CountingQuietWriter) qw).getCount(); + if (size >= maxFileSize && size >= nextRollover) { + rollOver(); + } + } + } +}