大家应该都用过Feign的日志打印,日志级别分为NONE、BASIC、HEADERS、FULL,一般咱们用的是BASIC,下面,我给大家展示一下除了NONE之外,另外三种日志级别的日志打印情况。
[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] <--- HTTP/1.1 200 (327ms)
[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Authorization: Bearer XXXX
[testClient#test] Content-Length: 384
[testClient#test] Content-Type: application/json
[testClient#test] logger_id: 8cef4448f21640b0b12fdc8ac4e478e6
[testClient#test] ---> END HTTP (384-byte body)
[testClient#test] <--- HTTP/1.1 200 (327ms)
[testClient#test] connection: keep-alive
[testClient#test] content-type: application/json;charset=UTF-8
[testClient#test] date: Thu, 09 Nov 2023 03:19:59 GMT
[testClient#test] keep-alive: timeout=60
[testClient#test] transfer-encoding: chunked
[testClient#test] <--- END HTTP (51-byte body)
[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Authorization: Bearer XXXX
[testClient#test] Content-Length: 383
[testClient#test] Content-Type: application/json
[testClient#test] logger_id: eaa807b1a34c4b56a66c92dc083235bd
[testClient#test]
[testClient#test] {"test":"123"}
[testClient#test] ---> END HTTP (383-byte body)
[testClient#test] <--- HTTP/1.1 200 (336ms)
[testClient#test] connection: keep-alive
[testClient#test] content-type: application/json;charset=UTF-8
[testClient#test] date: Wed, 08 Nov 2023 06:04:04 GMT
[testClient#test] keep-alive: timeout=60
[testClient#test] transfer-encoding: chunked
[testClient#test]
[testClient#test] {"code":2002,"msg":"OK","data":null}
[testClient#test] <--- END HTTP (51-byte body)
由上日志打印情况可知以下缺点:
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
@Bean
Logger QjxFeign() {
return new QjxFeignLogger(log);
}
}
import feign.Request;
import feign.Response;
import feign.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static feign.Util.*;
public class QjxFeignLogger extends feign.Logger {
private final Logger logger;
public QjxFeignLogger() {
this(feign.Logger.class);
}
public QjxFeignLogger(Class<?> clazz) {
this(LoggerFactory.getLogger(clazz));
}
QjxFeignLogger(Logger logger) {
this.logger = logger;
}
@Override
protected void logRequest(String configKey,
Level logLevel,
Request request) {
// 如果是info日志级别,进入自定义打印逻辑
if (logger.isInfoEnabled()) {
// 打印访问接口url地址
log(configKey, "---> %s %s HTTP/1.1",
request.httpMethod().name(), request.url());
// 获取请求体并打印
String bodyText =
request.charset() != null
? new String(request.body(), request.charset())
: null;
log(configKey, "Request Body:%s",
bodyText != null ? bodyText : "Binary data");
}
}
@Override
protected Response logAndRebufferResponse(String configKey,
Level logLevel,
Response response,
long elapsedTime)
throws IOException {
// 如果是info日志级别,进入自定义打印逻辑
if (logger.isInfoEnabled()) {
return myResponse(configKey, logLevel, response, elapsedTime);
}
return response;
}
protected Response myResponse(String configKey,
Level logLevel,
Response response,
long elapsedTime)
throws IOException {
String reason = response.reason() != null ? response.reason() : "";
int status = response.status();
// 打印调用接口响应时长
log(configKey, "<--- HTTP/1.1 %s %s (%sms)",
status, reason, elapsedTime);
// 获取响应体并打印
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
int bodyLength = bodyData.length;
if (bodyLength > 0) {
log(configKey, "Response Body:%s",
decodeOrDefault(bodyData, UTF_8, "Binary data"));
}
return response.toBuilder().body(bodyData).build();
}
@Override
protected void log(String configKey, String format, Object... args) {
if (logger.isInfoEnabled()) {
// 打印信息格式化
logger.info(String.format(methodTag(configKey) + format, args));
}
}
}
[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Request Body:{"test":"123"}
[testClient#test] <--- HTTP/1.1 200 (328ms)
[testClient#test] Response Body:{"code":2002,"msg":"OK","data":null}