JAVA Feign 调用日志不打印?Slf4jLogger 与 Logbook 集成配置

好的,接下来我们深入探讨一下 Feign 调用日志不打印的问题,以及如何通过 Slf4jLogger 与 Logbook 集成来解决它。

Feign 调用日志:为什么不打印?

Feign 默认情况下并不会自动打印请求和响应的详细日志。这主要是出于性能和隐私考虑。如果我们不做任何配置,Feign 只会记录一些基本的错误信息。要启用详细的日志,我们需要显式地进行配置。

通常,Feign 日志不打印的原因主要有以下几点:

  1. 日志级别未设置: 默认情况下,Feign 的日志级别可能设置为 NONE,这意味着不会记录任何日志。
  2. Logger 未配置: Feign 默认使用 java.util.logging,但如果我们希望使用 Slf4j 等更常用的日志框架,需要进行配置。
  3. 配置错误: 即使配置了日志级别和 Logger,也可能因为配置错误导致日志无法正确输出。
  4. 依赖缺失: 如果集成了 Logbook,但缺少必要的 Logbook 依赖,也会导致日志无法正常工作。

Slf4jLogger:Feign 日志的桥梁

Slf4j (Simple Logging Facade for Java) 是一种日志门面,它允许我们在代码中使用统一的 API 来记录日志,而无需关心底层具体的日志实现。通过 Slf4jLogger,我们可以将 Feign 的日志输出到我们选择的日志框架(如 Logback、Log4j)中。

配置 Slf4jLogger

首先,确保项目中已经添加了 Slf4j 的依赖。如果使用 Maven,可以在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.9</version>  <!-- 使用最新版本 -->
</dependency>

<!-- 选择具体的日志实现,例如 Logback -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.11</version> <!-- 使用最新版本 -->
    <scope>runtime</scope>
</dependency>

接下来,我们需要配置 Feign 客户端使用 Slf4jLogger。这可以通过以下几种方式实现:

  • 通过 Feign Builder:
import feign.Feign;
import feign.Logger;
import feign.slf4j.Slf4jLogger;

public class FeignClientFactory {

    public static <T> T createClient(Class<T> target, String url) {
        return Feign.builder()
                .logger(new Slf4jLogger(target))
                .logLevel(Logger.Level.FULL) // 设置日志级别
                .target(target, url);
    }

    public static void main(String[] args) {
        // 示例:
        GitHubClient client = createClient(GitHubClient.class, "https://api.github.com");
        // 使用 client 调用 API
    }
}
  • 通过 Spring Cloud OpenFeign 配置:

如果你在使用 Spring Cloud OpenFeign,可以通过配置类来设置 Slf4jLogger

import feign.Logger;
import feign.slf4j.Slf4jLogger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL; // 设置日志级别
    }

    @Bean
    public Slf4jLogger slf4jLogger() {
        return new Slf4jLogger(); // 或者指定具体的 Logger 名称:new Slf4jLogger(GitHubClient.class);
    }
}

配置日志级别

Logger.Level 用于控制 Feign 日志的详细程度,它有以下几种取值:

Logger.Level 描述
NONE 不记录任何日志(默认值)。
BASIC 只记录请求方法、URL 和响应状态码。
HEADERS 记录 BASIC 的信息,以及请求和响应的头部信息。
FULL 记录请求和响应的完整信息,包括请求体和响应体。

根据需要选择合适的日志级别。通常,在开发和调试阶段,建议使用 FULL 级别,以便查看完整的请求和响应信息。在生产环境中,可以根据实际情况选择更低的级别,以减少日志量。

Logbook:强大的 HTTP 请求/响应日志记录工具

Logbook 是一个强大的 Java 库,用于记录 HTTP 请求和响应的详细信息。它提供了灵活的配置选项,可以自定义日志格式、过滤器等。通过与 Feign 集成,我们可以使用 Logbook 来记录 Feign 客户端的请求和响应日志。

集成 Logbook

  1. 添加 Logbook 依赖:

pom.xml 文件中添加 Logbook 的依赖:

<dependency>
    <groupId>org.zalando</groupId>
    <artifactId>logbook-spring-boot-starter</artifactId>
    <version>3.3.0</version> <!-- 使用最新版本 -->
</dependency>
  1. 配置 Logbook:

Logbook 提供了多种配置选项,可以通过 application.propertiesapplication.yml 文件进行配置。以下是一些常用的配置项:

