使用依赖
<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创建了日志
@Override
public 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));
}
@Override
protected 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, ""); // CRLF
log(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: FULL
hello-feign-server: # 指定服务配置
loggerLevel: BASIC