SpringCloud Gateway打印请求、响应内容和唯一流水号配置
SpringCloudGateway
默认不打印请求和响应body
,对于问题排查非常不友好。通过以下方式打印请求和响应body
,header
等内容。
实现自定义netty handler
,转发请求和接受响应内容时打印请求内容。
package xxximport io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.UUID;@Slf4j
public class LoggingHandler extends ChannelDuplexHandler {private static final AttributeKey<String> TRACE_ID = AttributeKey.valueOf("traceId");@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {if (msg instanceof ByteBuf) {//定义uuid,用于关联请求和响应内容final String uuid = UUID.randomUUID().toString();if (!ctx.channel().hasAttr(TRACE_ID) || ctx.channel().attr(TRACE_ID).get().equals("")) {ctx.channel().attr(TRACE_ID).set(uuid);}final ByteBuf buf = (ByteBuf) msg;int length = buf.readableBytes();//设置MDC,打印日志时增加traceMDC.put("trace", ctx.channel().attr(TRACE_ID).get());if (length > 0) {final String content = buf.toString(StandardCharsets.UTF_8);final StringBuilder sb = new StringBuilder();Arrays.stream(content.split("\r\n|\n")).forEach(str -> sb.append(str).append("\n"));log.info("request meta: {}", sb.toString());}}super.write(ctx, msg, promise);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof ByteBuf) {if (ctx.channel().hasAttr(TRACE_ID)) {ctx.channel().attr(TRACE_ID).set("");}final ByteBuf buf = (ByteBuf) msg;int length = buf.readableBytes();if (length > 0) {String content = buf.toString(StandardCharsets.UTF_8);final StringBuilder sb = new StringBuilder(length);Arrays.stream(content.split("\r\n|\n")).forEach(str -> sb.append(str).append("\n"));log.info("response meta: {}", sb.toString());}//打印完日志后移除MDC.remove("trace");}super.channelRead(ctx, msg);}
}
配置HttpClient
,增加自定义handler
。
@Component
public class TestHttpClientCustomizer implements HttpClientCustomizer {@Overridepublic HttpClient customize(HttpClient client) {return client.tcpConfiguration(tcpClient ->tcpClient.bootstrap(b -> BootstrapHandlers.updateConfiguration(b, "log",((connectionObserver, channel) -> channel.pipeline().addFirst("log", new LoggingHandler())))));}
}
本人用的是logback
,在logback
配置文件内添加
<?xml version="1.0" encoding="UTF-8"?><configuration><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 添加 [%X{trace:-}] 打印日志时增加自定义的trace --><pattern>%d{HH:mm:ss.SSS} [%X{trace:-}] [%thread] %-5level %logger - %msg %n</pattern></encoder></appender><root level="INFO"><appender-ref ref="CONSOLE"/></root>
</configuration>
日志打印效果,日志内打印了请求内容,如果请求带有body
,内容也会被打印。根据上述配置的uuid
,请求和响应内容对应的日志,增加了唯一流水号,确保日志内请求和响应内容能够对应。
19:02:08.564 [bdd024fc-6bac-4b60-a1d6-8a402c39829f] [reactor-http-nio-4] INFO com.laomei.test.gatewaytest.LoggingHandler - request meta: GET /healthz HTTP/1.1
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en,zh-CN;q=0.9,zh;q=0.8
Forwarded: proto=http;host="localhost:9001";for="0:0:0:0:0:0:0:1:58012"
X-Forwarded-For: 0:0:0:0:0:0:0:1
X-Forwarded-Proto: http
X-Forwarded-Prefix: /READING-INSTANCE
X-Forwarded-Port: 9001
X-Forwarded-Host: localhost:9001
host: 127.0.0.1:9005
content-length: 019:02:08.573 [bdd024fc-6bac-4b60-a1d6-8a402c39829f] [reactor-http-nio-4] INFO com.laomei.test.gatewaytest.LoggingHandler - response meta: HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Content-Length: 15
Date: Mon, 29 Nov 2021 11:02:08 GMT{"status":"UP"}
SpringCloud Gateway打印请求、响应内容和唯一流水号配置相关推荐
- HTTP之请求响应内容详解
(尊重劳动成果,转载请注明出处:http://blog.csdn.NET/qq_25827845/article/details/54562339冷血之心的博客) 目录 HTTP协议(重点) 1 安装 ...
- Web Service之Soap请求响应内容中文编码解密
java模拟Soap请求测试Web Service接口,发现Web Service响应内容中的中文竟然是编码格式.比如: 中文:退保成功 Soap中文编码:退保成功 我仔细分析后发现,退编码实际上就是 ...
- http请求响应的组成部分的介绍 用cherome查看请求响应内容 curl命令行的使用
http请求由3部分组成:请求行 + 请求头 + 请求体 上面是一个GET,和POST请求实例 (1)请求行:由三个组成---请求HTTP的方法,URL,http版本,之间用空格分隔开 (2)请求头: ...
- 通过Fiddler Script替换请求/响应内容
首先点击菜单栏中的Rules->Customize Rules(Crtl+R)打开脚本编辑器.千万千万不要直接点击Fiddler右侧的Fiddler Script,在那里面直接改是不生效的. 抛 ...
- F12 界面:请求响应内容 Preview 和 Response 不一致、接口返回数据和 jsp 解析到的内容不一致
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 情况描述: 我有一个接口只是简单的查询列表数据并返回给前端作一个表格展示. 接口返回的 use ...
- java http打印请求日志_spring打印http接口请求和响应
在程序日志中打印出接口请求和响应的内容是一个基本的技术需求.如果在每个接口中实现请求响应的日志打印,程序编写会很繁琐,我们可以利用spring提供的机制,集中处理接口请求响应的日志打印. 具体的代码参 ...
- springcloud gateway 源码解析、请求响应流程、第三方响应结果在 gateway 的经过
大家好,我是烤鸭: 1. 官方介绍 官方文档: 看的是 2.2.5.RELEASE 版本的 https://docs.spring.io/spring-cloud-gateway/docs/2.2. ...
- Spring Cloud Gateway-ServerWebExchange核心方法与请求或者响应内容的修改
Spring Cloud Gateway-ServerWebExchange核心方法与请求或者响应内容的修改 前提 本文编写的时候使用的Spring Cloud Gateway版本为当时最新的版本Gr ...
- Jmeter书中不会教你的(7)——prev变量用于输出请求和响应内容
前一节讲了利用Dummy Sampler模拟接口请求和响应,实际执行接口时我们需要查看不同的请求内容对应的不同响应是否符合预期,如不符合期望将信息打印出来以便提供开发去查找问题. 利用beanshel ...
最新文章
- 【内网福音】如何离线部署Rancher
- 图灵奖获得者 Alan Kay:突破常规思维,创建下一代科研社区(附视频)
- 软件Trimmomatic
- python opencv 归一化
- 【Visual C++】一些开发心得与调试技巧
- 市电会引起UPS产生故障吗
- 世界是你们的,也是我们的,但终究是他们的!致程序员
- python递归函数的使用方法_让你Python到很爽的加速递归函数的装饰器
- DHCP之二 DHCP的中继代理
- 自己写cache server之网络框架处理——对比mysql、Oracle(上)
- LDA(latent dirichlet allocation)的应用
- exe反编译为py文件
- 公司收银系统要不要服务器,一套收银系统要多少成本
- 中国联通沃支付echop支付插件
- Echarts 地图中地点轮播
- 管理运筹学教程_期末复习_总结笔记
- 活灵活现用Git-技巧篇
- 本地词库翻译php,有道词典词库(您也可以轻松翻译离线的有道词典词库)
- 傅里叶分析之掐死教程
- 49个excel常用技巧(二)