Przeglądaj źródła

添加告警信息记录

Lin Qilong 1 miesiąc temu
rodzic
commit
9856412433

+ 16 - 0
src/main/java/cn/com/goldenwater/domain/GatewayRoutes.java

@@ -1,6 +1,8 @@
 package cn.com.goldenwater.domain;
 
+import cn.com.goldenwater.utils.JsonUtils;
 import cn.com.goldenwater.utils.StringUtils;
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import org.springframework.cloud.gateway.filter.FilterDefinition;
@@ -9,6 +11,7 @@ import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @Data
 @TableName
@@ -20,6 +23,10 @@ public class GatewayRoutes implements Serializable {
     private String predicates;
     private String filters;
     private String status;
+    /**
+     * 响应成功格式
+     */
+    private String resultSuccessFormat;
 
     public List<PredicateDefinition> getPredicateDefinition() {
         if (this.predicates != null) {
@@ -53,4 +60,13 @@ public class GatewayRoutes implements Serializable {
         }
     }
 
+
+    public JSONObject getResultSuccessFormatData() {
+        if (StringUtils.isNoneBlank(this.resultSuccessFormat)) {
+            return JsonUtils.jsonToPojo(this.resultSuccessFormat, JSONObject.class);
+        } else {
+            return JsonUtils.jsonToPojo("{\"code\":\"200\",\"field\":\"code\"}", JSONObject.class);
+        }
+    }
+
 }

+ 329 - 0
src/main/java/cn/com/goldenwater/domain/MdModelInfo.java

@@ -0,0 +1,329 @@
+package cn.com.goldenwater.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 模型信息对象 md_model_info
+ *
+ * @author 朱得糠
+ * @date 2025-07-31
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@TableName
+public class MdModelInfo {
+
+    /**
+     * 模型标识
+     */
+    @TableId
+    private String mdid;
+
+    /**
+     * 模型名称
+     */
+    private String name;
+
+    /**
+     * 模型英文名称
+     */
+    private String enname;
+
+    /**
+     * 目录标识
+     */
+    private String cateid;
+
+    /**
+     * 开发语言
+     */
+    private String devlang;
+
+    /**
+     * 模型版本号
+     */
+    private String version;
+
+    /**
+     * 模型介绍,简介
+     */
+    private String intro;
+
+    /**
+     * 模型分类
+     */
+    private String type;
+
+    /**
+     * 模型标签
+     */
+    private String tags;
+
+    /**
+     * 模型类别
+     */
+    private String kind;
+    /**
+     * 模型用途
+     */
+    private String purpose;
+    /**
+     * 可否率定
+     */
+    private Integer israte;
+    /**
+     * 权值
+     */
+    private Double weight;
+    /**
+     * 区分系统内的模型,还是第三方的模型
+     */
+    private String devkind;
+
+
+    /**
+     * 开发者用户编号
+     */
+    private String author;
+
+    /**
+     * 是否发布
+     */
+    private Integer ispublic;
+
+    /**
+     * 是否审核
+     */
+    private Integer isapproved;
+
+    /**
+     * 模型状态
+     */
+    private Integer status;
+
+    /**
+     * 模型类名
+     */
+    private String classname;
+
+    /**
+     * 模型运行命令
+     */
+    private String mdRunCmd;
+
+    /**
+     * 模型URL地址
+     */
+    private String mdUrl;
+
+    /**
+     * 模型验证类型
+     */
+    private String mdAuth;
+
+    /**
+     * 模型Header项
+     */
+    private String mdHeader;
+
+    /**
+     * 模型TOKEN Sercet
+     */
+    private String mdSecret;
+
+    /**
+     * 模型提供单位
+     */
+    private String mdUnit;
+
+    /**
+     * 模型单位联系方式
+     */
+    private String mdContact;
+
+    /**
+     * 开发单位,技术支撑单位
+     */
+    private String devUnit;
+
+    /**
+     * 开发单位联系方式
+     */
+    private String devContact;
+
+    /**
+     * 是否使用WebHook
+     */
+    private Integer whFlag;
+
+    /**
+     * 模型消息WebHook URL地址
+     */
+    private String whUrl;
+
+    /**
+     * WebHook请求方法
+     */
+    private String whMethod;
+
+    /**
+     * WebHook验证类型
+     */
+    private String whAuth;
+
+    /**
+     * WebHook Header项
+     */
+    private String whHeader;
+
+    /**
+     * WebHook TOKEN Sercet
+     */
+    private String whSecret;
+
+    /**
+     * 模型运行服务器操作系统
+     */
+    private String envOs;
+
+    /**
+     * 模型运行服务器架构
+     */
+    private String evnArmX86;
+
+    /**
+     * 模型CPU核心数
+     */
+    private Integer envCpu;
+
+    /**
+     * GPU类型
+     */
+    private String envGpuType;
+
+    /**
+     * GPU数量
+     */
+    private Integer envGpuNum;
+
+    /**
+     * GPU显存大小
+     */
+    private Integer envGpuMem;
+
+    /**
+     * 所需存储空间大小
+     */
+    private Integer envDisk;
+
+    /**
+     * 所需内存大小
+     */
+    private Integer envMem;
+
+    /**
+     * 部署服务器IP
+     */
+    private String deployIp;
+
+    /**
+     * 部署目录
+     */
+    private String deployDir;
+
+    /**
+     * 部署端口
+     */
+    private String deployPort;
+
+    /**
+     * 部署说明
+     */
+    private String deployNote;
+
+    /**
+     * 模型输入文件名称
+     */
+    private String mdInName;
+
+    /**
+     * 模型输入文件存储路径
+     */
+    private String mdInFile;
+
+    /**
+     * 模型输入说明
+     */
+    private String mdInNote;
+
+    /**
+     * 模型输出文件名称
+     */
+    private String mdOutName;
+
+    /**
+     * 模型输出文件存储路径
+     */
+    private String mdOutFile;
+
+    /**
+     * 模型输出说明
+     */
+    private String mdOutNote;
+
+    /**
+     * 模型镜像名称
+     */
+    private String mirrorImageName;
+
+    /**
+     * 模型镜像地址/服务地址
+     */
+    private String mirrorImageUrl;
+
+    /**
+     * 模型对应文件描述表
+     */
+    private String mirrorImageDesc;
+
+    /**
+     * 验证url
+     */
+    private String mdAuthUrl;
+
+    /**
+     * 编辑时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date modifyby;
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date createby;
+
+    /**
+     * 注册人员
+     */
+    private String regUser;
+    /**
+     * 顺序
+     */
+    private Integer sort;
+
+    /**
+     * 审核状态
+     * 审核状态 0=待审核;1=已审核;2 = 驳回
+     */
+    private String audit;
+
+}
+

+ 36 - 0
src/main/java/cn/com/goldenwater/domain/PtServiceAlarm.java

@@ -0,0 +1,36 @@
+package cn.com.goldenwater.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * entity:PtServiceAlarm
+ *
+ * @author lql
+ * @date 2025-9-17
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName
+public class PtServiceAlarm implements Serializable {
+
+    @TableId
+    private Long alertId;
+    private String mdid;
+    private String modelName;
+    private String srvId;
+    private String serviceName;
+    private Date alertTime;
+    private String alertType;
+    private String alertContent;
+    private String notifyStatus;
+    private Date createTime;
+
+}

+ 8 - 4
src/main/java/cn/com/goldenwater/domain/PtServiceLog.java

@@ -51,7 +51,7 @@ public class PtServiceLog implements Serializable {
 
     /**
      * 返回信息
-      */
+     */
     private String returnText;
 
     /**
@@ -62,7 +62,7 @@ public class PtServiceLog implements Serializable {
     /**
      * 状态码
      */
-    private Long statusCode;
+    private Integer statusCode;
 
     /**
      * 客户端ip
@@ -84,9 +84,13 @@ public class PtServiceLog implements Serializable {
      */
     private String serviceName;
 
-    /** 应用ID */
+    /**
+     * 应用ID
+     */
     private String appId;
 
-    /** 应用名称 */
+    /**
+     * 应用名称
+     */
     private String appName;
 }

+ 2 - 2
src/main/java/cn/com/goldenwater/filter/RequestLogGlobalFilter.java

@@ -56,7 +56,7 @@ public class RequestLogGlobalFilter implements GlobalFilter, Ordered {
                         byte[] bytes = new byte[dataBuffer.readableByteCount()];
                         dataBuffer.read(bytes);
                         String bodyString = new String(bytes, StandardCharsets.UTF_8);
-                        log.info("--> {}", bodyString);
+//                        log.info("--> {}", bodyString);
                         exchange.getAttributes().put("POST_BODY", bodyString);
                         DataBufferUtils.release(dataBuffer);
                         Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
@@ -75,7 +75,7 @@ public class RequestLogGlobalFilter implements GlobalFilter, Ordered {
                     });
         } else if ("GET".equals(method)) {
             MultiValueMap<String, String> queryParams = request.getQueryParams();
-            log.info("请求参数:" + queryParams);
+//            log.info("请求参数:" + queryParams);
         }
 
         String finalRequestUrl = requestUrl;

