Skip to main content

为什么要记录 Feign 日志

踩坑归来,最近在调试一个服务接口的时候,明明上游服务传递的参数都是正确的,下游服务接收到的请求就莫名其妙的丢失。在微服务中,OpenFeign 通过声明式 HTTP 客户端屏蔽了底层细节,调用简洁但也容易”看不到”请求与响应的真实数据。启用并合理配置 Feign 日志可以帮助你:
  • 追踪请求方法、URL、状态码与耗时
  • 审计请求/响应头与主体
  • 快速定位序列化、鉴权、网关或下游异常

日志级别概览

Feign 提供 4 个日志级别,常见选择如下:
  • NONE:默认,不输出日志
  • BASIC:方法、URL、响应状态、耗时
  • HEADERS:BASIC + 请求/响应头
  • FULL:最详细,包含头、正文与元数据(开发/问题定位推荐)

方式一:通过配置文件开启 DEBUG 与级别

application.yml 中为 Feign 接口包或类开启 DEBUG,并设置 Logger Level:
logging:
  level:
    com.example.feign: DEBUG
结合一个最小化的 Feign Logger Level Bean:
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PigFeignLogConfig {

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
在客户端上显式引用配置(可选,若使用全局配置可省略):
import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(name = "pig-example-client", configuration = PigFeignLogConfig.class)
public interface PigExampleClient {
    // 声明式方法定义
}

方式二:自定义 Feign Logger(更灵活)

当需要按需裁剪日志内容与格式(如屏蔽敏感字段、统一 JSON 输出、聚合 traceId)时,可自定义 Logger:
import feign.Logger;
import feign.Request;
import feign.Response;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class PigFeignLogger extends Logger {

    @Override
    protected void logRequest(String configKey, Level logLevel, Request request) {
        // 可添加 traceId、脱敏、统一格式化等
        super.logRequest(configKey, logLevel, request);
    }

    @Override
    protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
        // 可在此读取并重放响应体(注意内存与大包风险)
        return super.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
    }

    @Override
    protected void log(String configKey, String format, Object... args) {
        // 将输出接入统一日志框架或结构化日志
        System.out.printf((format) + "%n", args);
    }
}
把自定义 Logger 注入到配置中:
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PigCustomFeignLogConfig {

    @Bean
    public Logger feignLogger() {
        return new PigFeignLogger();
    }

    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}
客户端绑定该配置:
import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(name = "pig-custom-client", configuration = PigCustomFeignLogConfig.class)
public interface PigCustomClient {
    // 声明式方法定义
}

实战建议

  • 在开发/测试环境使用 FULL,生产建议结合采样与脱敏,避免过量 IO 与泄露敏感信息
  • 使用 logging.level 精确到包或类,降低无关噪音
  • 对大响应体谨慎 rebuffer,必要时只记录摘要或关键字段
  • 统一 traceId/请求 ID,便于跨服务追踪

常见问题

  • 已配置 FULL 但无输出:确认 logging.level 指到了接口包或类,并且 Spring Cloud OpenFeign 已启用
  • 日志乱码:确保控制台与日志文件编码一致(UTF-8),必要时显示转换

参考

  • Spring Cloud OpenFeign 文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/