logbook.format.style=http
logbook.strategy=org.zalando.logbook.DefaultStrategy
logbook.obfuscate.defaults=true
#logbook.include= # 可以使用 include 和 exclude 来过滤需要记录的请求
#logbook.exclude=
  • logbook.format.style:指定日志格式,http 表示使用 HTTP 格式。
  • logbook.strategy:指定日志记录策略,DefaultStrategy 是默认策略。
  • logbook.obfuscate.defaults:是否对敏感信息进行脱敏处理。
  • logbook.includelogbook.exclude:用于过滤需要记录的请求。
  1. 配置 Feign 集成 Logbook:

    需要自定义 RequestInterceptorErrorDecoder,并配置到 Feign Client 中。

    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.zalando.logbook.Logbook;
    import org.zalando.logbook.feign.LogbookFeignClientAutoConfiguration;
    
    @Configuration
    public class FeignLogbookConfig {
    
       @Bean
       public RequestInterceptor logbookRequestInterceptor(final Logbook logbook) {
           return new RequestInterceptor() {
               @Override
               public void apply(RequestTemplate template) {
                  // 这里可以通过 logbook 对 request 进行预处理,例如添加 header
               }
           };
       }
    
      // 如果需要自定义 ErrorDecoder 也需要注入Logbook
    }

    此外,还需要禁用 Feign 默认的 Logger,否则会重复打印日志,在 @Configuration 类中添加如下配置:

    import feign.Logger;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class FeignConfig {
    
       @Bean
       Logger.Level feignLoggerLevel() {
           return Logger.Level.NONE; // 禁用 Feign 默认的 Logger
       }
    }

    或者在yml文件中配置:

    feign:
    client:
      config:
        default:
          loggerLevel: none

完整示例

以下是一个完整的示例,展示了如何使用 Slf4jLogger 和 Logbook 集成来记录 Feign 客户端的日志:

  1. Feign 客户端接口:
import feign.Param;
import feign.RequestLine;

public interface GitHubClient {

    @RequestLine("GET /repos/{owner}/{repo}/contributors")
    String contributors(@Param("owner") String owner, @Param("repo") String repo);
}
  1. Feign 配置类:
import feign.Feign;
import feign.Logger;
import feign.slf4j.Slf4jLogger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

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

    @Bean
    public Slf4jLogger slf4jLogger() {
        return new Slf4jLogger();
    }

    @Bean
    public GitHubClient gitHubClient() {
        return Feign.builder()
                .logger(slf4jLogger())
                .logLevel(feignLoggerLevel())
                .target(GitHubClient.class, "https://api.github.com");
    }
}
  1. Logbook 配置:

application.yml 文件中添加以下配置:

logbook:
  format:
    style: http
  strategy: org.zalando.logbook.DefaultStrategy
  obfuscate:
    defaults: true
  1. 测试:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

    @Autowired
    private GitHubClient gitHubClient;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        String contributors = gitHubClient.contributors("OpenFeign", "feign");
        System.out.println(contributors);
    }
}

运行示例代码后,你可以在控制台中看到详细的 Feign 请求和响应日志,包括请求方法、URL、头部信息、请求体和响应体。Logbook 也会记录相同的信息。

常见问题和解决方案

  • 日志没有颜色: 默认情况下,Logback 等日志框架不会为日志添加颜色。可以通过配置 Logback 来启用颜色输出。
  • 敏感信息泄露: 确保启用了 Logbook 的脱敏功能,以防止敏感信息泄露到日志中。
  • 日志量过大: 可以通过调整日志级别和配置过滤器来减少日志量。
  • 依赖冲突: 确保项目中没有不同版本的 Slf4j 和 Logbook 依赖,避免依赖冲突。

示例表格:配置项对比

功能点 Slf4jLogger Logbook
主要作用 将 Feign 的日志输出到 Slf4j 兼容的日志框架中。 记录 HTTP 请求和响应的详细信息,提供灵活的配置选项。
配置方式 通过 Feign Builder 或 Spring Cloud OpenFeign 配置类。 通过 application.propertiesapplication.yml 文件进行配置。
主要配置项 Logger.Level (日志级别) logbook.format.style (日志格式), logbook.strategy (日志记录策略), logbook.obfuscate.defaults (是否脱敏), logbook.includelogbook.exclude (过滤器)
是否需要额外依赖 需要 Slf4j API 和具体的日志实现 (例如 Logback)。 需要 logbook-spring-boot-starter 依赖。
优点 简单易用,与常用的日志框架集成方便。 功能强大,配置灵活,可以自定义日志格式、过滤器等。
缺点 功能相对简单,无法自定义日志格式。 配置相对复杂,需要了解 Logbook 的各种配置选项。

总结:日志配置,清晰可见

通过配置 Slf4jLogger,我们可以将 Feign 的日志输出到我们选择的日志框架中。集成 Logbook,我们可以记录更详细的 HTTP 请求和响应信息,并进行灵活的配置和过滤。合理配置日志级别,避免敏感信息泄露,并根据实际情况调整日志量,可以帮助我们更好地监控和调试 Feign 客户端。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注