log4j2 中基于时间的触发策略

Posted

技术标签:

【中文标题】log4j2 中基于时间的触发策略【英文标题】:Time based triggering policy in log4j2 【发布时间】:2013-10-18 17:00:49 【问题描述】:

我正在尝试每小时创建新的日志文件。我在 RollingFileAppender 中使用 lo4j2 的 TimeBasedTriggerringPolicy。以下是我从 log4j2 官方网站获取的示例 xml 配置代码。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
   <Appenders>
      <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$$date:yyyy-MM/app-%dyyyy-MM-dd-HH-%i.log.gz">
         <PatternLayout>
            <Pattern>%d %p %c1. [%t] %m%n</Pattern>
         </PatternLayout>
         <Policies>
            **
            <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            **
            <SizeBasedTriggeringPolicy size="250 MB" />
         </Policies>
      </RollingFile>
   </Appenders>
   <Loggers>
      <Root level="error">
         <AppenderRef ref="RollingFile" />
      </Root>
   </Loggers>
</Configuration>

在间隔属性中,我设置了 1,表示 1 小时。 但我的文件仍然不是每 1 小时滚动一次。

请帮我找出任何错误。

注意:我已经包含了 log4j2 的 beta9(这是最新的)

【问题讨论】:

【参考方案1】:

您确实有一个非空的日志文件(否则没有什么可以翻转)?

请注意,即使名称是“TimeBased...”,它实际上也不会在指定时间翻转,而是在超过时间阈值后到达的第一个日志事件时翻转。您可以尝试使用一个在 61 分钟左右后记录某些内容的小型测试程序,看看问题是否仍然存在?

如果上面的测试程序没有翻转,你可能发现了一个错误。在这种情况下,请在 log4j 问题跟踪器上提出它。 (请务必附上团队可以用来重现问题的测试程序。

【讨论】:

【参考方案2】:

这里的 1 表示 1 天而不是 1 小时。我已经手动测试了以下配置。

<RollingFile name="T" fileName="/data_test/log/abc.log"
        filePattern="/data_test/log/abc-%dMM-dd-yyyy-%i.log">
        <PatternLayout>
            <Pattern>%dISO8601 %-5p [%t] (%F:%L) - %m%n</Pattern>
        </PatternLayout>
        <Policies>              
            <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            <SizeBasedTriggeringPolicy size="100 KB" />
        </Policies>
    </RollingFile>

对于手动测试,我更改了系统日期和时间。 首先,尝试增加 1 小时。将生成日志文件,但与预期不同。 然后更改系统日期,增加1天,然后查看结果。

假设第 29 天至 10 月的最后一个日志文件 (abc.log) 大小为 50 KB。配置大小为 100 KB。如果我们更改日期(增加 1 天)然后运行。 然后,最后一个文件将重命名为 29-Oct-(一些序列号).log(复制时为 50 KB 文件),并将使用 abc.log 创建新文件

我已经在 web.xml 中使用以下配置的简单 servlet 进行了尝试

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>log4j2.xml</param-value>
</context-param>

将 log4j2.xml 保存在 src 文件夹中。如果我们将 log4j2.xml 保存在类路径中,则不会加载它。

【讨论】:

interval = 根据日期模式中最具体的时间单位,应该多久发生一次翻转。例如,对于以小时为最具体项目的日期模式,并且每 4 小时将发生 4 次翻转的增量。默认值为 1。因此,如果您有类似“yyyy-MM-dd-HH”的模式,则文件将每小时滚动一次,如果是“yyyy-MM-dd”,则文件将每天滚动一次。 我能问一下文件模式中的 %i 替换了什么 我相信如果您基于日志文件大于大小限制而不是时间而翻转,%i 将会增加。 如果我们需要根据特定时间翻转活动文件(例如:logs/app.log),那么需要更改哪些配置?。【参考方案3】:

正如 Abid 所提到的,区间值是在作为 filePattern 的一部分指定的模式的上下文中解释的。它从最低面额开始。例如,如果模式包含 S,则频率将以毫秒为单位。它支持作为 SimpleDateFormat java doc http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html 的一部分详细描述的日期模式

【讨论】:

【参考方案4】:

Log4jdocumentations:

interval -> (integer) 基于最 日期模式中的特定时间单位。例如,带有日期 以小时为最具体的项目并且增量为 4 的模式 翻转将每 4 小时发生一次。默认值为 1。

如果您想每小时创建一次,您应该更改文件名模式。

【讨论】:

如果我们需要根据特定时间翻转活动文件(例如:logs/app.log),那么需要更改哪些配置?。【参考方案5】:

根据您的 TimeBasedTriggeringPolicy 配置,记录器只会每天而不是每小时填充日志。 AFAIK,您可以通过将 filePattern 从 HH(Hours) 更改为 dd(Days) 来实现该功能。

我已经修改了你的 config.xml。试试这个

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
   <Appenders>
      <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/$$date:yyyy-MM/app-%dyyyy-MM-dd-%i.log.gz">
         <PatternLayout>
            <Pattern>%d %p %c1. [%t] %m%n</Pattern>
         </PatternLayout>
         <Policies>
            **
            <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            **
            <SizeBasedTriggeringPolicy size="250 MB" />
         </Policies>
      </RollingFile>
   </Appenders>
   <Loggers>
      <Root level="error">
         <AppenderRef ref="RollingFile" />
      </Root>
   </Loggers>
</Configuration>

更多详情请查看this

希望这也能锻炼你。

【讨论】:

【参考方案6】:

时间间隔解释取决于您使用的文件模式。以下配置为我每秒滚动文件。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
            <Console name="A" target="SYSTEM_OUT">
                    <PatternLayout pattern="%d [%t] %-5p %F:%L %x - %m%n" />
                    <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Console>

            <RollingFile name="R"
                    fileName="/home/xxx/yyy/myapp.log" filePattern="/home/xxx/yyy/myapp-%dyyyy-MM-dd-HH-mm-ss-%i.log">
                    <PatternLayout pattern="%d [%t] %-5p %F:%L %x - %m%n" />
                    <Policies>
                            <TimeBasedTriggeringPolicy interval="1" />
                    </Policies>
            </RollingFile>
    </Appenders>


    <Loggers>
            <Root level="INFO">
                    <AppenderRef ref="A" />
                    <AppenderRef ref="R" />
            </Root>
    </Loggers>
</Configuration>

【讨论】:

以上是关于log4j2 中基于时间的触发策略的主要内容,如果未能解决你的问题,请参考以下文章

无法使用TimeBasedTriggeringPolicy存档log4j2中的最后一天日志文件

Apache Log4j2远程代码执行漏洞

Log4j2远程执行代码漏洞如何攻击? 又如何修复

Log4j2漏洞复现(CVE-2021-44228)

大数据组件Log4j2漏洞升级

如何在 log4j2 中每次服务器关闭时轮换日志