Java skill - 自定义feign调用日志打印

背景描述

大家应该都用过Feign的日志打印,日志级别分为NONE、BASIC、HEADERS、FULL,一般咱们用的是BASIC,下面,我给大家展示一下除了NONE之外,另外三种日志级别的日志打印情况。

BASIC

[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] <--- HTTP/1.1 200 (327ms)

HEADERS

[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Authorization: Bearer XXXX
[testClient#test] Content-Length: 384
[testClient#test] Content-Type: application/json
[testClient#test] logger_id: 8cef4448f21640b0b12fdc8ac4e478e6
[testClient#test] ---> END HTTP (384-byte body)
[testClient#test] <--- HTTP/1.1 200 (327ms)
[testClient#test] connection: keep-alive
[testClient#test] content-type: application/json;charset=UTF-8
[testClient#test] date: Thu, 09 Nov 2023 03:19:59 GMT
[testClient#test] keep-alive: timeout=60
[testClient#test] transfer-encoding: chunked
[testClient#test] <--- END HTTP (51-byte body)

FULL

[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Authorization: Bearer XXXX
[testClient#test] Content-Length: 383
[testClient#test] Content-Type: application/json
[testClient#test] logger_id: eaa807b1a34c4b56a66c92dc083235bd
[testClient#test]
[testClient#test] {"test":"123"}
[testClient#test] ---> END HTTP (383-byte body)
[testClient#test] <--- HTTP/1.1 200 (336ms)
[testClient#test] connection: keep-alive
[testClient#test] content-type: application/json;charset=UTF-8
[testClient#test] date: Wed, 08 Nov 2023 06:04:04 GMT
[testClient#test] keep-alive: timeout=60
[testClient#test] transfer-encoding: chunked
[testClient#test]
[testClient#test] {"code":2002,"msg":"OK","data":null}
[testClient#test] <--- END HTTP (51-byte body)

总结

由上日志打印情况可知以下缺点:

  1. BASIC 打印日志太少。
  2. HEADERS 和 FULL 打印日志太多,且大多数没有用。
  3. 我想打印请求体和响应体,只能选用 FULL ,但是打印的日志真的多。

代码实现

FeignConfig配置类新增日志级别配置

@Configuration
public class FeignConfig {
	@Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.BASIC;
    }

    @Bean
    Logger QjxFeign() {
        return new QjxFeignLogger(log);
    }	
}

QjxFeignLogger类自定义日志打印

import feign.Request;
import feign.Response;
import feign.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static feign.Util.*;

public class QjxFeignLogger extends feign.Logger {

    private final Logger logger;

    public QjxFeignLogger() {
        this(feign.Logger.class);
    }

    public QjxFeignLogger(Class<?> clazz) {
        this(LoggerFactory.getLogger(clazz));
    }


    QjxFeignLogger(Logger logger) {
        this.logger = logger;
    }


    @Override
    protected void logRequest(String configKey, 
                              Level logLevel, 
                              Request request) {
        // 如果是info日志级别,进入自定义打印逻辑
        if (logger.isInfoEnabled()) {
            // 打印访问接口url地址
            log(configKey, "---> %s %s HTTP/1.1", 
                    request.httpMethod().name(), request.url());
            // 获取请求体并打印
            String bodyText =
                    request.charset() != null
                            ? new String(request.body(), request.charset())
                            : null;
            log(configKey, "Request Body:%s", 
                    bodyText != null ? bodyText : "Binary data");
        }
    }

    @Override
    protected Response logAndRebufferResponse(String configKey, 
                                              Level logLevel, 
                                              Response response, 
                                              long elapsedTime)
            throws IOException {
        // 如果是info日志级别,进入自定义打印逻辑
        if (logger.isInfoEnabled()) {
            return myResponse(configKey, logLevel, response, elapsedTime);
        }
        return response;
    }

    protected Response myResponse(String configKey,
                                  Level logLevel,
                                  Response response,
                                  long elapsedTime)
            throws IOException {
        String reason = response.reason() != null  ? response.reason() : "";
        int status = response.status();
        // 打印调用接口响应时长
        log(configKey, "<--- HTTP/1.1 %s %s (%sms)", 
                status, reason, elapsedTime);
        // 获取响应体并打印
        byte[] bodyData = Util.toByteArray(response.body().asInputStream());
        int bodyLength = bodyData.length;
        if (bodyLength > 0) {
            log(configKey, "Response Body:%s", 
                    decodeOrDefault(bodyData, UTF_8, "Binary data"));
        }
        return response.toBuilder().body(bodyData).build();
    }

    @Override
    protected void log(String configKey, String format, Object... args) {
        if (logger.isInfoEnabled()) {
            // 打印信息格式化
            logger.info(String.format(methodTag(configKey) + format, args));
        }
    }
}

自定义后日志打印情况

[testClient#test] ---> POST http://test/test HTTP/1.1
[testClient#test] Request Body:{"test":"123"}
[testClient#test] <--- HTTP/1.1 200  (328ms)
[testClient#test] Response Body:{"code":2002,"msg":"OK","data":null}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值