81,114
社区成员
发帖
与我相关
我的任务
分享
public// synchronization not necessary since doAppend is alreasy synched
void rollOverOfRolling()
{
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)
{
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)
{
LogLog.error("setFile(" + fileName + ", false) call failed.", e);
}
}
}
/** (non-Javadoc)
* @see org.apache.log4j.FileAppender#setFile(java.lang.String, boolean, boolean, int)
* @param fileName String
* @param append boolean
* @param bufferedIO boolean
* @param bufferSize int
* @throws IOException IOException
*/
@Override
public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
throws IOException
{
// 父类FileAppender.setFile方法存在bug(log4j-1.2.6)。在log4j-1.2.15中修改为以下代码
// super.setFile(fileName, append, bufferedIO, bufferSize)
// -------------from log4j1.2.15---------------start
LogLog.debug("setFile called: " + fileName + ", " + append);
// It does not make sense to have immediate flush and bufferedIO.
if (bufferedIO)
{
setImmediateFlush(false);
}
reset();
FileOutputStream ostream = null;
try
{
//
// attempt to create file
//
ostream = new FileOutputStream(fileName, append);
}
catch (FileNotFoundException ex)
{
//
// if parent directory does not exist then
// attempt to create it and try to create file
// see bug 9150
//
String parentName = new File(fileName).getParent();
if (parentName != null)
{
File parentDir = new File(parentName);
if (!parentDir.exists() && parentDir.mkdirs())
{
ostream = new FileOutputStream(fileName, append);
}
else
{
throw ex;
}
}
else
{
throw ex;
}
}
Writer fw = createWriter(ostream);
if (bufferedIO)
{
fw = new BufferedWriter(fw, bufferSize);
}
this.setQWForFiles(fw);
this.fileName = fileName;
this.fileAppend = append;
this.bufferedIO = bufferedIO;
this.bufferSize = bufferSize;
writeHeader();
LogLog.debug("setFile ended");
// -----------------------------------------end
if (append)
{
File f = new File(fileName);
((CountingQuietWriter)qw).setCount(f.length());
}
}
/**
* Set the maximum number of backup files to keep around.
*
* <p>
* The <b>MaxBackupIndex</b> 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 <code>MaxFileSize</code>.
* @param maxBackups int
*/
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.
*
* <p>
* This method is equivalent to {@link #setMaxFileSize} except that it is
* required for differentiating the setter taking a <code>long</code>
* argument from the setter taking a <code>String</code> argument by the
* JavaBeans {@link java.beans.Introspector Introspector}.
*
* @see #setMaxFileSize(String)
* @param mFileSize Long
*/
public void setMaximumFileSize(long mFileSize)
{
this.maxFileSize = mFileSize;
}
/**
* Set the maximum size that the output file is allowed to reach before
* being rolled over to backup files.
*
* <p>
* In configuration files, the <b>MaxFileSize</b> 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.
* @param value String
*/
public void setMaxFileSize(String value)
{
maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);
}
@Override
protected void setQWForFiles(Writer writer)
{
this.qw = new CountingQuietWriter(writer, errorHandler);
}
/**
* This method differentiates RollingFileAppender from its super class.
*
* @since 0.9.0
* @param event LoggingEvent
*/
@Override
protected void subAppend(LoggingEvent event)
{
//按日期方式备份
super.subAppend(event);
//文件大小方式备份
if (fileName != null && qw != null)
{
long size = ((CountingQuietWriter)qw).getCount();
if (size >= maxFileSize && size >= nextRollover)
{
rollOverOfRolling();
}
}
}
/**
* get suffix
* @return the suffix
*/
public String getSuffix()
{
return suffix;
}
/**
* set suffix
* @param suffix the suffix to set
*/
public void setSuffix(String suffix)
{
this.suffix = suffix;
}
}
public class CustomDailyRollingFileAppender extends DailyRollingFileAppender
{
/**
* file separator
*/
public static final String FILE_SEPARATOR = System.getProperty("file.separator");
/**
* The default maximum file size is 10MB.
*/
public static final int DEFAULT_MAXFILE_SIZE = 10;
/**
* 1024
*/
public static final int NUMBER_1024 = 1024;
/**
* Content of scheduledFilename
*/
private String scheduledFilename;
/**
* The date pattern. By default, the pattern is set to
* "yyyy-MM-dd" meaning daily rollover.
*/
private String datePattern = "yyyy-MM-dd";
/**
* The file suffix. By default, the suffix is ".txt".
*/
private String suffix = ".txt";
/**
* The default maximum file size is 10MB.
*/
private long maxFileSize = DEFAULT_MAXFILE_SIZE * NUMBER_1024 * NUMBER_1024;
/**
* There is one backup file by default.
*/
private int maxBackupIndex = 1;
/**
* Content of note
*/
private long nextRollover = 0;
/**
* Returns the value of the <b>MaxBackupIndex</b> option.
* @return maxBackupIndex
*/
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
* @return maxFileSize
*/
public long getMaximumFileSize()
{
return maxFileSize;
}
/** (non-Javadoc)
* @see org.apache.log4j.FileAppender#setFile(java.lang.String)
* @param file String
*/
@Override
public void setFile(String file)
{
// Trim spaces from both ends. The users probably does not want
// trailing spaces in file names.
String val = file.trim();
sdf = new SimpleDateFormat(datePattern);
String dateName = sdf.format(new Date());
// directory name
String dirName = val + dateName;
File fdir = new File(dirName);
if (!fdir.exists())
{
//创建目录
boolean flag = fdir.mkdirs();
if (!flag)
{
LogLog.error("CustomDailyRollingFileAppender.setFile mkdir[" + dirName + "] Error!");
}
}
StringBuffer buf = new StringBuffer();
buf.append(dirName).append(FILE_SEPARATOR).append(dateName).append(suffix);
fileName = buf.toString();
}
/** (non-Javadoc)
* @see org.apache.log4j.DailyRollingFileAppender#activateOptions()
*/
@Override
public void activateOptions()
{
super.activateOptions();
if (datePattern != null && fileName != null)
{
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rc.setType(type);
// file = logs/2009-12-26/2009-12-26.txt
File file = new File(fileName);
// scheduledFilename = logs/2009-12-27
scheduledFilename =
new File(file.getParentFile().getParentFile(), sdf.format(new Date(file.lastModified()))).getPath();
}
else
{
LogLog.error("Either File or DatePattern options are not set for appender [" + name + "].");
}
}
/**
* Rollover the current file to a new file.
*/
@Override
void rollOver()
throws IOException
{
/* Compute filename, but only if datePattern is specified */
if (datePattern == null)
{
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
// file = logs/2009-12-26/
File file = new File(fileName).getParentFile();
String nowDate = sdf.format(now);
// logs/[sysdate]/
File nowFileDir = new File(file.getParentFile(), nowDate);
String datedFilename = nowFileDir.getPath();
// String datedFilename = fileName + sdf.format(now);
// It is too early to roll over because we are still within the
// bounds of the current interval. Rollover will occur once the
// next interval is reached.
if (scheduledFilename.equals(datedFilename))
{
return;
}
// close current file
this.closeFile();
try
{
// This will also close the file. This is OK since multiple
// close operations are safe.
// this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
File currentF = new File(nowFileDir, nowDate + suffix);
this.setFile(currentF.getPath(), false, this.bufferedIO, this.bufferSize);
}
catch (IOException e)
{
errorHandler.error("setFile(" + fileName + ", false) call failed.");
}
scheduledFilename = datedFilename;
}