Feign自定义打印日志

配置类:

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

@Configuration
public class FeignLoggerConfig {

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

    @Bean
    Logger feignLogger() {
        return new FeignLogger();
    }

}

重写feign.Logger#logRequest方法:

  • 响应拦截

        【记录日志,请求从ThreadLocal获取】

  • 异常拦截
  • 请求拦截

        【将请求保存到ThreadLocal中】

ThreadLocal使用完,则立马删除:get(); remove() set()


import com.alibaba.fastjson.JSON;
import feign.Request;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.*;

import static feign.Util.decodeOrDefault;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * Feign请求日志处理类<br/>
 * 所有通过Feign请求的外部接口都会被监控
 */
@Slf4j
public class FeignLogger extends feign.Logger {

    private static final ThreadLocal<Map<String, String>> logContext = new ThreadLocal<>();

    private static final String PATH = "path";

    private static final String METHOD = "method";

    private static final String REQUEST_BODY = "body";

    private static final String HEADER = "header";

    private static final String TIME = "time";

    /**
     * 构建headers字符串
     */
    private String builderHeaders(Map<String, Collection<String>> headersMap) {
        StringBuilder headers = new StringBuilder();
        Iterator<Map.Entry<String, Collection<String>>> iterator = headersMap.entrySet().stream().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Collection<String>> next = iterator.next();
            ArrayList<String> values = new ArrayList<>(next.getValue());
            headers.append(next.getKey())
                    .append(":")
                    .append(values.size() == 1 ? values.get(0) : JSON.toJSONString(values))
                    .append(iterator.hasNext() ? "|" : "");
        }
        return headers.toString();
    }

    /**
     * 请求拦截
     */
    @Override
    protected void logRequest(String configKey, Level logLevel, Request request) {
        Map<String, String> map = new HashMap<>(3);
        map.put(PATH, request.url());
        map.put(TIME, System.currentTimeMillis() + "");
        map.put(METHOD, request.httpMethod().name());
        map.put(HEADER, builderHeaders(request.headers()));
        String body = request.body() == null ? null : request.charset() == null ? null : new String(request.body(), request.charset());
        //文件上传不打印请求日志
        if (StringUtils.contains(request.url(),"/helper/common/file/upload")) {
            body = null;
        }
        map.put(REQUEST_BODY, body);
        logContext.set(map);
    }


    /**
     * 响应拦截
     */
    @Override
    protected Response logAndRebufferResponse(
            String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
        Map<String, String> request = logContext.get();
        logContext.remove();
        // 返回参数
        byte[] bodyData = streamToByteArray(response.body().asInputStream());
        if (null != bodyData && bodyData.length > 0) {
            String responseBody = decodeOrDefault(bodyData, UTF_8, "Binary data");
            log(request, response.status(), responseBody.replaceAll("\\s*|\t|\r|\n", ""));
            return response.toBuilder().body(bodyData).build();
        }
        log(request, response.status(), null);
        return response;
    }

    /**
     * 异常拦截
     */
    @Override
    protected IOException logIOException(String configKey, Level logLevel, IOException ioe, long elapsedTime) {
        Map<String, String> request = logContext.get();
        log.info("Feign-Error -> \npath -> {}\nmethod -> {}\nheaders -> {}\nrequest -> {}\n",
                request.get(PATH), request.get(METHOD), request.get(HEADER), request.get(REQUEST_BODY)
        );
        logContext.remove();
        return ioe;
    }

    /**
     * 日志打印
     *
     * @param request
     * @param responseStatus
     * @param responseBody
     */
    private void log(Map<String, String> request, Integer responseStatus, String responseBody) {
        log.info("\n<Feign>" +
                        "\npath     -> {}" +
                        "\ntime     -> {}" +
                        "\nmethod   -> {}" +
                        "\nstatus   -> {}" +
                        "\nheaders  -> {}" +
                        "\nrequest  -> {}" +
                        "\nresponse -> {}",
                request.get(PATH),
                (System.currentTimeMillis() - Long.parseLong(request.get(TIME))) + "ms",
                request.get(METHOD),
                responseStatus,
                request.get(HEADER),
                request.get(REQUEST_BODY),
                responseBody
        );
    }

    @Override
    protected void log(String configKey, String format, Object... args) {
        if (log.isInfoEnabled()) {
            log.info(String.format(methodTag(configKey) + format, args));
        }
    }
}



    /**
     * 输入流转byte[]
     *
     * @param inStream 文件流内容
     * @return
     */
    public static byte[] streamToByteArray(InputStream inStream) {
        if (inStream == null) {
            return null;
        }
        byte[] in2b = null;
        BufferedInputStream in = new BufferedInputStream(inStream);
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        int rc = 0;
        try {
            while ((rc = in.read()) != -1) {
                swapStream.write(rc);
            }
            in2b = swapStream.toByteArray();
        } catch (IOException e) {
            log.warn("streamToByteArray exception inStream:[{}]",inStream,e);
        } finally {
            closeIo(inStream, in, swapStream);
        }
        return in2b;
    }



    /**
     * 关闭流
     */
    public static void closeIo(Closeable... closeable) {
        if (null == closeable || closeable.length <= 0) {
            return;
        }
        for (Closeable cb : closeable) {
            try {
                if (null == cb) {
                    continue;
                }
                cb.close();
            } catch (IOException e) {
                throw new RuntimeException(
                        FileUtil.class.getName(), e);
            }
        }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值