【问题标题】:How do I make log4j create log files on demand only?如何让 log4j 仅按需创建日志文件?
【发布时间】:2010-04-27 08:50:04
【问题描述】:

我们有一个模块化应用程序,其中模块有自己的 log4j 日志(即通信日志和错误日志)。这些附加程序和类别都在核心 log4j XML 中配置,但并非总是安装所有模块。 DailyRollingFileAppender 无论使用如何都会创建其文件,并且会公开完整的模块集,尽管不存在,并且由于其中一些是客户特定的,我们希望隐藏未使用的日志。 有没有办法让 DailyRollingFileAppender 在首次使用时创建其文件,而不是在启动时自动创建?

【问题讨论】:

  • 为什么不在核心 XML 中排除禁用组件的块?
  • 我们只部署一次 log4j 配置,以后可以添加模块。当我们为本地更改保留 log4j 详细信息时,我们很难在以后的安装中修改文件。是的,我们需要高水平的安装自动化。

标签: log4j


【解决方案1】:

我遇到了同样的问题,所以我扩展了标准 FileAppender 类,并创建了一个新的LazyFileAppender,它是一个延迟初始化日志文件的 FileAppender(仅在第一次写入操作发生时创建)。

LazyFileAppender 和标准 log4j 库的其他一些补充可以在我创建的一个简单库中找到:log4j-additions。

您可以查看源代码来开发自己的扩展,也可以按原样使用它...

【讨论】:

    【解决方案2】:

    文件追加器没有延迟创建日志文件的选项 - 如果文件不存在,setFile 方法会自动创建文件:ostream = new FileOutputStream(fileName, append);

    您必须自己扩展附加程序并覆盖文件初始化代码才能获得您所追求的行为。

    【讨论】:

    • 我很欣赏这个答案有点晚了,但我最近一直在与 Log4j 斗争太多以至于没有留下问题:-)
    【解决方案3】:

    在 Log4j 2 中,FileAppender 和 RollingFileAppender 都有参数“createOnDemand”,可用于配置仅当日志事件传递给 appender 时才创建日志文件。

    例子:

    <RollingFile name="LogFile" fileName="test.log" filePattern="test-%i.log.gz" createOnDemand="true">
        <Policies>
            <SizeBasedTriggeringPolicy size="1MB"/>
        </Policies>
        <DefaultRolloverStrategy max="5"/>
    </RollingFile>
    

    更多详情:https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingRandomAccessFileAppender

    【讨论】:

      【解决方案4】:

      扩展标准 FileAppender 类对我来说是不成功的。因此,我找到了另一种解决方案,它使用附加程序以编程方式仅按需创建日志文件(并且在名称文件中带有时间戳)。我写了这两种方法:

      public void startLog() {
          SimpleDateFormat sdf_long = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
          FileAppender fa = new FileAppender();
          fa.setName("foo");
          fa.setFile(sdf_long.format(new Date()) + ".log");
          fa.setLayout(new PatternLayout("%d{HH:mm:ss.SSS} %m%n"));
          fa.setThreshold(Level.DEBUG);
          fa.setAppend(true);
          fa.activateOptions();
          Logger.getRootLogger().addAppender(fa);
      }
      
      public void stopLog() {
          Logger.getRootLogger().getAppender("foo").close();
          Logger.getRootLogger().removeAppender("foo");
      }
      

      我的 log4j.properties 文件只配置控制台附加程序。当我想开始记录时,我调用 startLog() 方法。当我想登录其他文件时,我先调用 stopLog(),然后调用 startLog() 方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多