Log4j dailyrollingfileappender文件问题

时间:2011-09-21 13:02:50

标签: java log4j

我们遇到了一个特殊的问题。 场景:我们有3台服务器,它们有一个组件的多个实例都将事务日志写入单个日志文件。我们使用log4j,服务器在Java 1.3中运行。 setAppend()传递为true,实现是DailyRollingFileAppender

问题:在午夜,我们期望当前日志文件以新文件名翻转并开始写入新文件。这在我们的测试设置(单服务器写日志)中运行良好。在生产中,在午夜,新文件将被创建,新文件将被写入,但滚动文件将被删除

任何帮助都将受到高度赞赏,因为它已经过了几天,我们无法获得任何问题的线索。

3 个答案:

答案 0 :(得分:4)

不应该从许多进程登录到同一文件。 Log4j可以是线程安全的,但如果我这么说的话,它不是过程安全的。它不能作为不同java进程之间的共享库。嵌入在一个java应用程序中的Log4j不了解任何其他应用程序。

使用翻转会导致您刚刚发现的问题:所有进程都会运行自己的翻转代码,盲目地覆盖以前的内容(因为他们都没有预期)。

这里有一个可能的解决方案:Log4j Logging to a Shared Log File

答案 1 :(得分:2)

我们遇到了同样的问题。根本问题是没有办法在多个进程之间协调对日志文件的访问(在这种情况下在多个服务器上运行。)这意味着会发生各种不好的事情:日志被覆盖,文件无法滚动等等...... / p>

我的建议是让每个服务器写入一个单独的文件,然后在后处理作业中合并它们。

答案 2 :(得分:2)

假设您已将DailyRollingFileAppender配置为每日轮换(可以配置为每小时,每分钟等轮换)。比如,今天是2014年12月31日,日志文件名是 sample.log 。日志轮换将以下列方式发生:

  • 午夜后收到的第一条日志消息(比如2015年1月1日凌晨1点)将触发日志文件轮换。
  • 日志文件轮换将首先删除前一天后缀的任何现有文件。 (即它将删除名称为 sample-2014-12-31.log 的任何文件。理想情况下,不应存在此类文件。)。
  • 然后它将使用前一天的后缀重命名当前文件。即它将 sample.log 重命名为 sample-2014-12-31.log
  • 它将创建没有后缀的新日志文件。即new sample.log
  • 它将开始写入新文件 sample.log

如果两个Log Manager实例指向同一个日志文件,则每个实例将在同一文件上独立重复上述步骤。这可能发生在以下任何情况中:

  • 如果在同一容器中部署的两个或多个WAR文件指向同一个日志文件。
  • 如果两个或多个进程指向同一个日志文件。

这种情况会导致问题中提到的问题。

  • 在Windows机器上,一旦第一个进程旋转了日志文件并获取了新文件的句柄,第二个日志追加器将无法写入日志。
  • 在Linux机器上,第二个进程将删除第一个进程创建的存档文件,并将新文件(当前正由第一个进程使用)重命名为前一天文件。因此,第一个进程将开始在前一天的文件中写入日志,第二个进程将在新文件中写入日志。午夜过后,第一个进程使用的日志文件将被删除。因此,来自第一个流程的日志将不断丢失。