Java 如何将Log4j2 ThreadContext值注入Jersey';s测井特征
我想在日志文件中记录服务器的请求/响应。我使用的是Springboot+jersey 2.x+log4j2。我像这样注册了jersey的日志功能-Java 如何将Log4j2 ThreadContext值注入Jersey';s测井特征,java,spring,jersey-2.0,log4j2,java.util.logging,Java,Spring,Jersey 2.0,Log4j2,Java.util.logging,我想在日志文件中记录服务器的请求/响应。我使用的是Springboot+jersey 2.x+log4j2。我像这样注册了jersey的日志功能- jerseyConfig.register( new LoggingFeature( java.util.logging.Logger.getLogger( LoggingFeature.DEFAULT_LOGGER_NAME), java.util.loggi
jerseyConfig.register(
new LoggingFeature(
java.util.logging.Logger.getLogger(
LoggingFeature.DEFAULT_LOGGER_NAME),
java.util.logging.Level.SEVERE,
LoggingFeature.Verbosity.PAYLOAD_ANY,
Integer.MAX_VALUE)
);
log4j2.xml
<!-- Jersey logger -->
<AsyncLogger name="org.glassfish" level="all" additivity="false">
<AppenderRef ref="Console" level="off" />
<AppenderRef ref="RollingFileIO" level="error" />
</AsyncLogger>
在模式中,我在log4j2的ThreadContext
的帮助下注入事务id。我在pom.xml中有log4jjul2.1
,我正在用
-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
一切正常,唯一的问题是,在jersey的日志中,我无法插入事务id。我使用自定义代码尝试了utils日志,并且我能够将事务id放入其中。但是当jersey写入这些日志时,ThreadContext被清除,事务id值变为空。如果日志流是
JUL->log4j2->fooander->Layout->ThreadContext.pop
,那么
Per:
PatternLayout提供打印ThreadContext映射和堆栈内容的机制
- 单独使用
可包含地图的全部内容%X
- 使用
包含指定的键%X{key}
- 使用
包含堆栈的全部内容%x
log4j2->JUL->foodhandler->Formatter->ThreadContext.pop
,那么您必须安装或创建一个了解ThreadContext
的格式化程序。您还必须确保在此配置中不会发生log4j2->ThreadContext.pop->JUL->foodhandler->Formatter
,因为这会在到达JUL
之前忘记所有信息
文档中的所有示例都显示
ThreadContext
是在调用记录器之前设置的。这意味着您必须在执行任何Jersey代码之前设置ThreadContext
。我没有详细介绍Jersey,但从问题描述来看,它似乎有一个线程模型,使得使用ThreadContext
非常困难
幸运的是,Log4j 2.7提供了一种工具,允许您将键值对(如ID)注入来自ThreadContext以外的另一个源的日志事件中。这是为了帮助使用异步框架,例如,所以它可能对Jersey也很有用
Log4j2手册在上一节中简要介绍了此功能
如果你想使用这个工具,你需要写一个自定义的,并告诉Log4j使用这个注射器,而不是通过指定一个默认的。您的自定义注入器需要从某处获取键值对。在Jersey的情况下,RequestContext.getProperty和setProperty是否合适?什么是“无法插入事务id”?错误?不清楚要使用什么API(或者API是否存在)?我的意思是,当jersey编写这些日志时,ThreadContext被我的代码清除了。对于任何http请求,我都会生成事务id并将其放在ThreadContext中,并在响应发出时清除它。泽西在这些事件之前和之后写作。我通过自己的日志记录尝试了java.util.logging,它成功地将事务id放入日志中。我正在寻找一种在jersey的代码执行之前设置ThreadContext的方法。