+ 24 - 11
src/main/java/cn/com/goldenwater/filter/ResponseLogGlobalFilter.java

@@ -2,8 +2,10 @@ package cn.com.goldenwater.filter;
 
 import cn.com.goldenwater.domain.PtApp;
 import cn.com.goldenwater.domain.PtService;
+import cn.com.goldenwater.domain.PtServiceAlarm;
 import cn.com.goldenwater.domain.PtServiceLog;
 import cn.com.goldenwater.service.PtAppService;
+import cn.com.goldenwater.service.PtServiceAlarmService;
 import cn.com.goldenwater.service.PtServiceLogService;
 import cn.com.goldenwater.service.PtServiceService;
 import cn.com.goldenwater.utils.GeoipUtils;
@@ -48,26 +50,23 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
     @Autowired
     private PtAppService ptAppService;
 
+    @Autowired
+    private PtServiceAlarmService ptServiceAlarmService;
+
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         try {
             ServerHttpResponse originalResponse = exchange.getResponse();
             DataBufferFactory bufferFactory = originalResponse.bufferFactory();
-            HttpStatus statusCode = originalResponse.getStatusCode();
 
             // 记录请求开始时间
             long startTime = System.currentTimeMillis();
 
-            if (statusCode != HttpStatus.OK) {
-                return chain.filter(exchange); // 降级处理返回数据
-            }
-
             ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
                 @Override
                 public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                     if (body instanceof Flux) {
                         Flux<? extends DataBuffer> fluxBody = Flux.from(body);
-
                         return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
 
                             // 合并多个流集合,解决返回体分段传输
@@ -92,7 +91,6 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
                             rspArgs.add(originalResponse.getStatusCode().value());
                             rspArgs.add(exchange.getRequest().getURI());
                             rspArgs.add(result);
-                            log.info("<-- {} {}\n{}", rspArgs.toArray());
 
                             // 保存服务日志
                             saveServiceLog(exchange, result, System.currentTimeMillis() - startTime, originalResponse.getStatusCode().value());
@@ -101,10 +99,16 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
                             return bufferFactory.wrap(result.getBytes());
                         }));
                     } else {
-                        // 对于非Flux响应体,仍然记录日志但不处理内容
-                        saveServiceLog(exchange, "", System.currentTimeMillis() - startTime, originalResponse.getStatusCode().value());
+                        Mono<DataBuffer> monoBody = (Mono<DataBuffer>) body;
+                        return super.writeWith(monoBody.doOnNext(dataBuffer -> {
+                            byte[] content = new byte[dataBuffer.readableByteCount()];
+                            dataBuffer.read(content);
+                            String responseStr = new String(content);
+
+                            // 记录日志
+                            saveServiceLog(exchange, responseStr, System.currentTimeMillis() - startTime, originalResponse.getStatusCode().value());
+                        }));
                     }
