而是隻計算一次(Tomcat啓動時)的一個簡單的FileAppender
,你應該使用一個RollingFileAppender
,它可以根據滾動策略創建一個新的日誌文件。
使用logback's滾動文件appender。
appender("ROLLING", RollingFileAppender) {
encoder(PatternLayoutEncoder) {
Pattern = "%d %level %thread %mdc %logger - %m%n"
}
rollingPolicy(TimeBasedRollingPolicy) {
FileNamePattern = "$logDirectory/logs/root-%d{yyyy-MM-dd}.zip"
}
}
如果你想使用Log4J,你可以使用DailyRollingFileAppender
。但是默認的實現有一些問題:
DailyRollingFileAppender已經觀察到顯示出同步 問題和數據丟失。 log4j臨時夥伴包括 備選方案,這些備選方案應在新部署中考慮, 在 org.apache.log4j.rolling.RollingFileAppender的文檔中討論。
有一些自定義的實現可用在名稱CustodianDailyRollingFileAppender
您可以使用。這也可以讓你指定要保留的備份文件的數量。而且每天都可以壓縮前一天的日誌文件以節省空間。我不會添加任何特定的鏈接,因爲這可能會在不久的將來打破。相反,我在過去的幾個月裏添加了我們在項目中使用的實現,沒有任何問題。
package org.apache.log4j
import org.apache.log4j.helpers.LogLog
import org.apache.log4j.spi.LoggingEvent
import org.apache.tools.zip.ZipEntry
import org.apache.tools.zip.ZipOutputStream
import java.lang.reflect.Field
import java.text.SimpleDateFormat
class CustodianDailyRollingFileAppender extends DailyRollingFileAppender {
String datePattern = "'.'yyyy-MM-dd"
boolean compress
Integer maxNumberOfDays = 7
/**
* The next time we estimate a rollover should occur.
*/
private long nextCheck = System.currentTimeMillis() - 1
/*
* This method checks to see if we're exceeding the number of log backups
* that we are supposed to keep, and if so, deletes the offending files.
* It then delegates to the rollover method to rollover to a new file if
* required.
*/
protected void cleanupAndRollOver() throws IOException {
File file = new File(fileName)
Calendar cal = Calendar.getInstance()
cal.add(Calendar.DATE, -maxNumberOfDays)
Field field_sdf = DailyRollingFileAppender.getDeclaredField("sdf")
field_sdf.setAccessible(true)
SimpleDateFormat sdf = field_sdf.get(this) as SimpleDateFormat
Date cutoffDate = cal.getTime()
if (file.getParentFile().exists()) {
File[] files = file.getParentFile().listFiles(new StartsWithFileFilter(file.getName(), false))
int nameLength = file.getName().length()
files.each {
File logFile ->
String datePart
try {
datePart = logFile.getName().substring(nameLength)
Date date = sdf.parse(datePart)
if (date.before(cutoffDate)) {
logFile.delete()
} else if (compress) {
zipAndDelete(logFile)
}
}
catch (Exception pe) {
//This isn't a file we should touch (it isn't named correctly)
}
}
}
rollOver()
}
class StartsWithFileFilter implements FileFilter {
private String startsWith
private boolean inclDirs = false
public StartsWithFileFilter(String startsWith, boolean includeDirectories) {
super()
this.startsWith = startsWith.toUpperCase()
inclDirs = includeDirectories
}
public boolean accept(File pathname) {
if (!inclDirs && pathname.isDirectory()) {
return false
} else {
String upperCase = pathname.getName().toUpperCase()
return upperCase.startsWith(startsWith) && upperCase.length() > startsWith.length()
}
}
}
/**
* Compresses the passed file to a .zip file, stores the .zip in the
* same directory as the passed file, and then deletes the original,
* leaving only the .zipped archive.
* @param file
*/
private void zipAndDelete(File file) throws IOException {
if (!file.getName().endsWith(".zip")) {
File zipFile = new File(file.getParent(), file.getName() + ".zip")
FileInputStream fis = new FileInputStream(file)
FileOutputStream fos = new FileOutputStream(zipFile)
ZipOutputStream zos = new ZipOutputStream(fos)
ZipEntry zipEntry = new ZipEntry(file.getName())
zos.putNextEntry(zipEntry)
byte[] buffer = new byte[4096]
while (true) {
int bytesRead = fis.read(buffer)
if (bytesRead == -1) break
else {
zos.write(buffer, 0, bytesRead)
}
}
zos.closeEntry()
fis.close()
zos.close()
file.delete()
}
}
@Override
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis()
Field field_now = DailyRollingFileAppender.getDeclaredField("now")
field_now.setAccessible(true)
Date now = field_now.get(this) as Date
Field field_rc = DailyRollingFileAppender.getDeclaredField("rc")
field_rc.setAccessible(true)
def rc = field_rc.get(this)
if (n >= nextCheck) {
now.setTime(n)
nextCheck = rc.getNextCheckMillis(now)
try {
cleanupAndRollOver()
}
catch (IOException ioe) {
LogLog.error("cleanupAndRollover() failed.", ioe)
}
}
super.subAppend(event)
}
}
並創建一個appender:
appender("ROLLING", CustodianDailyRollingFileAppender) {
file("$logDirectory/logs/root.log")
layout(EnhancedPatternLayout) {
Pattern = "%d %level %thread %mdc %logger - %m%n"
}
maxNumberOfDays(30)
compress(true)
}