【问题标题】:How to disable additivity on marker logger?如何禁用标记记录器的可加性?
【发布时间】:2014-01-22 12:21:26
【问题描述】:

我已经定义了一个Marker 并且希望只将它记录到一个特定的文件中。因此我试图设置additivity = false。但它不起作用,并且还记录到我的全局日志文件中。这里可能有什么问题?

<Configuration>
    <Appenders>
        <RollingFile name="TEST" fileName="test.log" filePattern="test1.log">
            <MarkerFilter marker="TEST_LOG" onMatch="ACCEPT" onMismatch="DENY"/>
        </RollingFile>
        <RollingFile name="GLOBAL" fileName="global.log" filePattern="global.log">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <MarkerFilter marker="TEST_LOG" onMatch="DENY" onMismatch="ACCEPT"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <logger name="foo" additivity="false">
            <appender-ref ref="TEST" />
        </logger>
    </Loggers>
</Configuration>

用法:

LogManager.getRootLogger().info(MarkerManager.getMarker("TEST_LOG"), "test log");

【问题讨论】:

  • 您不需要将name 添加到您的logger 元素吗?
  • 我也试过加个名字,更新了我上面的帖子,但效果一样。

标签: java logging configuration log4j log4j2


【解决方案1】:

在示例代码中,标记被命名为"TEST",但在配置中,MarkerFilter 只接受带有标记"TEST_LOG" 的日志事件。配置和代码应该使用相同的字符串。

此外,您可能需要定义两个 Appender:一个用于您的全局日志文件,一个用于您的特定(标记)日志事件。然后 ACCEPT 仅在您的特定 appender 中标记的日志事件,并 DENY 在全局 appender 中标记的日志事件。

【讨论】:

  • 抱歉,标记名称打错了。我当然已经有第二个附加程序来创建我的全局日志文件。我向它添加了以下标记过滤器&lt;MarkerFilter marker="SELL_FAILURE" onMatch="DENY" onMismatch="ACCEPT"/&gt;,但我仍然看到标记记录在全局文件中
  • 在这种情况下,能否请您发布您的完整 log4j2.xml?
【解决方案2】:

可加性在您的情况下不起作用,因为可加性控制特定记录器不继承父级的附加程序。

在您的配置中,您将记录器foo 设置为具有additivity = false,这意味着,除非您使用foo 或其子记录器进行记录,否则您仍将遵循根记录器的配置。 (我在您的帖子中看不到您的根记录器配置,我怀疑它指的是两个附加程序)。从您引用的代码中,您正在使用根记录器进行记录,foo 记录器的配置根本不会生效。

我可以建议两种解决方案:

  1. 对于使用TEST_LOG 标记记录的所有日志消息,请确保使用foo 记录器记录它。或者,
  2. 如果您需要为您的TEST_LOG 消息使用任何记录器,那么您应该重新配置您的附加程序,以便您的GLOBAL 文件附加程序接受除TEST_LOG 之外的任何内容。 (目前你只是否认SELL_FAILURE标记)

正确的解决方案取决于您的实际需求。确保您了解基本概念,以便选择适合自己的解决方案。


编辑:

首先,即使您在评论中提到的“正确”配置,不同记录器的问题仍然存在。这意味着,因为您使用 root 记录器进行记录,foo 记录器的配置与您的日志消息无关,并且在您的情况下可加性不适用。

我没有使用 Log4J2,对过滤器使用的简要检查导致我发现两个问题:

首先,我认为定义多个过滤器的正确方法是使用复合过滤器(这意味着在 &lt;Filters&gt; 元素中定义,尽管我不太了解 Log4J 文档的语法)。

其次,即使你在复合过滤器中定义它,你的配置仍然有问题。当日志事件具有 INFO 或更高级别时,您在过滤器中声明它是 ACCEPTDENY,这将禁止后续过滤器评估。如果您想记录带有INFO 且不包含TEST_LOG 标记的消息,您应该执行以下操作:

<MarkerFilter marker="TEST_LOG" onMatch="DENY" onMismatch="NETURAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>

NEUTRAL 表示当前过滤器无法确定是接受还是拒绝该消息,将评估下一个过滤器来确定它。

【讨论】:

  • 抱歉,SELL_FAILURE 是复制过去的问题。事实上,我已经在那里写了TEST_LOG 否认除了这个标记之外的任何东西。虽然,它仍然被记录到 root...
  • 非常感谢您的帮助。如您在上面所写的那样配置日志记录确实可以按预期工作!所以确实我不知道过滤顺序在这里很重要。
  • 其实不仅顺序很重要,而且你还需要知道,一旦一个过滤器决定“接受”或“拒绝”一个日志事件,就不会发生后续的过滤器评估. “中性”是这里的关键
【解决方案3】:

我注意到的几件事:

  • 您应该在代码中和 both MarkerFilters 的配置中使用相同的标记字符串。
  • 您需要添加 AppenderRef 元素以将您的记录器连接到两个附加程序
  • 您可以在 AppenderRef 中指定一个级别,这比使用 ThresholdFilter 更容易

这给了你这个配置:

<Configuration>
    <Appenders>
        <RollingFile name="MARKED_ONLY" fileName="markedOnly.log" filePattern="markedOnly1.log">
            <MarkerFilter marker="MY_MARKER" onMatch="ACCEPT" onMismatch="DENY"/>
        </RollingFile>
        <RollingFile name="GLOBAL" fileName="global.log" filePattern="global.log">
            <MarkerFilter marker="MY_MARKER" onMatch="DENY" onMismatch="ACCEPT"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <root level="trace">
            <appender-ref ref="MARKED_ONLY" level="trace" />
            <appender-ref ref="GLOBAL" level="info" />
        </root>
    </Loggers>
</Configuration>

还有这段代码:

Logger logger = LogManager.getLogger(MyClass.class); // or .getRootLogger()
logger.info(MarkerManager.getMarker("MY_MARKER"), "test log");

请注意,在代码和两个附加程序的过滤器中使用相同的“MY_MARKER”字符串很重要。这样,全局文件的 appender 可以使用该过滤器来拒绝标记的日志事件。

【讨论】:

    猜你喜欢
    • 2019-04-01
    • 2013-11-15
    • 2021-10-18
    • 1970-01-01
    • 2014-04-13
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    相关资源
    最近更新 更多