-                    return super.writeWith(body);
                 }
             };
             return chain.filter(exchange.mutate().response(decoratedResponse).build());
@@ -134,6 +138,7 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
             PtServiceLog serviceLog = new PtServiceLog();
             // 设置日志字段
             serviceLog.setTm(new Date());
+            serviceLog.setStatusCode(statusCode);
 
             // 构建包含查询参数和请求体的JSON对象
             JSONObject requestParams = new JSONObject();
@@ -168,9 +173,11 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
             // 将请求参数转换为JSON字符串存储
             serviceLog.setSenText(requestParams.toJSONString());
             serviceLog.setUrl(exchange.getRequest().getURI().getPath());
+            if (responseContent.length() > 4000) {
+                responseContent = responseContent.substring(0, 4000);
+            }
             serviceLog.setReturnText(responseContent);
             serviceLog.setExecTm(execTime);
-            serviceLog.setStatusCode((long) statusCode);
 
             // 获取客户端IP
             String clientIp = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
@@ -187,6 +194,8 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
 
             // 通过URL获取服务信息
             String requestUrl = exchange.getRequest().getURI().getPath();
+            String gatewayUrl = "/" + requestUrl.split("/")[1];
+            requestUrl = requestUrl.replaceFirst(gatewayUrl, "");
             PtService ptService = ptServiceService.getServiceByUrl(requestUrl);
             if (ptService != null) {
                 serviceLog.setServiceName(ptService.getName());
@@ -207,8 +216,12 @@ public class ResponseLogGlobalFilter implements GlobalFilter, Ordered {
 
             // 异步保存日志
             ptServiceLogService.save(serviceLog);
+
+            // 判断是否记录报警信息
+            ptServiceAlarmService.saveByLog(serviceLog, responseContent, gatewayUrl);
         } catch (Exception e) {
             log.error("保存服务日志异常: ", e);
         }
     }
