首页 > 其他分享 >Gateway 代理日志记录 Filter

Gateway 代理日志记录 Filter

时间:2022-12-14 18:33:23浏览次数:37  
标签:------------ ch image Fetch Filter application 日志 ua Gateway


前言

我们在使用网关的时候,有时候客户端会有莫名其妙的问题需要服务端辅助定位,这时候有一份完全的请求的信息的日志会非常有帮助,这里提供一种基于过滤器的实现方式。

我的实现方式是作为一个工程来实现的,方便后续的引用

Gateway 代理日志记录 Filter_java


pom.xml依赖

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>

过滤器 实现类

package com.spacetime.gateway.recorder.config;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Component
@ConditionalOnProperty(value = "gateway.log.enable", matchIfMissing = true)
public class GatewayLoggerProfile {
public static final String LOGGER_NAME = "requestRecorder";

@Value("${logging.path}")
private String logPath;

//@Value("${logging.pattern.file}")
String logPattern = "%date %level [%thread] %logger{36} [%file : %line] %msg%n";

@PostConstruct
public void onReady() {
LoggerContext context = (LoggerContext)StaticLoggerBinder.getSingleton().getLoggerFactory();

//把 log 写入到专门的文件中
Logger logger = context.getLogger(LOGGER_NAME);
logger.detachAndStopAllAppenders();

String logFile = null;
if (logPath.endsWith("/"))
logFile = logPath + "pv/pv.log";
else
logFile = logPath + "/pv/pv.log";

//以下代码 通过反编译 log组件代码发现的, 不保证时效性
RollingFileAppender<ILoggingEvent> appender = new RollingFileAppender<>();
appender.setFile(logFile);

PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setPattern(logPattern);
encoder.setContext(context);
encoder.setParent(appender);
appender.setEncoder(encoder);
encoder.start();

TimeBasedRollingPolicy policy = new TimeBasedRollingPolicy();
policy.setCleanHistoryOnStart(false);
policy.setMaxHistory(30);
policy.setContext(context);
policy.setFileNamePattern(logFile + ".%d{yyyy-MM-dd}.gz");
policy.setParent(appender);
appender.setRollingPolicy(policy);
policy.start();

appender.setName(LOGGER_NAME + "-appender");
appender.setContext(context);
appender.start();

logger.addAppender(appender);

logger.setAdditive(false);
}
}

辅助类 RecorderServerHttpRequestDecorator

package com.spacetime.gateway.recorder.filter;

import com.spacetime.gateway.recorder.filter.util.DataBufferUtilFix;
import com.spacetime.gateway.recorder.filter.util.DataBufferWrapper;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class RecorderServerHttpRequestDecorator extends ServerHttpRequestDecorator {
private DataBufferWrapper data = null;

public RecorderServerHttpRequestDecorator(ServerHttpRequest delegate) {
super(delegate);
}

@Override
public Flux<DataBuffer> getBody() {
synchronized (this) {
Mono<DataBuffer> mono = null;
if (data == null) {
mono = DataBufferUtilFix.join(super.getBody())
.doOnNext(d -> this.data = d)
.filter(d -> d.getFactory() != null)
.map(DataBufferWrapper::newDataBuffer);
} else {
mono = Mono.justOrEmpty(data.newDataBuffer());
}

return Flux.from(mono);
}
}
}
package com.spacetime.gateway.recorder.filter;


import com.spacetime.gateway.recorder.filter.util.DataBufferUtilFix;
import com.spacetime.gateway.recorder.filter.util.DataBufferWrapper;
import org.reactivestreams.Publisher;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class RecorderServerHttpResponseDecorator extends ServerHttpResponseDecorator {
private DataBufferWrapper data = null;

public RecorderServerHttpResponseDecorator(ServerHttpResponse delegate) {
super(delegate);
}

@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
return DataBufferUtilFix.join(Flux.from(body))
.doOnNext(d -> this.data = d)
.flatMap(d -> super.writeWith(copy()));
}

@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body)
.flatMapSequential(p -> p));
}

public Flux<DataBuffer> copy() {
//如果data为null 就出错了 正好可以调试
DataBuffer buffer = this.data.newDataBuffer();
if (buffer == null)
return Flux.empty();

return Flux.just(buffer);
}
}

实现的效果如下:

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:39 GMT
------------body------------
1212
------------ end ------------





