我有一个小问题,找不到解决方案。我想为级别信息而不是级别警告设置图案布局。如果我有一个登录级别 INFO 一切正常,但如果日志是 level
WARN
,它会被写入控制台两次(作为级别信息和级别警告)。简而言之,特定级别的所有日志都会写出我们该级别和以下级别的日志。
我想登录级别 INFO 并写入控制台,例如:
"%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"
和级别 WARN
,例如"%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"
。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
<Console name="ConsoleWarning" target="SYSTEM_OUT">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</Console>
<File name="File" fileName="logs/cli.log">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="ConsoleInfo"/>
<AppenderRef ref="ConsoleWarning"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
据我了解,您希望将 WARN 或更高级别(WARN、ERROR、FATAL)的日志事件仅发送到“ConsoleWarning”附加程序,而不是同时发送到“ConsoleWarning”和“ConsoleInfo”。
最简单的方法是修改“ConsoleInfo”附加程序中的过滤器配置,基本上执行相反的方法,如下所示:
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
这是有效的,因为正如 log4j2 手册所述:
如果 LogEvent 中的级别与配置的级别相同或更具体,则此过滤器返回 onMatch 结果,否则返回 onMismatch 值。例如,如果 ThresholdFilter 配置为 ERROR 级别,并且 LogEvent 包含 DEBUG 级别,则将返回 onMismatch 值,因为 ERROR 事件比 DEBUG 更具体。
这将导致附加程序仅接受级别低于 WARN 的事件。
另一种可能的解决方案是使用
RoutingAppender 指定每个级别的目的地。如果您这样做,那么您根本不需要 ThresholdFilters。另请注意,您可以通过不提供默认路由以及不提供该级别的路由来忽略特定级别的事件。例如,如果从下面的配置中删除 <Route ref="ConsoleInfo" key="DEBUG" />
,则所有 DEBUG 事件都将被路由附加程序忽略,并且不会打印到控制台。这是配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleInfo" target="SYSTEM_OUT">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>
<Console name="ConsoleWarning" target="SYSTEM_OUT">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</Console>
<File name="File" fileName="logs/cli.log">
<PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
</File>
<Routing name="Routing">
<Routes>
<Script name="RoutingInit" language="JavaScript"><![CDATA[
logEvent.getLevel();]]>
</Script>
<Route ref="ConsoleInfo" key="TRACE" />
<Route ref="ConsoleInfo" key="DEBUG" />
<Route ref="ConsoleInfo" key="INFO" />
<Route ref="ConsoleWarning" key="WARN" />
<Route ref="ConsoleWarning" key="ERROR" />
<Route ref="ConsoleWarning" key="FATAL" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="Routing"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>