我正在尝试记录来自http客户端的原始请求/响应。我正在遵循这些logging instructions中的log4j2配置。
HttpAsync客户端依赖项:- HttpAsync客户端(版本4.1.1)
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingRandomAccessFile name="app-log" fileName="${log.path}/app.log"
filePattern="${log.path}/app-%d{yyyy-MM-dd}.gz">
<PatternLayout>
<pattern>[%-5level] [%X{uuid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<AsyncLogger name="org.apache.http.impl.conn.Wire" level="debug">
<AppenderRef ref="app-log"/>
</AsyncLogger>
<AsyncRoot level="debug" includeLocation="true">
<AppenderRef ref="app-log"/>
</AsyncRoot>
</Loggers>
</Configuration>打印正常,但是线程上下文没有传递到网络记录器上。
示例:-
// with uuid, output of logger.debug(ThreadContext.getImmutableContext().toString());
[DEBUG] [c48b97f7-0094-44af-82af-3d6b43d76014] 2016-11-14 17:06:03.408 [http-bio-8080-exec-1] OutboundRequestHandler - {uuid=c48b97f7-0094-44af-82af-3d6b43d76014}
// without uuid
[DEBUG] [] 2016-11-14 17:06:03.440 [I/O dispatcher 1] headers - http-outgoing-0 >> POST /abcd.json HTTP/1.1
[DEBUG] [] 2016-11-14 17:06:03.441 [I/O dispatcher 1] headers - http-outgoing-0 >> Content-Length: 2
[DEBUG] [] 2016-11-14 17:06:03.441 [I/O dispatcher 1] headers - http-outgoing-0 >> Content-Type: text/plain; charset=ISO-8859-1
[DEBUG] [] 2016-11-14 17:06:03.441 [I/O dispatcher 1] headers - http-outgoing-0 >> Host: 127.0.0.1:80
[DEBUG] [] 2016-11-14 17:06:03.441 [I/O dispatcher 1] headers - http-outgoing-0 >> Connection: Keep-Alive
[DEBUG] [] 2016-11-14 17:06:03.441 [I/O dispatcher 1] headers - http-outgoing-0 >> User-Agent: Apache-HttpAsyncClient/4.1.1 (Java/1.8.0_92)如何将ThreadContext传递给记录器?
谢谢。
发布于 2016-11-14 22:41:09
由于设置UUID的线程(http-bio-8080-exec-1)与应用程序中执行日志记录的线程(I/O dispatcher 1)不同,它们具有不同的ThreadContext映射,并且第二个线程无法看到第一个线程在其映射中放入的内容。
从log4j 2.7开始,可以创建一个custom context data injector,它可以从ThreadLocal映射之外的其他地方获取上下文数据(因为ThreadContext本质上就是这样的)。
这确实意味着您需要创建一个自定义外观,类似于log4j的ThreadContext,您可以将键值对放入某些数据结构中。我不熟悉AsyncHttpClient,但我找不到一个“上下文”概念,它允许不同的线程共享与同一会话相关的数据。
您的自定义context injector implementation将获取键-值对的快照,并将其注入到每个日志消息的LogEvent中。
发布于 2019-03-29 19:35:09
我不确定这在2019年有多重要,因为提问者肯定会转移到其他事情上。但它仍然在这里:
在log4j2中,我们必须使用ThreadContext.put而不是用于log4j的MDC.put。这将完美地记录所有内容。休息一切都保持不变
发布于 2020-09-18 22:12:04
从v2.13.2开始,建议创建ContextDataProvider而不是ContextDataInjector。
LogEvent2.13.2中引入的ContextDataProvider是一个接口,应用程序和库可以使用它将额外的键值对注入到
的上下文数据中。Log4j的ThreadContextDataInjector使用java.util.ServiceLoader来定位和加载ContextDataProvider实例。Log4j本身使用org.apache.logging.log4j.core.impl.ThreadContextDataProvider.将ThreadContextData添加到LogEvent自定义实现应该实现org.apache.logging.log4j.core.util.ContextDataProvider接口,并通过在名为META-INF/services/org.apache.logging.log4j.core.util.ContextDataProvider.的文件中定义实现类来将其声明为服务
https://stackoverflow.com/questions/40588215
复制相似问题