|
@@ -1,9 +1,15 @@
|
|
package cn.com.goldenwater.filter;
|
|
package cn.com.goldenwater.filter;
|
|
|
|
|
|
|
|
+import cn.com.goldenwater.domain.PtService;
|
|
|
|
+import cn.com.goldenwater.domain.PtServiceLog;
|
|
|
|
+import cn.com.goldenwater.service.PtServiceLogService;
|
|
|
|
+import cn.com.goldenwater.service.PtServiceService;
|
|
|
|
+import cn.com.goldenwater.utils.GeoipUtils;
|
|
import cn.com.goldenwater.utils.JsonUtils;
|
|
import cn.com.goldenwater.utils.JsonUtils;
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.reactivestreams.Publisher;
|
|
import org.reactivestreams.Publisher;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
|
import org.springframework.context.annotation.Configuration;
|
|
import org.springframework.context.annotation.Configuration;
|
|
@@ -21,21 +27,34 @@ import reactor.core.publisher.Flux;
|
|
import reactor.core.publisher.Mono;
|
|
import reactor.core.publisher.Mono;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
|
|
+import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
|
|
@Slf4j
|
|
@Slf4j
|
|
@Configuration
|
|
@Configuration
|
|
public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
|
|
public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private PtServiceLogService ptServiceLogService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private PtServiceService ptServiceService;
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
|
try {
|
|
try {
|
|
ServerHttpResponse originalResponse = exchange.getResponse();
|
|
ServerHttpResponse originalResponse = exchange.getResponse();
|
|
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
|
|
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
|
|
HttpStatus statusCode = originalResponse.getStatusCode();
|
|
HttpStatus statusCode = originalResponse.getStatusCode();
|
|
|
|
+
|
|
|
|
+ // 记录请求开始时间
|
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
|
+
|
|
if (statusCode != HttpStatus.OK) {
|
|
if (statusCode != HttpStatus.OK) {
|
|
- return chain.filter(exchange);//降级处理返回数据
|
|
|
|
|
|
+ return chain.filter(exchange); // 降级处理返回数据
|
|
}
|
|
}
|
|
|
|
+
|
|
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
|
|
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
|
|
@Override
|
|
@Override
|
|
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
|
|
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
|
|
@@ -54,6 +73,8 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
|
|
//排除Excel导出,不是application/json不打印。若请求是上传图片则在最上面判断。
|
|
//排除Excel导出,不是application/json不打印。若请求是上传图片则在最上面判断。
|
|
MediaType contentType = originalResponse.getHeaders().getContentType();
|
|
MediaType contentType = originalResponse.getHeaders().getContentType();
|
|
if (!MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
|
|
if (!MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
|
|
|
|
+ // 即使不是JSON也记录日志
|
|
|
|
+ saveServiceLog(exchange, new String(content), System.currentTimeMillis() - startTime, originalResponse.getStatusCode().value());
|
|
return bufferFactory.wrap(content);
|
|
return bufferFactory.wrap(content);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -66,6 +87,9 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
|
|
rspArgs.add(result);
|
|
rspArgs.add(result);
|
|
log.info("<-- {} {}\n{}", rspArgs.toArray());
|
|
log.info("<-- {} {}\n{}", rspArgs.toArray());
|
|
|
|
|
|
|
|
+ // 保存服务日志
|
|
|
|
+ saveServiceLog(exchange, result, System.currentTimeMillis() - startTime, originalResponse.getStatusCode().value());
|
|
|
|
+
|
|
getDelegate().getHeaders().setContentLength(result.getBytes().length);
|
|
getDelegate().getHeaders().setContentLength(result.getBytes().length);
|
|
return bufferFactory.wrap(result.getBytes());
|
|
return bufferFactory.wrap(result.getBytes());
|
|
}));
|
|
}));
|
|
@@ -88,33 +112,53 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
|
|
return Ordered.HIGHEST_PRECEDENCE;
|
|
return Ordered.HIGHEST_PRECEDENCE;
|
|
}
|
|
}
|
|
|
|
|
|
- //返回统一的JSON日期数据 2024-02-23 11:00, null转空字符串
|
|
|
|
|
|
+ // 返回统一的JSON日期数据 2024-02-23 11:00, null转空字符串
|
|
private String modifyBody(String jsonStr) {
|
|
private String modifyBody(String jsonStr) {
|
|
JSONObject json = JsonUtils.jsonToPojo(jsonStr, JSONObject.class);
|
|
JSONObject json = JsonUtils.jsonToPojo(jsonStr, JSONObject.class);
|
|
return JsonUtils.objectToJson(json);
|
|
return JsonUtils.objectToJson(json);
|
|
}
|
|
}
|
|
|
|
|
|
-// public void setJSONObjectWriteNullStringAsEmpty() {
|
|
|
|
-// JSON.toJSONString(data,SerializerFeature.WriteNullStringAsEmpty);
|
|
|
|
-// JSONObject jsonObj = JSON.parseObject(data, Feature.AllowISO8601DateFormat);
|
|
|
|
-// JSON.toJSONString(data,SerializerFeature.DisableCircularReferenceDetect);
|
|
|
|
-// JSONObject.DEFFAULT_DATE_FORMAT ="yyyy-MM-dd HH:mm";
|
|
|
|
-// JSONObject.toJSONString(jsonObject,SerializerFeature.WriteDateUseDateFormat);
|
|
|
|
-//
|
|
|
|
-// String dataJson = JSON.toJSONString(data, (ValueFilter) (object, name, value) -> {
|
|
|
|
-// log.info("data:{} ", data);
|
|
|
|
-//
|
|
|
|
-// log.info("object:{}, name:{}, value:{}", object, name, value);
|
|
|
|
-// if (value == null) {
|
|
|
|
-// return "";
|
|
|
|
-// }
|
|
|
|
-// return value;
|
|
|
|
-// });
|
|
|
|
-// JSONObject jsonObject = new JSONObject();
|
|
|
|
-// 把json对象转换成字节数组
|
|
|
|
-// byte[] bits = data.getBytes(StandardCharsets.UTF_8);
|
|
|
|
-// DataBuffer buffer = originalResponse.bufferFactory().wrap(bits);
|
|
|
|
-// originalResponse.writeWith(Mono.just(buffer));
|
|
|
|
-// }
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 保存服务日志到数据库
|
|
|
|
+ */
|
|
|
|
+ private void saveServiceLog(ServerWebExchange exchange, String responseContent, long execTime, int statusCode) {
|
|
|
|
+ try {
|
|
|
|
+ PtServiceLog serviceLog = new PtServiceLog();
|
|
|
|
+ // 设置日志字段
|
|
|
|
+ serviceLog.setTm(new Date());
|
|
|
|
+ serviceLog.setSenText(exchange.getRequest().getURI().toString());
|
|
|
|
+ serviceLog.setReturnText(responseContent);
|
|
|
|
+ serviceLog.setExecTm(execTime);
|
|
|
|
+ serviceLog.setStatusCode((long) statusCode);
|
|
|
|
+
|
|
|
|
+ // 获取客户端IP
|
|
|
|
+ String clientIp = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
|
|
|
|
+ if (clientIp == null || clientIp.isEmpty()) {
|
|
|
|
+ clientIp = exchange.getRequest().getRemoteAddress() != null ?
|
|
|
|
+ exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() : "unknown";
|
|
|
|
+ }
|
|
|
|
+ serviceLog.setClientIp(clientIp);
|
|
|
|
+
|
|
|
|
+ Map<String, Object> geoCity = GeoipUtils.getGeoCity(clientIp);
|
|
|
|
+ if (geoCity != null) {
|
|
|
|
+ serviceLog.setGeoCity((String) geoCity.get("city"));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 通过URL获取服务信息
|
|
|
|
+ String requestUrl = exchange.getRequest().getURI().getPath();
|
|
|
|
+ PtService ptService = ptServiceService.getServiceByUrl(requestUrl);
|
|
|
|
+ if (ptService != null) {
|
|
|
|
+ serviceLog.setServiceName(ptService.getName());
|
|
|
|
+ serviceLog.setSerId(ptService.getSrvId());
|
|
|
|
+ serviceLog.setMdId(ptService.getMdid());
|
|
|
|
+ } else {
|
|
|
|
+ serviceLog.setServiceName("未找到服务信息");
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ // 异步保存日志
|
|
|
|
+ ptServiceLogService.save(serviceLog);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("保存服务日志异常: ", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|