OpenFeign日志组件Logger原理与应用

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 该文章详细解释了如何在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

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
机器学习/深度学习 存储 监控
Elasticsearch 在日志分析中的应用
【9月更文第2天】随着数字化转型的推进,日志数据的重要性日益凸显。日志不仅记录了系统的运行状态,还提供了宝贵的洞察,帮助企业改进产品质量、优化用户体验以及加强安全防护。Elasticsearch 作为一个分布式搜索和分析引擎,因其出色的性能和灵活性,成为了日志分析领域的首选工具之一。本文将探讨如何使用 Elasticsearch 作为日志分析平台的核心组件,并详细介绍 ELK(Elasticsearch, Logstash, Kibana)栈的搭建和配置流程。
263 4
|
3月前
|
Java API 开发者
你的应用是不是只有service_stdout.log?
本文记录了logback-spring.xml文件不生效问题的整体排查思路。
|
10天前
|
存储 SQL 监控
|
10天前
|
自然语言处理 监控 数据可视化
|
1月前
|
SQL 存储 关系型数据库
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
老架构师尼恩在其读者交流群中分享了关于 MySQL 中 redo log、undo log 和 binlog 的面试题及其答案。这些问题涵盖了事务的 ACID 特性、日志的一致性问题、SQL 语句的执行流程等。尼恩详细解释了这些日志的作用、所在架构层级、日志形式、缓存机制以及写文件方式等内容。他还提供了多个面试题的详细解答,帮助读者系统化地掌握这些知识点,提升面试表现。此外,尼恩还推荐了《尼恩Java面试宝典PDF》和其他技术圣经系列PDF,帮助读者进一步巩固知识,实现“offer自由”。
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1625 14
|
2月前
|
存储 缓存 关系型数据库
redo log 原理解析
redo log 原理解析
40 0
redo log 原理解析
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
45 2
|
1月前
|
缓存 Linux 编译器
【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案
通过上述步骤,您应该能够在CentOS环境中成功安装并使用log4cplus日志组件。面对任何安装或使用过程中出现的问题,仔细检查错误信息,对照提供的解决方案进行调整,通常都能找到合适的解决之道。log4cplus的强大功能将为您的项目提供灵活、高效的日志管理方案,助力软件开发与维护。
54 0
|
3月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决