+
 }

+ 7 - 0
src/main/java/cn/com/goldenwater/mapper/MdModelInfoMapper.java

@@ -0,0 +1,7 @@
+package cn.com.goldenwater.mapper;
+
+import cn.com.goldenwater.domain.MdModelInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface MdModelInfoMapper extends BaseMapper<MdModelInfo> {
+}

+ 11 - 0
src/main/java/cn/com/goldenwater/mapper/PtServiceAlarmMapper.java

@@ -0,0 +1,11 @@
+package cn.com.goldenwater.mapper;
+
+import cn.com.goldenwater.domain.PtServiceAlarm;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PtServiceAlarmMapper extends BaseMapper<PtServiceAlarm> {
+
+
+}

+ 2 - 0
src/main/java/cn/com/goldenwater/service/GatewayRoutesService.java

@@ -7,4 +7,6 @@ public interface GatewayRoutesService extends IService<GatewayRoutes> {
 
     String loadRouteDefinition();
 
+    GatewayRoutes getByPredicates(String predicates);
+
 }

+ 7 - 0
src/main/java/cn/com/goldenwater/service/MdModelInfoService.java

@@ -0,0 +1,7 @@
+package cn.com.goldenwater.service;
+
+import cn.com.goldenwater.domain.MdModelInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface MdModelInfoService extends IService<MdModelInfo> {
+}

+ 15 - 0
src/main/java/cn/com/goldenwater/service/PtServiceAlarmService.java

@@ -0,0 +1,15 @@
+package cn.com.goldenwater.service;
+
+import cn.com.goldenwater.domain.PtServiceAlarm;
+import cn.com.goldenwater.domain.PtServiceLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @author lql
+ * @date 2025-9-17
+ */
+public interface PtServiceAlarmService extends IService<PtServiceAlarm> {
+
+    void saveByLog(PtServiceLog serviceLog, String responseContent, String gatewayUrl);
+
+}

+ 8 - 0
src/main/java/cn/com/goldenwater/service/impl/GatewayRoutesServiceImpl.java

@@ -3,6 +3,7 @@ package cn.com.goldenwater.service.impl;
 import cn.com.goldenwater.domain.GatewayRoutes;
 import cn.com.goldenwater.mapper.GatewayRoutesMapper;
 import cn.com.goldenwater.service.GatewayRoutesService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -69,4 +70,11 @@ public class GatewayRoutesServiceImpl extends ServiceImpl<GatewayRoutesMapper, G
         }
     }
 
+    @Override
+    public GatewayRoutes getByPredicates(String predicates) {
+        QueryWrapper<GatewayRoutes> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("predicates", predicates);
+        return getOne(queryWrapper);
+    }
+
 }

+ 11 - 0
src/main/java/cn/com/goldenwater/service/impl/MdModelInfoServiceImpl.java

