org.apache.hadoop.hive.ql.log.NoDeleteRollingFileAppender Maven / Gradle / Ivy
/**
* 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.hadoop.hive.ql.log;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.Writer;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;
public class NoDeleteRollingFileAppender extends FileAppender {
/**
* The default maximum file size is 10MB.
*/
protected long maxFileSize = 10 * 1024 * 1024;
private long nextRollover = 0;
/**
* The default constructor simply calls its {@link FileAppender#FileAppender
* parents constructor}.
*/
public NoDeleteRollingFileAppender() {
}
/**
* Instantiate a RollingFileAppender and open the file designated by
* filename
. The opened filename will become the output
* destination for this appender.
*
* If the append
parameter is true, the file will be appended to.
* Otherwise, the file designated by filename
will be truncated
* before being opened.
*/
public NoDeleteRollingFileAppender(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 NoDeleteRollingFileAppender(Layout layout, String filename)
throws IOException {
super(layout, filename);
}
/**
* Get the maximum size that the output file is allowed to reach before being
* rolled over to backup files.
*/
public long getMaximumFileSize() {
return maxFileSize;
}
/**
* Implements the usual roll over behavior.
*
* File
is renamed File.yyyyMMddHHmmss
and closed. A
* new File
is created to receive further log output.
*/
// synchronization not necessary since doAppend is already synced
public void rollOver() {
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;
}
this.closeFile(); // keep windows happy.
int p = fileName.lastIndexOf(".");
String file = p > 0 ? fileName.substring(0, p) : fileName;
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(file, false, bufferedIO, bufferSize);
nextRollover = 0;
} catch (IOException e) {
if (e instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
LogLog.error("setFile(" + file + ", false) call failed.", e);
}
}
public synchronized void setFile(String fileName, boolean append,
boolean bufferedIO, int bufferSize) throws IOException {
String newFileName = getLogFileName(fileName);
super.setFile(newFileName, append, this.bufferedIO, this.bufferSize);
if (append) {
File f = new File(newFileName);
((CountingQuietWriter) qw).setCount(f.length());
}
}
/**
* 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.
*/
protected void subAppend(LoggingEvent event) {
super.subAppend(event);
if (fileName != null && qw != null) {
long size = ((CountingQuietWriter) qw).getCount();
if (size >= maxFileSize && size >= nextRollover) {
rollOver();
}
}
}
// Mangled file name. Append the current timestamp
private static String getLogFileName(String oldFileName) {
return oldFileName + "." + Long.toString(System.currentTimeMillis());
}
}