I have a logback configured using the RollingFileAppender to rollover to a new log file with the SizeAndTimeBasedFNATP policy. I have it set up to rollover to a new file based on the day or based on the size. At that time, it will also compress the old log into a zip file.
Something like this:
<appender name="xyz" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>%d{yyyy/MM/dd}/log.zip</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
Is there a way to get logback to make a copy of the zipped log at rollover time to a second location? Note that I want to keep one copy in the original location, but copy the file to a second location. (I need to keep the file in the original location for some period of time, but then delete it. The copied file will stay present indefinitely.)
Size-based rolling policy allows to rollover based on file on each log file. For example, we can rollover to a new file when the log file reaches 10 MB in size. The maxFileSize is used to specify the size of each file when it gets rolled over.
prudent. boolean. In prudent mode, FileAppender will safely write to the specified file, even in the presence of other FileAppender instances running in different JVMs, potentially running on different hosts. The default value for prudent mode is false .
The lastest version of logback.qos.ch (1.1. 7) supports the property "totalSizeCap". This property can be used to limit the total size of archived log files. Currently, the top level nifi pom. xml specifies version 1.1.
I figured out a way to do this by extending the TimeBasedRollingPolicy. It feels a bit hackish, but it works. You need to put your new policy class within the ch.qos.logback.core.rolling package because TimeBasedRollingPolicy does not make it easy to override just the functionality needed without being within the package.
public class DuplicatingTimeBasedRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
// root directory of log (so we can retain subdirectory structures in copy)
String originalRoot;
// root directory for secondary log location
String duplicateRoot;
@Override
Future<?> asyncCompress(String nameOfFile2Compress,
String nameOfCompressedFile, String innerEntryName)
throws RolloverFailure {
// Do standard async compression
final Future<?> future = super.asyncCompress(nameOfFile2Compress, nameOfCompressedFile,
innerEntryName);
// Figure out the file name to copy to and from
String extension = compressionMode == CompressionMode.ZIP ? ".zip" : ".gz";
final String sourceFileName = nameOfCompressedFile + extension;
final String destFileName = duplicateRoot + File.separator + sourceFileName.substring(originalRoot.length());
new Thread(new Runnable() {
@Override
public void run() {
try {
// Wait for compression to finish and then make a copy
future.get();
FileUtils.copyFile(new File(sourceFileName), new File(destFileName));
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return future;
}
}
Note that this specifically only works when using compression (zip or gz) at rollover. Could be modified to also work when no compression is used. I'm not sure if this is the best way to handle this. Any better ideas?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With