@@ -0,0 +1,11 @@
+package cn.com.goldenwater.service.impl;
+
+import cn.com.goldenwater.domain.MdModelInfo;
+import cn.com.goldenwater.mapper.MdModelInfoMapper;
+import cn.com.goldenwater.service.MdModelInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+@Service
+public class MdModelInfoServiceImpl extends ServiceImpl<MdModelInfoMapper, MdModelInfo> implements MdModelInfoService {
+}

+ 76 - 0
src/main/java/cn/com/goldenwater/service/impl/PtServiceAlarmServiceImpl.java

@@ -0,0 +1,76 @@
+package cn.com.goldenwater.service.impl;
+
+import cn.com.goldenwater.domain.GatewayRoutes;
+import cn.com.goldenwater.domain.MdModelInfo;
+import cn.com.goldenwater.domain.PtServiceAlarm;
+import cn.com.goldenwater.domain.PtServiceLog;
+import cn.com.goldenwater.mapper.PtServiceAlarmMapper;
+import cn.com.goldenwater.service.GatewayRoutesService;
+import cn.com.goldenwater.service.MdModelInfoService;
+import cn.com.goldenwater.service.PtServiceAlarmService;
+import cn.com.goldenwater.utils.JsonUtils;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONPath;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * @author lql
+ * @date 2025-9-17
+ */
+@Slf4j
+@Service
+@Transactional
+public class PtServiceAlarmServiceImpl extends ServiceImpl<PtServiceAlarmMapper, PtServiceAlarm> implements PtServiceAlarmService {
+
+    @Autowired
+    private GatewayRoutesService gatewayRoutesService;
+
+    @Autowired
+    private MdModelInfoService mdModelInfoService;
+
+    @Override
+    public boolean save(PtServiceAlarm ptServiceAlarm) {
+        ptServiceAlarm.setCreateTime(new Date());
+        return super.save(ptServiceAlarm);
+    }
+
+    @Override
+    public void saveByLog(PtServiceLog serviceLog, String responseContent, String gatewayUrl) {
+        PtServiceAlarm ptAlarmMessage = new PtServiceAlarm();
+        ptAlarmMessage.setMdid(serviceLog.getMdId());
+        ptAlarmMessage.setSrvId(serviceLog.getSerId());
+        ptAlarmMessage.setServiceName(serviceLog.getServiceName());
+        ptAlarmMessage.setAlertTime(serviceLog.getTm());
+
+        MdModelInfo mdModelInfo = mdModelInfoService.getById(serviceLog.getMdId());
+        Optional.ofNullable(mdModelInfo).map(MdModelInfo::getName).ifPresent(ptAlarmMessage::setModelName);
+
+        if (serviceLog.getStatusCode() >= 500) {
+            ptAlarmMessage.setAlertType("1");
+            ptAlarmMessage.setAlertContent("模型服务异常");
+            save(ptAlarmMessage);
+        } else if (serviceLog.getStatusCode() >= 400) {
+            ptAlarmMessage.setAlertType("2");
+            ptAlarmMessage.setAlertContent("模型服务接口异常");
+            save(ptAlarmMessage);
+        } else {
+            GatewayRoutes gatewayRoutes = gatewayRoutesService.getByPredicates(gatewayUrl);
+            JSONObject resultSuccessFormatData = gatewayRoutes.getResultSuccessFormatData();
+
+            JSONObject responseContentObj = JsonUtils.jsonToPojo(responseContent, JSONObject.class);
+            Object statusCode = JSONPath.eval(responseContentObj, resultSuccessFormatData.getString("field"));
+            if (!resultSuccessFormatData.getString("code").equals(String.valueOf(statusCode))) {
+                ptAlarmMessage.setAlertType("3");
+                ptAlarmMessage.setAlertContent("模型服务接口异常");
+                save(ptAlarmMessage);
+            }
+        }
+    }
+}

+ 1 - 1
src/main/java/cn/com/goldenwater/utils/GeoipUtils.java

@@ -83,7 +83,7 @@ public class GeoipUtils {
                     "longitude", location.getLongitude()
             );
         } catch (Exception e) {
-            log.error("获取地理位置信息失败,IP: {}", ip, e);
+            log.warn("获取地理位置信息失败,IP: {}", ip);
         }
         return null;
     }