1、开启feign日志
在application.yml 添加配置
feign:client:config:default:loggerLevel: FULL
2、日志实体类
@Document(collection = "feignLogs")
@Data
public class FeignLog {@Idprivate 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;@Overrideprotected void log(String configKey, String format, Object... args) {log.info(String.format(methodTag(configKey) + format, args));}@Overrideprotected 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);}@Overrideprotected 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 {@Autowiredprivate FeignLogRepository feignLogRepository;@BeanLogger feignLogger() {return new CustomFeignLogger(feignLogRepository);}
}
效果展示