一、场景介绍
在通常情况下,微服务的业务功能都需要通过网关来进行转发,记录业务请求日志通过网关来记录是最有利的方式。
二、演示代码
-
测试版本
组件名 版本号 Spring Boot 2.2.5.RELEASE Spring Cloud Hoxton.SR3 Spring Cloud Alibaba 2.2.1.RELEASE -
测试代码
import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction; import org.springframework.core.Ordered; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import javax.annotation.PostConstruct; /** * @ClassName: CustomGlobalLogFilter * @Description: 自定义全局日志过滤器(借用 ModifyRequestBodyGatewayFilterFactory, 该类的本身功能是为了修改请求体数据的, 这里也是比较巧妙的利用了他本身已经对请求体参数进行了封装, 在 RewriteFunction 中可以直接拿到请求参数的特点) * @Author: Rambo * @CreateDate: 2020/7/5 21:43 * @UpdateUser: Rambo * @UpdateDate: 2020/7/5 21:43 * @Version: 1.0.0 */ @Component @Slf4j public class CustomRequestGlobalLogFilter implements GlobalFilter, Ordered { private GatewayFilter delegate; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 获取请求对象 ServerHttpRequest request = exchange.getRequest(); // 获取请求参数信息 MediaType contentType = request.getHeaders().getContentType(); log.info("------------------------> REQUEST URI = [{}]" , request.getURI()); log.info("------------------------> REQUEST HEADER = [{}]" , request.getHeaders()); log.info("------------------------> REQUEST METHOD = [{}]" , request.getMethodValue()); if (HttpMethod.GET == request.getMethod()) { log.info("------------------------> REQUEST PARAMS = [{}]" , JSON.toJSONString(request.getQueryParams().toSingleValueMap())); // 正常放行的处理,进入下一个过滤链 return chain.filter(exchange); // 只能读取到 contentType 为 application/json 的数据 } else if (contentType.equals(MediaType.APPLICATION_JSON) || contentType.equals(MediaType.APPLICATION_JSON_UTF8)){ return delegate.filter(exchange, chain); } // 正常放行的处理,进入下一个过滤链 return chain.filter(exchange); } @PostConstruct public void init() { this.delegate = new ModifyRequestBodyGatewayFilterFactory().apply(this.getConfig()); } private ModifyRequestBodyGatewayFilterFactory.Config getConfig() { ModifyRequestBodyGatewayFilterFactory.Config cf = new ModifyRequestBodyGatewayFilterFactory.Config(); cf.setRewriteFunction(Object.class, Object.class, getRewriteFunction()); return cf; } private RewriteFunction<Object, Object> getRewriteFunction() { return (serverWebExchange, body) -> { // 这里的 body 就是请求体参数, 类型是 LinkedHashMap, 可以根据需要转成JSON log.info("------------------------> REQUEST PARAMS = [{}]", JSON.toJSONString(body)); return Mono.just(body); }; } @Override public int getOrder() { // 定义过滤链的顺序 return 0; } }