使用Grails记录今天的日期文件

时间:2016-02-12 12:45:24

标签: grails

我正在尝试登录文件root.$date.log,其中date是提交日志的日期。

现在我创建了这个appender,但我遇到的问题是timestamp只被评估一次(当Tomcat启动时)

appender("STDOUT", FileAppender) {

    file = "$logDirectory/logs/root.${timestamp("yyyy-MM-dd")}.log"
    append = true
    encoder(PatternLayoutEncoder) {
        pattern = loggerPattern
    }
}

PS 我正在使用Grails 3.0.x

1 个答案:

答案 0 :(得分:2)

而不是简单的FileAppender,您应该使用RollingFileAppender,它可以根据滚动策略创建新的日志文件。

使用logback's滚动文件追加器。

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 extras伴侣包括   新部署应考虑的替代方案,以及哪些方案   在文档中讨论   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)
}