我已经使用 log4j 的滚动策略来压缩达到一定大小的文件。下面的 log4j 属性工作正常。
log4j.appender.FILE=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.FILE.rollingPolicy=org.apache.log4j.rolling.FixedWindowRollingPolicy
log4j.appender.FILE.rollingPolicy.maxIndex=13
log4j.appender.FILE.triggeringPolicy=org.apache.log4j.rolling.SizeBasedTriggeringPolicy
log4j.appender.FILE.triggeringPolicy.MaxFileSize=80
log4j.appender.FILE.rollingPolicy.FileNamePattern=log/projectlog_${current.date.time}.%i.log.gz
log4j.appender.FILE.rollingPolicy.ActiveFileName=log/project_log_${current.date.time}.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%m%n
Run Code Online (Sandbox Code Playgroud)
但这里的问题是在生成压缩文件后,它还使用 gz 文件的名称重命名压缩 gz 文件中存在的文件。
对于我的场景,我不希望 log4j 重命名压缩的 gz 存档中存在的文件。有什么方法可以限制 log4j 不更改它正在压缩的文件名。
您不能使用 log4j @UmarTahir 提供的代码。
正如您在该类的源代码中看到的FixedWindowRollingPolicy,在实际处理 的方法中rollover,它们首先指示RollingFileAppender 同步重命名文件,然后在必要时异步压缩它:
public RolloverDescription rollover(final String currentFileName) {
if (maxIndex >= 0) {
int purgeStart = minIndex;
if (!explicitActiveFile) {
purgeStart++;
}
if (!purge(purgeStart, maxIndex)) {
return null;
}
StringBuffer buf = new StringBuffer();
formatFileName(new Integer(purgeStart), buf);
String renameTo = buf.toString();
String compressedName = renameTo;
Action compressAction = null;
if (renameTo.endsWith(".gz")) {
renameTo = renameTo.substring(0, renameTo.length() - 3);
compressAction =
new GZCompressAction(
new File(renameTo), new File(compressedName), true);
} else if (renameTo.endsWith(".zip")) {
renameTo = renameTo.substring(0, renameTo.length() - 4);
compressAction =
new ZipCompressAction(
new File(renameTo), new File(compressedName), true);
}
FileRenameAction renameAction =
new FileRenameAction(
new File(currentFileName), new File(renameTo), false);
return new RolloverDescriptionImpl(
currentFileName, false, renameAction, compressAction);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
返回的结果RolloverDescription将在方法中使用来处理实际的翻转过程:RollingFileAppender rollover
public boolean rollover() {
//
// can't roll without a policy
//
if (rollingPolicy != null) {
Exception exception = null;
synchronized (this) {
//
// if a previous async task is still running
//}
if (lastRolloverAsyncAction != null) {
//
// block until complete
//
lastRolloverAsyncAction.close();
//
// or don't block and return to rollover later
//
//if (!lastRolloverAsyncAction.isComplete()) return false;
}
try {
RolloverDescription rollover = rollingPolicy.rollover(getFile());
if (rollover != null) {
if (rollover.getActiveFileName().equals(getFile())) {
closeWriter();
boolean success = true;
if (rollover.getSynchronous() != null) {
success = false;
try {
success = rollover.getSynchronous().execute();
} catch (Exception ex) {
exception = ex;
}
}
if (success) {
if (rollover.getAppend()) {
fileLength = new File(rollover.getActiveFileName()).length();
} else {
fileLength = 0;
}
if (rollover.getAsynchronous() != null) {
lastRolloverAsyncAction = rollover.getAsynchronous();
new Thread(lastRolloverAsyncAction).start();
}
setFile(
rollover.getActiveFileName(), rollover.getAppend(),
bufferedIO, bufferSize);
} else {
setFile(
rollover.getActiveFileName(), true, bufferedIO, bufferSize);
if (exception == null) {
LogLog.warn("Failure in post-close rollover action");
} else {
LogLog.warn(
"Exception in post-close rollover action", exception);
}
}
} else {
Writer newWriter =
createWriter(
createFileOutputStream(
rollover.getActiveFileName(), rollover.getAppend()));
closeWriter();
setFile(rollover.getActiveFileName());
this.qw = createQuietWriter(newWriter);
boolean success = true;
if (rollover.getSynchronous() != null) {
success = false;
try {
success = rollover.getSynchronous().execute();
} catch (Exception ex) {
exception = ex;
}
}
if (success) {
if (rollover.getAppend()) {
fileLength = new File(rollover.getActiveFileName()).length();
} else {
fileLength = 0;
}
if (rollover.getAsynchronous() != null) {
lastRolloverAsyncAction = rollover.getAsynchronous();
new Thread(lastRolloverAsyncAction).start();
}
}
writeHeader();
}
return true;
}
} catch (Exception ex) {
exception = ex;
}
}
if (exception != null) {
LogLog.warn(
"Exception during rollover, rollover deferred.", exception);
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
FixedWindowRollingPolicy如果您需要这种特殊行为,也许您可以创建自己的滚动策略,并尝试以最适合您的要求的方式实现与 中所做的类似的操作,并配置 log4j 以使用这个新的滚动策略。
话虽如此,请注意,gzip 意味着只是压缩数据,没有实际的文件名或文件条目,只是压缩的数据。如果您使用该gzip工具,它会使用存档的名称来压缩、压缩数据,并将结果存储在带有后缀(通常为.gz. 这是 log4j 试图在其代码中模仿的行为。