RestTemplate 和Apache HttpClient的日志打印如何分开 | 日志打印的精细化控制
背景
某项目使用了 Apache HttpClient,由于过于重要,HttpClient从底层开启了该组件的 DEBUG日志,而项目中其他位置又使用了 RestTemplate,导致RestTemplate也会打印到这里,两种组件的日志混合:
Apache HttpClient 打印的日志格式如下:
org.apache.http.wire - >> "POST /ImportantSystem/api/data HTTP/1.1[\r][\n]"
org.apache.http.wire - >> "Content-Type: application/json[\r][\n]"
org.apache.http.wire - >> "{"name":"test","id":123}"
org.apache.http.wire - << "HTTP/1.1 200 OK[\r][\n]"
org.apache.http.wire - << "Content-Type: application/json[\r][\n]"
org.apache.http.wire - << "{"status":"ok"}"
org.apache.http.wire - >> "POST /notImportant/api/run HTTP/1.1[\r][\n]"
org.apache.http.wire - >> "Content-Type: application/json[\r][\n]"
org.apache.http.wire - >> "{"name":"test","id":123}"
org.apache.http.wire - << "HTTP/1.1 200 OK[\r][\n]"
org.apache.http.wire - << "Content-Type: application/json[\r][\n]"
org.apache.http.wire - << "{"status":"ok"}"
需求
需要将 RestTemplate 的日志关闭或者分离到其他位置。
分析
打印日志的来源分析
RestTemplate 是对 HttpClient的封装:例如 JDK 自身的httpClient,通过工厂类 SimpleClientHttpRequestFactory 管理。
还有一种 Apache HttpClient的封装,通过工厂类 HttpComponentsClientHttpRequestFactory 管理,其他工厂类不在本次讨论范围。
如果使用 SimpleClientHttpRequestFactory ,则打印的日志只能通过 RestTemplate 的 Interceptor 实现。
如果既有 Intercetor 也有 Apache HttpClient,还打开了 org.apache.http.wire ,就会出现上述局面,DEBUG日志不能轻易关闭,会导致RestTemplate 打印了不重要的日志,混入重要的日志,而且还通过 Interceptor 多打印了一份。
结论
完整内容参见 英文版
Github Gist