log4j2如何过滤掉没有ThreadContext键的消息
log4j2 how to filter out messages having not ThreadContext key
在我的应用程序中,有时我在记录时有一个 threadContext 键 'jobId',有时没有。
所以我想将日志消息传递到我的 jdbc 日志附加程序(它需要字段 'jobId'),只有当键 'jobId' 存在于 threadContext 中时。
我无法通过配置 DynamicThresholdFilter 来跳过日志消息
<JDBC name="databaseAppender" tableName="LOG_MESSAGE">
<DynamicThresholdFilter key="jobId" defaultThreshold="INFO" onMatch="ACCEPT" onMismatch="DENY">
</DynamicThresholdFilter>
<DataSource jndiName="java:jboss/datasources/myDS" />
<Column name="MESSAGE" pattern="%message" />
<Column name="Job_KEY_" pattern="%X{jobId}" />
</JDBC>
您可以使用 RoutingAppender to do this, similar to an example on the log4j2 FAQ page。
这里有一个 Java class 可以做一些日志记录:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
//These should appear in the console only
log.debug("No jobId, This is some debug!");
log.info("No jobId, Here's some info!");
log.error("No jobId, Some error happened!");
//These should route to a simulated JDBC appender only
ThreadContext.put("jobId", "1234");
log.debug("With jobId, This is some debug!");
log.info("With jobId, Here's some info!");
log.error("With jobId, Some error happened!");
//Once again these will go to console only
ThreadContext.remove("jobId");
log.debug("No jobId, This is some debug!");
log.info("No jobId, Here's some info!");
log.error("No jobId, Some error happened!");
}
}
这是一个示例 log4j2.xml 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="simulatedJdbc" fileName="logs/simulatedJdbc.txt"
immediateFlush="false" append="true">
<PatternLayout
pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} %X{jobId} - %msg%n" />
</File>
<Routing name="Routing">
<Routes pattern="$${ctx:jobId}">
<!-- This route is chosen if ThreadContext has no value for key jobId. -->
<Route key="$${ctx:jobId}" ref="Console" />
<!-- This is the default route when no others match -->
<Route ref = "simulatedJdbc"/>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Routing" />
</Root>
</Loggers>
</Configuration>
上面运行的结果是下面的输出:
控制台输出:
17:49:41.659 [main] DEBUG example.SomeClass - No jobId, This is some debug!
17:49:41.663 [main] INFO example.SomeClass - No jobId, Here's some info!
17:49:41.664 [main] ERROR example.SomeClass - No jobId, Some error happened!
17:49:41.664 [main] DEBUG example.SomeClass - No jobId, This is some debug!
17:49:41.664 [main] INFO example.SomeClass - No jobId, Here's some info!
17:49:41.664 [main] ERROR example.SomeClass - No jobId, Some error happened!
simulatedJdbc.txt 输出:
2019-02-08 17:49:41.664 [main] DEBUG example.SomeClass 1234 - With jobId, This is some debug!
2019-02-08 17:49:41.664 [main] INFO example.SomeClass 1234 - With jobId, Here's some info!
2019-02-08 17:49:41.664 [main] ERROR example.SomeClass 1234 - With jobId, Some error happened!
如您所见,当 ThreadContext
包含 jobId
时,日志将路由到模拟的 JDBC 附加程序(在我的示例中只是一个文件附加程序)。当 jobId
丢失时,日志将改为路由到控制台附加程序。
希望对您有所帮助!
在我的应用程序中,有时我在记录时有一个 threadContext 键 'jobId',有时没有。
所以我想将日志消息传递到我的 jdbc 日志附加程序(它需要字段 'jobId'),只有当键 'jobId' 存在于 threadContext 中时。
我无法通过配置 DynamicThresholdFilter 来跳过日志消息
<JDBC name="databaseAppender" tableName="LOG_MESSAGE">
<DynamicThresholdFilter key="jobId" defaultThreshold="INFO" onMatch="ACCEPT" onMismatch="DENY">
</DynamicThresholdFilter>
<DataSource jndiName="java:jboss/datasources/myDS" />
<Column name="MESSAGE" pattern="%message" />
<Column name="Job_KEY_" pattern="%X{jobId}" />
</JDBC>
您可以使用 RoutingAppender to do this, similar to an example on the log4j2 FAQ page。
这里有一个 Java class 可以做一些日志记录:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
//These should appear in the console only
log.debug("No jobId, This is some debug!");
log.info("No jobId, Here's some info!");
log.error("No jobId, Some error happened!");
//These should route to a simulated JDBC appender only
ThreadContext.put("jobId", "1234");
log.debug("With jobId, This is some debug!");
log.info("With jobId, Here's some info!");
log.error("With jobId, Some error happened!");
//Once again these will go to console only
ThreadContext.remove("jobId");
log.debug("No jobId, This is some debug!");
log.info("No jobId, Here's some info!");
log.error("No jobId, Some error happened!");
}
}
这是一个示例 log4j2.xml 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="simulatedJdbc" fileName="logs/simulatedJdbc.txt"
immediateFlush="false" append="true">
<PatternLayout
pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} %X{jobId} - %msg%n" />
</File>
<Routing name="Routing">
<Routes pattern="$${ctx:jobId}">
<!-- This route is chosen if ThreadContext has no value for key jobId. -->
<Route key="$${ctx:jobId}" ref="Console" />
<!-- This is the default route when no others match -->
<Route ref = "simulatedJdbc"/>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Routing" />
</Root>
</Loggers>
</Configuration>
上面运行的结果是下面的输出:
控制台输出:
17:49:41.659 [main] DEBUG example.SomeClass - No jobId, This is some debug!
17:49:41.663 [main] INFO example.SomeClass - No jobId, Here's some info!
17:49:41.664 [main] ERROR example.SomeClass - No jobId, Some error happened!
17:49:41.664 [main] DEBUG example.SomeClass - No jobId, This is some debug!
17:49:41.664 [main] INFO example.SomeClass - No jobId, Here's some info!
17:49:41.664 [main] ERROR example.SomeClass - No jobId, Some error happened!
simulatedJdbc.txt 输出:
2019-02-08 17:49:41.664 [main] DEBUG example.SomeClass 1234 - With jobId, This is some debug!
2019-02-08 17:49:41.664 [main] INFO example.SomeClass 1234 - With jobId, Here's some info!
2019-02-08 17:49:41.664 [main] ERROR example.SomeClass 1234 - With jobId, Some error happened!
如您所见,当 ThreadContext
包含 jobId
时,日志将路由到模拟的 JDBC 附加程序(在我的示例中只是一个文件附加程序)。当 jobId
丢失时,日志将改为路由到控制台附加程序。
希望对您有所帮助!