如何在log4j2中抑制重复的日志消息

6

我对Java和log4j2都比较新,所以可能有些问题不太合适。我的问题是这样的,我写了一个应用程序并使用log4j2进行日志记录。该程序分析数据,并在给定字符串无法按要求解析时发出警告。有时,程序会收到许多意外的字符串,因此它会不断地记录相同的错误消息。所以,我的问题是如何避免一遍又一遍地记录相同的错误消息。例如,我想在日志文件中看到此错误消息被写入x次,而不是在日志文件中看到2000次相同的错误消息。我的当前log4j2配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="pattern">%d{DEFAULT} %-5p %-18.18c %4.4L [%-15.15t] %m%n</Property>
    </Properties>

    <Appenders>
        <Console name="STDERR" target="SYSTEM_ERR">
            <PatternLayout pattern="${pattern}" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="warn">
            <AppenderRef ref="STDERR" />
        </Root>
    </Loggers>
</Configuration>
2个回答

0

很遗憾,我目前没有代码,但是这是解决问题的方法(也许已经有现成的解决方案了)。

您可以创建一个新的appender,将日志异步记录到文件/控制台中。

在appender中,您可以自己实现聚合。每当接收到一个logevent时,不要立即写出它,而是检查是否之前见过该消息。如果是,则不要记录它,而是增加计数器。

最终,将这些聚合的日志事件转换为聚合的消息,并处理该消息,而不是处理数千个日志事件。

例如,您可以通过第二个工作线程来解决此问题。通常(我在看lockback,但我认为对于您而言也应该相当类似),异步appender最终会将事件添加到队列中,该队列将由不同的线程处理。

您可以为聚合的消息设置另一个队列,并且每隔5秒运行一次worker。如果在这5秒内多次看到相同的消息,则您的worker可以聚合该消息并将其放入队列以供处理,以便最终出现在日志中。

希望这可以帮到您,

Artur

补充一点:关于您的配置,请将控制台附加器替换为您的自定义聚合附加器。如果您需要控制台,则可以扩展该附加器并使其执行您想要执行的操作:)


实际上,使用一个通用的AppenderWrapper委托给你的实际Appender可能更有意义。这样,如果您不再喜欢控制台appender,您就可以轻松地切换appenders了。 - philnate
您可以使用过滤器来实现相同的功能。过滤器可以提供多个模式来匹配事件。如果过滤器匹配了一个模式,它会将其传送到内存存储中,并停止事件的传播。然后,内存存储bean可以有一个工作程序简单地使用普通的日志来记录聚合操作(确保在关闭时写入)。这样,您就可以简单地重复使用所有聚合器,并让过滤器完成工作。 - pandaadb

0
当然可以创建一个 log4j2 插件来实现这一点,但我认为日志记录库不是解决此问题的最佳位置。
如果在应用程序中跟踪上一个记录的消息,则代码会简单得多。如果下一条消息相同,则不要记录,而是增加计数器。当您遇到不同的消息时,请记录计数器值。
(使用 Dequeue 跟踪多个消息可以使此过程更为一般化。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接