log4j - 如何在文件名中包含日期/时间并删除旧日志?

时间:2012-03-15 19:42:01

标签: log4j

我的老板要求我有一个日志记录解决方案

  1. 所有日志文件在文件名中都有日期/时间(例如myapp.2-28-2012.log)
  2. 仅保留最新的日志文件。旧的日志文件被删除,因此硬盘驱动器没有空间不足
  3. 看来log4j我只能得到一个或另一个标准,但不能同时得到两个标准。使用log4j extras TimeBasedRollingPolicy我能够获取日志文件以包含日期/时间,这将满足1.但是,似乎没有办法让TimeBasedRollingPolicy删除旧的日志文件。根据此post,无法使TimeBasedRollingPolicy删除旧的日志文件

    使用log4j附加功能FixedWindowRollingPolicy和SizeBasedTriggeringPolicy我可以让log4j删除除最后10个日志文件以外的所有文件,这样我的硬盘驱动器就不会用完空间,满满的2.但是我无法得到这个解决方案来放置日期/文件名中的时间。使用此配置

    def myAppAppender = new org.apache.log4j.rolling.RollingFileAppender(name: 'myApp', layout: pattern(conversionPattern: "%m%n"))
    def rollingPolicy = new org.apache.log4j.rolling.FixedWindowRollingPolicy(fileNamePattern: '/tmp/myapp-%d{MM-dd-yyyy_HH:mm:ss}.log.%i',maxIndex:10,activeFileName: '/tmp/myapp.log')
    rollingPolicy.activateOptions()
    def triggeringPolicy = new org.apache.log4j.rolling.SizeBasedTriggeringPolicy(maxFileSize:10000000)
    triggeringPolicy.activateOptions()
    eventAppender.setRollingPolicy(rollingPolicy)
    eventAppender.setTriggeringPolicy(triggeringPolicy)
    

    滚动的日志文件不包含日期/时间。他们看起来像这样

    myapp-.log.1
    myapp-.log.2
    ...
    

    是否可以使用log4j满足标准1)和2)?我是否必须继承TimeBasedRollingPolicy?如果是这样,我应该覆盖哪些方法?

1 个答案:

答案 0 :(得分:1)

在Log4j中一般很难做到,但您可以随时根据您的特定需求扩展策略,如下所示。

首先需要将粘贴TimeBasedRollingPolicy源代码复制到新类,例如MyAppDeletingTimeBasedRollingPolicy。 Apache许可允许这样做。

关键部分是根据您的需求实施删除逻辑。下面是我的类,它删除以“myapp-debug”开头并以“gz”结尾并且在3天内未被修改的文件。您可能需要进行其他检查,因此在盲目复制和粘贴代码时要小心。

private static class DeleteOldMyAppLogFilesInDirAction extends ActionBase {

    private static final long MAX_HISTORY = 3l * 24 * 60 * 60 * 1000; //3 days
    private File dir;

    public DeleteOldMyAppLogFilesInDirAction (File dir) {
        this.dir = dir;
    }

    @Override
    public boolean execute() throws IOException {
        for (File f : dir.listFiles()) {
            if (f.getName().startsWith("myapp-debug.") && f.getName().endsWith(".gz")
                    && f.lastModified() < System.currentTimeMillis() - MAX_HISTORY) {
                f.delete();
            }
        }
        return true;
    }

}

然后你需要改变它的返回值:

    return new RolloverDescriptionImpl(nextActiveFile, false, renameAction, compressAction);

对此:

    Action deleteOldFilesAction = new DeleteOldMyAppLogFilesInDirAction (new File(currentActiveFile).getParentFile());
    List<Action> asynchActions = new ArrayList<Action>();
    if (compressAction != null) {
        asynchActions.add(compressAction);
    }
    asynchActions.add(deleteOldFilesAction);

    return new RolloverDescriptionImpl(nextActiveFile, false, renameAction, new CompositeAction(asynchActions, false));

这个类中有一些硬编码的假设,比如文件名和与当前文件位于同一目录中的旧文件,请小心这些假设,并乐意根据自己的需要进行破解。

相关问题