为什么 JBoss 和 Logrotate 会创建充满 NUL 字符的日志文件?

Ben*_*ams 7 rhel4 jboss logrotate log4j

我已经设置了 Logrotate 来每晚轮换我的 JBoss Application Server 4.2.2.GA 日志。在轮换日志文件并且 JBoss 再次开始写入它们之后,新日志文件以与前一个日志文件中的字符一样多的 NUL 字符开头,然后是新的日志消息。例如,如果 JBoss server.log 文件的长度为 5000 字节,那么在轮换后,新的 server.log 文件将以 5000 个 NUL 字符开头。几天后,server.log 以 NUL 字符开始,相当于前几天所有日志文件中字符的总和。似乎 JBoss 正在记住它在日志文件中的位置,并在截断的文件中从它停止的地方开始。这是我的 JBoss 的 logrotate 配置:

/apps/jboss-4.2.2.GA/server/default/log/*log {
    daily
    rotate 30
    compress
    notifempty
    copytruncate
    missingok
    nocreate
}
Run Code Online (Sandbox Code Playgroud)

我无法每晚重新启动 JBoss,因为那会导致停机时间过长。我也不能使用 log4j DailyRollingFileAppender,因为它不会删除旧的日志文件。有没有人让 logrotate 与 JBoss 一起正常工作?

小智 7

对于由 log4j 写入的文件,我们遇到了同样的问题。解决方案是将 FileAppender 的属性“Append”设置为“true”。在此更改之后,我们还没有看到在由 logrotate 等外部程序旋转时具有 NUL 的文件的问题。


Gus*_*uss 5

根据我的经验 - 我们不将 logrotate 与 Log4j 一起使用的原因是 logrotate 的工作方式是它重命名文件,然后指示程序关闭其日志并使用旧文件名(不再存在)重新打开它们),通常使用 HUP 信号。

但是不能告诉 Log4j 重新打开它的日志文件,所以我看到你copytruncate用来复制文件 - 问题是 Log4j 使用缓冲写入器来跟踪正在写入的文件的当前位置以及何时截断日志文件 log4j 从截断之前停止写入的位置继续写入。根据您的文件系统实现,这应该会创建“有漏洞的文件”——即您在那里看到的 NULL 字符实际上并不存在——该文件实际上只与实际数据一样大,而 NULL 字符是您的查看器表示的方式洞。另一方面,某些文件系统不支持空洞,并且在 Log4j 恢复写入时确实会用 NULL 字符填充文件。

我建议 - 不要使用 logrotate,通过使用 RollingFileAppender(支持删除旧文件)或使用 DailyRollingFileAppender 和从外部删除旧文件的 cronjob 找到某种方法来旋转 Log4j 中的文件(因为它本来是要完成的) )。