API已更改(例如,setMaxFileSize不再存在),上面的很多东西似乎都不起作用,但是我有一些针对logback 1.1.8(此时最新版本)的工作内容。
我想在启动时滚动并按大小滚动,但不是按时间滚动。这样做:
public class RollOnStartupAndSizeTriggeringPolicy<E> extends SizeBasedTriggeringPolicy<E> {
private final AtomicBoolean firstTime = new AtomicBoolean();
public boolean isTriggeringEvent(final File activeFile, final E event) {
if (firstTime.compareAndSet(false, true) && activeFile != null && activeFile.length() > 0) {
return true;
}
return super.isTriggeringEvent(activeFile, event);
}
}
这样你还需要一个滚动策略。FixedWindowRollingPolicy可能会起作用,但我不喜欢它,因为我想保留大量的文件,但对于那些来说它效率非常低下。一些按数字递增的东西(而不是像FixedWindow那样滑动)可能有效,但这不存在。只要我在编写自己的内容,我决定使用时间而不是计数。我想扩展当前的logback代码,但对于基于时间的内容,滚动和触发策略通常结合成一个类,并且有很多嵌套和循环的东西以及没有getter的字段,所以我发现这相当不可能。因此,我必须从头开始做很多工作。我将它保持简单,没有实现压缩等功能-虽然我很想拥有它们,但我只是试图保持简单。
public class TimestampRollingPolicy<E> extends RollingPolicyBase {
private final RenameUtil renameUtil = new RenameUtil();
private String activeFileName;
private String fileNamePatternStr;
private FileNamePattern fileNamePattern;
@Override
public void start() {
super.start();
renameUtil.setContext(this.context);
activeFileName = getParentsRawFileProperty();
if (activeFileName == null || activeFileName.isEmpty()) {
addError("No file set on appender");
}
if (fileNamePatternStr == null || fileNamePatternStr.isEmpty()) {
addError("fileNamePattern not set");
fileNamePattern = null;
} else {
fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
}
addInfo("Will use the pattern " + fileNamePattern + " to archive files");
}
@Override
public void rollover() throws RolloverFailure {
File f = new File(activeFileName);
if (!f.exists()) {
return;
}
if (f.length() <= 0) {
return;
}
try {
String archiveFileName = fileNamePattern.convert(new Date(f.lastModified()));
renameUtil.rename(activeFileName, archiveFileName);
} catch (RolloverFailure e) {
throw e;
} catch (Exception e) {
throw new RolloverFailure(e.toString(), e);
}
}
@Override
public String getActiveFileName() {
return activeFileName;
}
public void setFileNamePattern(String fnp) {
fileNamePatternStr = fnp;
}
}
然后配置看起来像这样
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<file>/tmp/monitor.log</file>
<rollingPolicy class="my.log.TimestampRollingPolicy">
<fileNamePattern>/tmp/monitor.%d{yyyyMMdd-HHmmss}.log</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="my.log.RollOnStartupAndSizeTriggeringPolicy">
<maxFileSize>1gb</maxFileSize>
</triggeringPolicy>
</appender>
如果您感到沮丧,因为这个问题还没有得到本地解决,请在以下网址投票支持它:
http://jira.qos.ch/browse/LOGBACK-204
http://jira.qos.ch/browse/LOGBACK-215
多年过去了,对我来说这是绝对关键的功能,尽管我知道许多其他框架也无法做到这一点。
TimeBasedFileNamingAndTriggeringPolicy
会导致您选择的类被实例化,但稍后会被另一个实例覆盖。即使使用@NoAutoStart
注释标记了start
,也不会调用。我将发布我的解决方案。 - Dico