首页 > 解决方案 > 以编程方式更改 Log4j2 RollingFileAppender 在运行时写入的文件名

问题描述

我的组织正在从 Log4j1 迁移到 Log4j2。我们有一个自定义的滚动文件附加程序,当应用程序中发生某个事件时,它会更改它在运行时记录的文件名。这样做是为了很容易在日志目录中找到日志文件。例如,日志文件目录可能如下所示;

mylog-2021-08-02.log

mylog-2021-08-03.log

SPECIAL_EVENT_mylog-2021-08-03.log

mylog-2021-08-04.log

mylog-2021-08-05.log

根据我所做的研究,Appender 文件名似乎是不可变的,我必须创建一个新的 Appender 并在事件发生时将其添加到配置中,然后当触发策略发出信号时删除此 Appender 并添加回原始配置的新Appender?还有比这更优雅的解决方案吗?我是否需要编写自定义附加程序并自己处理文件命名/翻转逻辑?

2021 年 9 月 2 日更新

感谢@DB 的回答,这帮助我了解了很多关于 Log4j2 的知识。您提到的问题与我的情况非常相似。我们有很多设备,每个设备都需要登录到自己的文件中。不过,我确实有一些额外的要求。我们在每个设备中有许多线程需要记录到同一个设备日志文件,并且许多设备都需要自己的日志文件。此外,当设备中发生特定事件时,我需要处理特殊的翻转文件命名要求(原始帖子)。最后,分配给每个设备的名称直到运行时才知道(它在我们拥有的另一个配置文件中定义)。我可以使用标记,就像你建议的那样,但这很快就会变得难以维护,因为开发人员需要知道他们必须在每个日志记录语句中传递一个标记,并且需要更新整个现有代码库以传递适当的标记。我也可以按照您的建议使用上下文映射,但应用程序有很多线程,并且开发人员需要再次知道他们必须在从任何线程记录之前适当地设置上下文数据。

使用 Log4j1,这些要求通过以下方式得到满足:

  1. 从处理特殊事件文件命名翻转逻辑的 RollingFileAppender 派生的自定义 appender 类。
  2. 接受满足以下条件的事件的自定义过滤器:事件来自的线程名称包括设备的“设备名称” b。事件消息包含“设备名称”</li>
  3. 在系统中实例化新设备时: a.使用“设备名称”字符串创建一个新的自定义过滤器以进行过滤。湾。创建一个新的自定义附加程序,将日志记录到名为“设备名称”.log 的文件中。此附加程序是使用自定义过滤器创建的。C。添加附加程序作为对 Root 记录器的引用
  4. 这会导致所有日志事件都发送到新的附加程序(以及创建的所有其他设备附加程序),但日志事件会根据“设备名称”进行过滤。这会生成一个设备特定的日志文件。

我可以像使用 Log4j1 一样实现自定义过滤器和附加程序,但我不希望依赖于日志记录核心类。您的任何其他建议将不胜感激。

标签: log4j2

解决方案


在您的情况下,过滤器可能会有很好的用途。因此,您将创建一个带有自定义过滤器的新文件附加程序,以仅包含您感兴趣的日志语句。此附加程序上的文件名将是特殊情况下的文件名。

但我认为这不会让您的日志记录体验变得更轻松。

我会像往常一样保持日志条目在文件中流动,并研究如何在事后使用 grep 或其他日志聚合器将它们过滤掉。

过滤器文档:

https://logging.apache.org/log4j/2.x/manual/filters.html


推荐阅读