OpenFeign日志组件Logger原理与应用

简介: 该文章详细解释了如何在OpenFeign中配置并使用请求和响应的GZIP压缩功能。

前言

前面已经分析了OpenFeign三个组件了

今天还是继续分析OpenFeign的组件,分布式rpc服务调用的日志信息是非常关键的,OpenFeign提供了Logger组件,通过Logger组件可以实现openfeign接口调用的日志的打印。

OpenFeign日志打印源码

OpenFeign如何打印日志的,我们可以看到OpenFeign执行请求主流程源码 位于feign.SynchronousMethodHandler#executeAndDecode

Object executeAndDecode(RequestTemplate template) throws Throwable {
   
   

Request request = targetRequest(template);

//打印请求日志

if (logLevel != Logger.Level.NONE) {
   
   

logger.logRequest(metadata.configKey(), logLevel, request);

}

Response response;

long start = System.nanoTime();

try {
   
   

response = client.execute(request, options);

} catch (IOException e) {
   
   

//异常日志打印

if (logLevel != Logger.Level.NONE) {
   
   

logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start));

}

throw errorExecuting(request, e);

}

long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);

boolean shouldClose = true;

try {
   
   

//日志打印响应

if (logLevel != Logger.Level.NONE) {
   
   

response = logger.logAndRebufferResponse(metadata.configKey(), logLevel, response, elapsedTime);

}

//相应解码

Object result = decode(response);

return result;

} catch (IOException e) {
   
   

//打印响应解码日志

if (logLevel != Logger.Level.NONE) {
   
   

logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime);

}

throw errorReading(request, response, e);

}

}

从源码可以看出,OpenFeign分别在发起请求前使用Logger对象打印请求信息,发起请求后打印请求响应信息,响应解码的信息打印。

image.png

Logger抽象类定义好了打印日志的方法,同时OpenFeign给Logger抽象类提供了4个实现类。

image.png

由此可知,OpenFeign默认支持Slf4j,JavaLogger等日志组件。

OpenFeign默认使用Slf4j日志组件

我们在自动装配类FeignClientsConfiguration中,发现没有配置Logger的Bean实现。 只是配置了FeignLoggerFactory的Bean是DefaultFeignLoggerFactory

那么OpenFeign默认使用什么日志组件呢?通过feignLoggerFactory就可以看得出来。

@Configuration(
    proxyBeanMethods = false
)
public class FeignClientsConfiguration {
   
   

    @Autowired(required = false)
    private Logger logger;
    @Bean
    @ConditionalOnMissingBean(FeignLoggerFactory.class)
    public FeignLoggerFactory feignLoggerFactory() {
   
   
       return new DefaultFeignLoggerFactory(this.logger);
    }
}
public class DefaultFeignLoggerFactory implements FeignLoggerFactory {
   
   

   private Logger logger;

   public DefaultFeignLoggerFactory(Logger logger) {
   
   
      this.logger = logger;
   }

   @Override
   public Logger create(Class<?> type) {
   
   
      //logger为空,默认使用log4j
      return this.logger != null ? this.logger : new Slf4jLogger(type);
   }

}

由此可知OpenFeign默认使用Slf4j日志组件打印日志。

日志级别

在Logger抽象类的方法参数里,对request和response方法日志打印还支持日志Level,日志等级共有4个。

public static enum Level {
   
   
    NONE,//不打印
    BASIC, //打印基本信息
    HEADERS,//只打印头
    FULL; //全部打印

    private Level() {
   
   
    }
}

定制日志组件与日志级别

  • 针对单个Feign客户端
public class TestFeignClientConfiguration {
   
   

    @Bean
    public Logger logger() {
   
   
        return new Logger.JavaLogger();
    }

    @Bean 
    public Logger.Level level() {
   
   
        return  Logger.Level.FULL;
    }
}


@RestController
@FeignClient(value = "fox-server", configuration = TestFeignClientConfiguration.class)
public interface FeignService {
   
   
    @PostMapping("/get")
    String getName(@RequestBody @Validated DemoRequest request);
}
  • 针对全局Feign客户端
@Configuration
public class TestFeignClientConfiguration {
   
   

    @Bean
    public Logger logger() {
   
   
        return new Logger.JavaLogger();
    }

    @Bean 
    public Logger.Level level() {
   
   
        return  Logger.Level.FULL;
    }
}
  • 自定义日志组件

我们也可以自己实现自己的日志组件,只要继承抽象类feign.Logger,实现log方法,比如我们想把日志上报到kafka,提供给监控平台或者日志云平台分析等。

image.png

总结

OpenFeign日志组件实现还是比较简单的,她和其他OpenFeign组件一样提供了的扩展点,我们可以按需实现自己的日志组件,实现个性化的日志打印或者日志上报功能,你在生产环境有没有使用过OpenFeign日志组件呢?欢迎评论区留言分享讨论。

image.png

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
SpringCloudAlibaba 负载均衡 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(五)OpenFeign的使用
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(五)OpenFeign的使用
1002 0
|
存储 监控 Java
OpenFeign请求拦截器组件RequestInterceptor原理与使用场景
该文章讲述了OpenFeign中的请求拦截器组件RequestInterceptor的原理及其常见使用场景。
OpenFeign请求拦截器组件RequestInterceptor原理与使用场景
|
6月前
|
JSON Java 数据格式
Feign 复杂对象参数传递避坑指南:从报错到优雅落地
本文深入剖析了SpringCloud Feign在复杂对象参数传递中的常见问题及解决方案。文章首先分析了GET请求传递复杂对象失败的底层原因,包括HTTP规范约束和Feign参数解析逻辑。针对GET场景,提供了四种解决方案:@SpringQueryMap(首选)、手动拆分属性+@RequestParam、MultiValueMap封装和自定义FeignEncoder,详细比较了各方案的优缺点和适用场景。对于POST场景,推荐使用@RequestBody注解传递JSON请求体。
1093 6
|
负载均衡
OpenFeign重试组件Retryer原理
该文章主要讲解了OpenFeign中的重试组件Retryer的工作原理及其实现细节。
OpenFeign重试组件Retryer原理
|
JSON Java API
Springboot整合Swagger2.0、3.0
Springboot整合Swagger2.0、3.0
730 0
HashMap的put方法的具体流程?
1. 判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容; 2. 根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建节点添加,转向 ⑥,如果table[i]不为空,转向③; 3. 判断table[i]的首个元素是否和key一样,如果相同直接覆盖value,否则转向④,这里的相同指的 是hashCode以及equals; 4. 判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值 对,否则转向5; 5. 遍历table[i],判断链表长度是否大于8,大于8的
feign如何开启日志及分析
feign如何开启日志及分析
911 0
|
缓存 Java 数据库
SpringBoot中ThreadPoolTaskExecutor的使用
SpringBoot中ThreadPoolTaskExecutor的使用
891 0
|
存储 Dubbo 应用服务中间件
使用Dubbo的RpcContext居然那么多坑
使用Dubbo的RpcContext居然那么多坑
3719 0
使用Dubbo的RpcContext居然那么多坑
|
NoSQL Redis
Redis进阶- Redisson分布式锁实现原理及源码解析
Redis进阶- Redisson分布式锁实现原理及源码解析
865 0

热门文章

最新文章