feign日志学习记录
使用依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.1.1.RELEASE</version></dependency>
1.通过@FeignClient查看feign配置
org.springframework.cloud.openfeign.FeignClient/*** A custom <code>@Configuration</code> for the feign client. Can contain override* <code>@Bean</code> definition for the pieces that make up the client, for instance* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.** @see FeignClientsConfiguration for the defaults* @return list of configurations for feign client*/Class<?>[] configuration() default {};
如果没有配置默认使用FeignClientsConfiguration.
@Autowired(required = false)private Logger logger;@Bean@ConditionalOnMissingBean(FeignLoggerFactory.class)public FeignLoggerFactory feignLoggerFactory() {return new DefaultFeignLoggerFactory(this.logger);}
使用DefaultFeignLoggerFactory创建了日志
@Overridepublic Logger create(Class<?> type) {return this.logger != null ? this.logger : new Slf4jLogger(type);}
默认情况logger为空默认选用feign.slf4j.Slf4jLogger
只有logger是debug级别才会打印feign日志。
public Slf4jLogger(Class<?> clazz) {this(LoggerFactory.getLogger(clazz));}@Overrideprotected void logRequest(String configKey, Level logLevel, Request request) {// 只有类日志级别为debug才会有feign日志输出,if (logger.isDebugEnabled()) {super.logRequest(configKey, logLevel, request);}}
org.slf4j.LoggerFactory会根据类名创建logger,
public static Logger getLogger(Class<?> clazz) {Logger logger = getLogger(clazz.getName());if (DETECT_LOGGER_NAME_MISMATCH) {Class<?> autoComputedCallingClass = Util.getCallingClass();if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(),autoComputedCallingClass.getName()));Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");}}return logger;}
feign请求日志feign.Logger应请求日志为例,根据不同feign日志级别打印不同信息
protected void logRequest(String configKey, Level logLevel, Request request) {log(configKey, "---> %s %s HTTP/1.1", request.httpMethod().name(), request.url());if (logLevel.ordinal() >= Level.HEADERS.ordinal()) {for (String field : request.headers().keySet()) {for (String value : valuesOrEmpty(request.headers(), field)) {log(configKey, "%s: %s", field, value);}}int bodyLength = 0;if (request.body() != null) {bodyLength = request.body().length;if (logLevel.ordinal() >= Level.FULL.ordinal()) {String bodyText =request.charset() != null ? new String(request.body(), request.charset()) : null;log(configKey, ""); // CRLFlog(configKey, "%s", bodyText != null ? bodyText : "Binary data");}}log(configKey, "---> END HTTP (%s-byte body)", bodyLength);}}
feign日志级别
public enum Level {/*** No logging.*/NONE,/*** Log only the request method and URL and the response status code and execution time.*/BASIC,/*** Log the basic information along with request and response headers.*/HEADERS,/*** Log the headers, body, and metadata for both requests and responses.*/FULL}
配置class类日志级别debug,后feign日志级别生效。
logging:level:com.example.feign.client: debug # Feign客户端所在包的日志级别
spring:cloud:openfeign:client:config:default: # 全局默认配置loggerLevel: FULLhello-feign-server: # 指定服务配置loggerLevel: BASIC