【问题标题】:Log4J rerouting of Log EventsLog4J 重新路由日志事件
【发布时间】:2010-11-15 12:37:22
【问题描述】:

我想构建一个 Appender(或类似的东西)来检查事件并在某些条件下创建日志新事件。

一个例子是 Escalating Appender,它检查是否记录了一定数量的相同事件,如果是,则使用更高的日志级别记录事件。因此,您可以定义如下内容:如果您在此记录器上收到超过 10 个相同的警告,则将其设为错误。

所以我的问题是:

  1. 这样的东西已经存在了吗?

  2. Appender 是实现此行为的正确类吗?

  3. 有什么你认为我应该注意的陷阱吗?

澄清: 我对收集和分析事件的算法很好。我将在 appender 中使用一个集合来做到这一点。我的目的不需要坚持不懈。我的问题 #2 是:appender 是否适合这样做?毕竟,为 appender 创建日志条目是不正常的行为。

【问题讨论】:

    标签: java logging log4j appender


    【解决方案1】:

    Logback(log4j 的继任者)将允许您通过TurboFilters 启用任何事件的日志记录。例如,假设同一事件在给定时间范围内发生 N 次或多次,您可以强制接受该事件(无论其级别如何)。另请参阅 DuplicateMessageFilter ,它执行相反的操作(拒绝重新发生的事件)。

    但是,即使是 logback,也不允许增加日志事件的级别。 Log4j 也不会。这两个框架都不是为此而设计的,我不鼓励您尝试在同一线程中增加级别动态。另一方面,在后期处理期间增加级别是完全不同的事情。向另一个线程发出信号以生成具有更高级别的 new 日志事件是另一种可能性。 (让您的 turbo-filter 向另一个线程发出信号以生成更高级别的 new 日志事件。)

    从您的问题中不清楚您为什么希望增加级别。级别的增加本身是一个原因还是它是实现目标的一种手段,即无论其级别如何都记录事件。如果是后者,那么 logback 的 TurboFilters 就是要走的路。

    HTH,

    【讨论】:

    • 增加级别基本上只是我可能想做的事情的一个例子。 “我不鼓励您尝试在同一线程中即时增加级别”这是否包括创建一个新的 Eventet,即调用 Logger.log(..),或者只是更改级别(我什至不知道是否这是可能的。
    • TurboFilters 看起来很有前途
    • 您无法更改现有事件的级别,因为级别是只读字段。在处理一个新事件的同时创建一个新事件可能会变得非常麻烦。因此,我建议避免这样做。你可以做任何你想做的事情,包括创建一个新事件,只要它来自不同的线程。
    【解决方案2】:

    正如 Rafe 已经指出的那样,最大的挑战是将实际事件保存在 Appender 中,以便您知道触发事件的时机已经到来(例如升级日志级别)。

    因此,我提出以下策略:

    1. 使用custom JDBCAppender。与与 Log4j 捆绑的那个不同,这个可以记录异常。
    2. 设置一个嵌入式数据库,如HSQLDB,并设置一个包含一个用于事件记录的表的数据库。它解决了持久性问题,因为您可以使用 SQL 来查找发生的事件类型。
    3. 运行一个单独的线程来监控数据库,并检测所需的事件模式。
    4. 使用LogManager 访问所需的Loggers 并手动设置其级别。

    【讨论】:

    • Jens 说:“我的目的不需要坚持。”
    • 在我发布答案后添加了持久性评论。尽管如此,HSQLDB 仍可以配置为仅在内存中工作(请参阅:hsqldb.org/doc/guide/ch01.html#N101CA)。使用该解决方案可以在结构和时间意义上从 Appender 之外移动事件分析逻辑。
    • 根据我的经验,写入 DB appender(每个事件 1 毫秒)与使用 turbo 过滤器(每个事件 100 纳秒)相比至少要慢 10'000。假设一个非常快的数据库,这个比率可能会降低,但仍然会慢几个数量级。
    【解决方案3】:

    你可以通过实现log4j提供的Appender接口来创建自己的appender。

    http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Appender.html

    那将是一种方法。另一种方法是使用现有的附加程序,然后编写一些监控日志的代码。例如,您可以登录到数据库,然后编写一个进程来监控数据库中的日志条目并根据它看到的内容创建元事件。

    这主要取决于您对什么感到满意。您必须处理的一个问题是如何回顾日志以创建您的元事件。您要么必须在 appender 中累积事件,要么将它们保存在您可以查询以构建元事件的地方。累积它们的问题是,如果您停止并启动您的流程,您要么必须将它们转储到某个地方以便它们被重新拾取,要么在流程重新启动时重新开始。

    例如,假设我想在每 10 次抛出 NullPointerException 时创建一个日志条目。如果我在某种数据库中有日志条目,那么每次抛出 NPE 时,我都会运行一个查询来查看自上次为它们创建日志条目以来已经抛出了多少 NPE。如果每次抛出一个时我只在内存中计算它们,如果在抛出 5 个后重新启动应用程序,如果我不坚持这个数字,我就会失去计数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      相关资源
      最近更新 更多