Java Log4j DailRollingFileAppender文件问题

Java Log4j DailRollingFileAppender文件问题,java,log4j,Java,Log4j,我们遇到了一个特殊的问题。 场景:我们有3台服务器,其中包含一个组件的多个实例,所有这些服务器都将事务日志写入一个日志文件。setAppend()传递为true,实现为DailRollingFileAppender 问题:在午夜,我们希望当前日志文件以新文件名滚动并开始写入新文件。这在我们的测试设置(单服务器写入日志)中运行良好。在生产中,在午夜,新文件被创建,新的日志被写入,但滚动文件被删除 如果您有任何帮助,我们将不胜感激,因为已经过去几天了,我们无法获得有关此问题的任何线索。您不应该从多个

我们遇到了一个特殊的问题。 场景:我们有3台服务器,其中包含一个组件的多个实例,所有这些服务器都将事务日志写入一个日志文件。setAppend()传递为true,实现为DailRollingFileAppender

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


如果您有任何帮助,我们将不胜感激,因为已经过去几天了,我们无法获得有关此问题的任何线索。

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

对于滚动,它会导致您刚刚发现的问题:所有进程都运行自己的滚动代码,盲目地覆盖以前的内容(因为它们都不需要任何内容)


这里有一个可能的解决方案:

我们遇到了同样的问题。根本的问题是无法跨多个进程协调对日志文件的访问(在本例中是在多台服务器上运行的)。这意味着会发生各种各样的坏事:日志被覆盖,文件无法滚动等等


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

假设您已将DailRollingFileAppender配置为每日轮换(可以将其配置为每小时、每分钟轮换一次)。比如说,今天是2014年12月31日,日志文件名是sample.log。日志旋转将按以下方式进行:

  • 午夜后收到的第一条日志消息(比如2015年1月1日凌晨1点)将触发日志文件旋转
  • 日志文件旋转将首先删除任何具有前一天后缀的现有文件。(即,它将删除任何名为sample-2014-12-31.log的文件。理想情况下,不应存在此类文件。)
  • 然后,它将以前一天的后缀重命名当前文件。i、 e.将sample.log重命名为sample-2014-12-31.log
  • 它将创建不带后缀的新日志文件。i、 e.新的sample.log
  • 它将开始写入新文件sample.log
如果日志管理器的两个实例指向同一个日志文件,则每个实例将在同一文件上独立重复上述步骤。在以下任何情况下都可能发生这种情况:

  • 如果部署在同一容器中的两个或多个WAR文件指向同一日志文件
  • 如果两个或多个进程指向同一个日志文件
这种情况导致问题中提到的问题

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

请发布您的配置文件好吗?谢谢回复。我在这里又找到了一个链接[.将尝试此操作并提供更新我们继续使用上面链接中提供的解决方案,它成功了。基于FileAppender的类中的基础文件是打开、附加和关闭的,并且保存了每个日志部分。真的是这样吗?我不太确定。至少在UNIX上,如果您登录到一个文件,然后从命令行截断它,您将我看到在下一次写入时,在写入消息之前,文件被填充为二进制零。这表明文件没有在每个日志事件中关闭和打开(这将非常昂贵),但事实上,在写入之间保留了一个文件指针。消息不会混合在一起,因为对文件系统的底层写入是原子的。你是对的。不记得我在近2年前的想法,但在源代码中没有证据支持我的理论。我现在只能道歉。我们在你身上看到了非常类似的行为r web应用程序-尚未确定为什么我们可能有多个日志管理器。@sbarlster-当计算机上运行的两个war文件(或两个独立进程)具有相同的日志文件名时,通常会发生这种情况。