From f0fa36d005884fe982336783fd9dc40a99e47f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Mon, 30 May 2022 21:30:39 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E5=A2=9E=E5=8A=A0=20=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E6=97=A5=E5=BF=97=20=E8=BF=87=E6=BB=A4=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/dev/ruoyi-gateway.yml | 2 + .../properties/CustomGatewayProperties.java | 24 ++++ .../ruoyi/gateway/filter/GlobalLogFilter.java | 120 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CustomGatewayProperties.java create mode 100644 ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/GlobalLogFilter.java diff --git a/config/dev/ruoyi-gateway.yml b/config/dev/ruoyi-gateway.yml index deb3fe97..4ee7cd6a 100644 --- a/config/dev/ruoyi-gateway.yml +++ b/config/dev/ruoyi-gateway.yml @@ -34,6 +34,8 @@ spring: cloud: # 网关配置 gateway: + # 打印请求日志(自定义) + requestLog: true discovery: locator: lowerCaseServiceId: true diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CustomGatewayProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CustomGatewayProperties.java new file mode 100644 index 00000000..4b520f91 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CustomGatewayProperties.java @@ -0,0 +1,24 @@ +package com.ruoyi.gateway.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 自定义gateway参数配置 + * + * @author Lion Li + */ +@Data +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "spring.cloud.gateway") +public class CustomGatewayProperties { + + /** + * 请求日志 + */ + private Boolean requestLog; + +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/GlobalLogFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/GlobalLogFilter.java new file mode 100644 index 00000000..f33a83ac --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/GlobalLogFilter.java @@ -0,0 +1,120 @@ +package com.ruoyi.gateway.filter; + +import cn.hutool.core.map.MapUtil; +import com.ruoyi.common.core.utils.JsonUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.gateway.config.properties.CustomGatewayProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashSet; + +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR; + +/** + * 全局日志过滤器 + *

+ * 用于打印请求执行参数与响应时间等等 + * + * @author Lion Li + */ +@Slf4j +@Component +public class GlobalLogFilter implements GlobalFilter, Ordered { + + @Autowired + private CustomGatewayProperties customGatewayProperties; + + private static final String START_TIME = "startTime"; + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + ServerHttpRequest request = exchange.getRequest(); + String path = getOriginalRequestUrl(exchange); + String url = request.getMethod().name() + " " + path; + + if (!customGatewayProperties.getRequestLog()) { + return chain.filter(exchange); + } + // 打印请求参数 + if (isJsonRequest(request)) { + ServerHttpRequestDecorator decorator = (ServerHttpRequestDecorator) + exchange.getAttributes().get(CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR); + String jsonParam = resolveBodyFromRequest(decorator); + log.debug("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam); + } else { + MultiValueMap parameterMap = request.getQueryParams(); + if (MapUtil.isNotEmpty(parameterMap)) { + String parameters = JsonUtils.toJsonString(parameterMap); + log.debug("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters); + } else { + log.debug("[PLUS]开始请求 => URL[{}],无参数", url); + } + } + + exchange.getAttributes().put(START_TIME, System.currentTimeMillis()); + return chain.filter(exchange).then(Mono.fromRunnable(() -> { + Long startTime = exchange.getAttribute(START_TIME); + if (startTime != null) { + long executeTime = (System.currentTimeMillis() - startTime); + log.debug("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", url, executeTime); + } + })); + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } + + /** + * 判断本次请求的数据类型是否为json + * + * @param request request + * @return boolean + */ + private boolean isJsonRequest(ServerHttpRequest request) { + MediaType contentType = request.getHeaders().getContentType(); + if (contentType != null) { + return StringUtils.startsWithIgnoreCase(contentType.toString(), MediaType.APPLICATION_JSON_VALUE); + } + return false; + } + + private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) { + //获取请求体 + Flux body = serverHttpRequest.getBody(); + StringBuilder sb = new StringBuilder(); + body.subscribe(buffer -> { + byte[] bytes = new byte[buffer.readableByteCount()]; + buffer.read(bytes); + String bodyString = new String(bytes, StandardCharsets.UTF_8); + sb.append(bodyString); + }); + return sb.toString(); + } + + public static String getOriginalRequestUrl(ServerWebExchange exchange) { + ServerHttpRequest request = exchange.getRequest(); + LinkedHashSet uris = exchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR); + URI requestUri = uris.stream().findFirst().orElse(request.getURI()); + return UriComponentsBuilder.fromPath(requestUri.getRawPath()).build().toUriString(); + } + +}