1、开启feign日志
在application.yml 添加配置
feign:
client:
config:
default:
loggerLevel: FULL
2、日志实体类
@Document(collection = "feignLogs")
@Data
public class FeignLog {
@Id
private String id;
private String method;
private String url;
private LocalDateTime requestTime;
private String requestBody;
private LocalDateTime responseTime;
private String responseBody;
private long elapsedTime;
private int status;
}
3、定义一个 Spring Data MongoDB 存储库
public interface FeignLogRepository extends MongoRepository<FeignLog, String> {
}
自定义 Feign 日志记录器
import com.softding.dao.FeignLogRepository;
import com.softding.domain.log.FeignLog;
import feign.Logger;
import feign.Request;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@Slf4j
public class CustomFeignLogger extends Logger {
private final FeignLogRepository feignLogRepository;
public CustomFeignLogger(FeignLogRepository feignLogRepository) {
this.feignLogRepository = feignLogRepository;
}
private FeignLog feignLog;
@Override
protected void log(String configKey, String format, Object... args) {
log.info(String.format(methodTag(configKey) + format, args));
}
@Override
protected void logRequest(String configKey, Level logLevel, Request request) {
LocalDateTime requestTime = LocalDateTime.now();
log.info("Request: {} {} {}", request.httpMethod(), request.url(), request.headers());
log.info("Request Time: {}", requestTime);
if (request.body() != null) {
log.info("Request Body: {}", new String(request.body(), StandardCharsets.UTF_8));
}
FeignLog log = new FeignLog();
log.setMethod(request.httpMethod().name());
log.setUrl(request.url());
log.setRequestTime(requestTime);
log.setRequestBody(request.body() != null ? new String(request.body(), StandardCharsets.UTF_8) : null);
feignLog = log;
feignLogRepository.save(log);
}
@Override
protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
LocalDateTime responseTime = LocalDateTime.now();
log.info("Response: {} {} {}", response.status(), response.reason(), response.headers());
log.info("Response Time: {}", responseTime);
log.info("Elapsed Time: {} ms", elapsedTime);
byte[] bodyData = response.body() != null ? IOUtils.toByteArray(response.body().asInputStream()) : null;
if (bodyData != null) {
log.info("Response Body: {}", new String(bodyData, StandardCharsets.UTF_8));
}
FeignLog log = null;
if (feignLog != null) {
log = feignLog;
}else {
log = new FeignLog();
}
log.setResponseTime(responseTime);
log.setResponseBody(bodyData != null ? new String(bodyData, StandardCharsets.UTF_8) : null);
log.setElapsedTime(elapsedTime);
log.setStatus(response.status());
feignLogRepository.save(log);
return response.toBuilder().body(bodyData).build();
}
}
4、配置使用自定义日志记录器
import com.softding.dao.FeignLogRepository;
import feign.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig {
@Autowired
private FeignLogRepository feignLogRepository;
@Bean
Logger feignLogger() {
return new CustomFeignLogger(feignLogRepository);
}
}
效果展示