|  | @@ -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);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  }
 |  |  }
 |