2022-10-21 22:47:40,235 INFO [reactor-http-nio-6] requestRecorder [LowerRequestRecorderGlobalFilter.java : 57]
---------------------------
原始请求:
GET http://127.0.0.1:8100/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:39 GMT
------------body------------
1212
------------ end ------------





2022-10-21 22:47:40,421 INFO [reactor-http-nio-6] requestRecorder [LowerRequestRecorderGlobalFilter.java : 57]
---------------------------
原始请求:
GET http://127.0.0.1:8100/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:39 GMT
------------body------------
1212
------------ end ------------





2022-10-21 22:47:40,594 INFO [reactor-http-nio-6] requestRecorder [LowerRequestRecorderGlobalFilter.java : 57]
---------------------------
原始请求:
GET http://127.0.0.1:8100/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:40 GMT
------------body------------
1212
------------ end ------------





2022-10-21 22:47:40,949 INFO [reactor-http-nio-6] requestRecorder [LowerRequestRecorderGlobalFilter.java : 57]
---------------------------
原始请求:
GET http://127.0.0.1:8100/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:40 GMT
------------body------------
1212
------------ end ------------





2022-10-21 22:47:41,106 INFO [reactor-http-nio-6] requestRecorder [LowerRequestRecorderGlobalFilter.java : 57]
---------------------------
原始请求:
GET http://127.0.0.1:8100/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

代理请求:
GET http://192.168.30.1:8210/usermgr/user/id
------------请求头------------
Host:127.0.0.1:8100
Connection:keep-alive
Cache-Control:max-age=0
sec-ch-ua:"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile:?0
sec-ch-ua-platform:"Windows"
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
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:zh-CN,zh;q=0.9
------------ end ------------

响应:200 OK
------------响应头------------
transfer-encoding:chunked
Content-Type:application/json
Date:Fri, 21 Oct 2022 14:47:40 GMT
------------body------------
1212
------------ end ------------


标签:------------,ch,image,Fetch,Filter,application,日志,ua,Gateway
From: https://blog.51cto.com/u_15461374/5938174

相关文章

  • asp.net core 微服务网关示例 ocelot gateway Demo
    ocelotasp.netcore微服务gateway介绍https://ocelot.readthedocs.io/en/latest/introduction/gettingstarted.html 1.新建asp.netcorewebapi空项目AProject,nug......
  • 今日份JS解密日志
    今天拿到手的JS加密源代码如下functionenterKeyDown(_0x28623b){const_0x32979d=_0x58fe;const_0xde64a8=_0x1d66;try{let_0x1f57e5=msgIn......
  • spring-cloud-alibaba-整合spring-clouid-gateway-3.1.4
    spring-cloud-alibaba-整合spring-clouid-gateway-3.1.4spring-cloud-alibaba-整合spring-clouid-gateway-3.1.4前言版本说明引入spring-cloud-gatewayspring-cloud......
  • Zuul和Gateway
    Zuul是Netflix公司提供的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,实现认证和安全、性能监测、动态路由、负载均衡、压力测试、静态资源处理等功能。Gate......
  • ELK+Filebeat日志分析系统
    一、ELK简介ELK平台是一套完整的日志集中处理解决方案,将ElasticSearch、Logstash和Kiabana三个开源工具配合使用,完成更强大的用户对日志的查询、排序、统计需求。1......
  • 重启mysql的时候,mysql日志也会抛错错误
    修改mysql配置文件,移动mysql数据存储位置修改。重启mysql的时候,mysql日志也会抛错错误2021-11-27T00:34:43.403963Z0[ERROR]Failedtoopenlog(file'/logs/mysq......
  • 06-Go日志库Zap简单二次封装
    Go日志库Zap简单二次封装1.在项目根目录或者项目其他目录下创建二次封装代码存放目录zaplog,其他目录名称也可以2.新建config.go文件和zaplog文件,文件内容如下:config.g......
  • Filter过滤器
    1.使用方法: 2.执行流程:      3.拦截路径配置 4.过滤器链(遵循自然排序如aFilter,bFilter依次执行) ......
  • @Order和Ordered在gateway中的异常情况
    使用场景多个过滤器时,确定执行的先后顺序.注意是过滤器执行的先后顺序,不是加载的先后顺序值越小,越先执行@ComponentpublicclassGlobalLogFilterimplementsGloba......
  • springMvc32-原生apiSpring MVC过滤器-HiddenHttpMethodFilter
    浏览器form​​表单​​只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE......