【问题标题】:log4j - How do I include date/time in file names AND delete older logs?log4j - 如何在文件名中包含日期/时间并删除旧日志?
【发布时间】:2012-03-15 19:42:01
【问题描述】:

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

  1. 所有日志文件的文件名中都有日期/时间(例如 myapp.2-28-2012.log)
  2. 只保留最新的日志文件。旧的日志文件被删除,因此硬盘驱动器不会耗尽空间

似乎使用 log4j 我只能获得一个或其他标准,但不能同时获得两者。使用 log4j extras TimeBasedRollingPolicy 我可以获得包含满足 1 的日期/时间的日志文件。但是,似乎没有办法让 TimeBasedRollingPolicy 删除旧的日志文件。根据这个post 不可能让 TimeBasedRollingPolicy 删除旧的日志文件

使用 log4j extras FixedWindowRollingPolicy 和 SizeBasedTriggeringPolicy 我可以让 log4j 删除除最后 10 个日志文件之外的所有文件,这样我的硬盘驱动器就不会用完空间,填满 2。但是我无法获得这个解决方案来放置日期/time 在文件名中。有了这个配置

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 吗?如果是这样,我应该重写哪些方法?

【问题讨论】:

    标签: log4j


    【解决方案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));
    

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

    【讨论】:

      猜你喜欢
      • 2012-02-06
      • 2014-11-17
      • 2010-09-16
      • 2019-04-11
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多