package edbmonitor import ( "encoding/json" "eta/eta_api/models/data_manage" edbmonitor "eta/eta_api/models/edb_monitor" "eta/eta_api/models/edb_monitor/request" "eta/eta_api/models/edb_monitor/response" "eta/eta_api/models/system" "eta/eta_api/utils" "fmt" "strconv" "strings" "sync" "time" "github.com/rdlucklib/rdluck_tools/paging" ) type SafeEdbMonitorSet struct { m map[int]struct{} mu sync.Mutex } func NewSafeEdbMonitorSet() *SafeEdbMonitorSet { return &SafeEdbMonitorSet{ m: make(map[int]struct{}), } } func (e *SafeEdbMonitorSet) Add(id int) { e.mu.Lock() defer e.mu.Unlock() e.m[id] = struct{}{} } func (e *SafeEdbMonitorSet) IsExist(id int) (ok bool) { e.mu.Lock() defer e.mu.Unlock() _, ok = e.m[id] return } func (e *SafeEdbMonitorSet) Remove(id int) { e.mu.Lock() defer e.mu.Unlock() delete(e.m, id) } var EdbLocalSet = NewSafeEdbMonitorSet() func GetMonitorList(classifyId, level, state, userId string, pageSize, currentIndex int) (resp response.EdbMonitorInfoListResp, msg string, err error) { if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize := utils.StartIndex(currentIndex, pageSize) var classifyIdList []int if classifyId != "" { tmp := strings.Split(classifyId, ",") for _, v := range tmp { cv, _ := strconv.Atoi(v) classifyIdList = append(classifyIdList, cv) } } var levelList []string if level != "" { levelList = strings.Split(level, ",") } var stateList []int if state != "" { tmp := strings.Split(state, ",") for _, v := range tmp { st, _ := strconv.Atoi(v) stateList = append(stateList, st) } } var userIdList []int if userId != "" { tmp := strings.Split(userId, ",") for _, v := range tmp { ui, _ := strconv.Atoi(v) userIdList = append(userIdList, ui) } } var conditon string var pars []interface{} if len(classifyIdList) != 0 { conditon += ` AND edb_monitor_classify_id IN (` + utils.GetOrmInReplace(len(classifyIdList)) + ` )` pars = append(pars, classifyIdList) } if len(levelList) != 0 { conditon += ` AND monitor_level IN (` + utils.GetOrmInReplace(len(levelList)) + ` )` pars = append(pars, levelList) } if len(stateList) != 0 { conditon += ` AND state IN (` + utils.GetOrmInReplace(len(stateList)) + ` )` pars = append(pars, stateList) } if len(userIdList) != 0 { conditon += ` AND create_user_id IN (` + utils.GetOrmInReplace(len(userIdList)) + ` )` pars = append(pars, userIdList) } total, err := edbmonitor.GetEdbMonitorInfoCountByCondition(conditon, pars) if err != nil { msg = "获取监控列表失败" err = fmt.Errorf("GetEdbMonitorInfoCountByCondition err:%w", err) return } edbMonitorList, err := edbmonitor.GetEdbMonitorInfoPageByCondition(conditon, pars, startSize, pageSize) if err != nil { msg = "获取监控列表失败" err = fmt.Errorf("GetEdbMonitorInfoPageByCondition err:%w", err) return } var edbInfoId, edbUserId []int for _, v := range edbMonitorList { edbUserId = append(edbUserId, v.CreateUserId) edbInfoId = append(edbInfoId, v.EdbInfoId) } edbInfoList, err := data_manage.GetEdbInfoByIdList(edbInfoId) if err != nil { msg = "获取监控列表失败" err = fmt.Errorf("GetEdbInfoByIdList err:%w", err) return } infoMap := make(map[int]string) for _, v := range edbInfoList { infoMap[v.EdbInfoId] = v.EdbName } userInfoList, err := system.GetSysAdminByIdList(edbUserId) if err != nil { msg = "获取监控列表失败" err = fmt.Errorf("GetSysAdminByIdList err:%w", err) return } userMap := make(map[int]string) for _, v := range userInfoList { userMap[v.AdminId] = v.RealName } classifyList, err := edbmonitor.GetEdbMonitorClassifyList() if err != nil { msg = "获取监控列表失败" err = fmt.Errorf("GetEdbMonitorClassifyList err:%w", err) return } classifyMap := make(map[int]string) for _, v := range classifyList { classifyMap[v.ClassifyId] = v.ClassifyName } classifyPathMap := make(map[int]string) for _, v := range classifyList { var path []string if v.ParentId != 0 { parentName := classifyMap[v.ParentId] if v.RootId != 0 && v.RootId != v.ParentId { rootName := classifyMap[v.RootId] path = append(path, rootName) } curName := v.ClassifyName path = append(path, parentName, curName) } else { path = append(path, v.ClassifyName) } classifyPathMap[v.ClassifyId] = strings.Join(path, "/") } edbMonitorItems := toEdbMonitorInfoItems(edbMonitorList, userMap, classifyPathMap, infoMap) page := paging.GetPaging(currentIndex, pageSize, total) resp.List = edbMonitorItems resp.Paging = page return } func SaveEdbMonitorInfo(req request.EdbMonitorInfoSaveReq, adminId int) (msg string, err error) { edb, er := data_manage.GetEdbInfoById(req.EdbInfoId) if er != nil { if er.Error() == utils.ErrNoRow() { msg = "指标不存在,请刷新重试" err = er return } msg = "添加指标预警失败" err = er return } var edbMonitorInfo *edbmonitor.EdbMonitorInfo if req.EdbMonitorId > 0 { ok, msg1, er := OperatePermissionCheck(req.EdbMonitorId, adminId) if !ok { if msg1 == "" { msg1 = "编辑失败" } msg = msg1 if er == nil { er = fmt.Errorf("权限校验失败") } err = er return } edbMonitorInfo, er = edbmonitor.GetEdbMonitorInfoById(req.EdbMonitorId) if er != nil { if er.Error() == utils.ErrNoRow() { msg = "指标预警不存在,请刷新重试" err = er return } msg = "编辑指标预警失败" err = fmt.Errorf("GetEdbMonitorInfoById err:%w", er) return } var updateCols []string if edbMonitorInfo.EdbInfoId != req.EdbInfoId { updateCols = append(updateCols, []string{"edb_info_id", "edb_info_type", "edb_code", "edb_classify_id", "edb_unique_code", "source", "sub_source", "edb_latest_date", "edb_latest_value"}...) edbMonitorInfo.EdbInfoId = req.EdbInfoId edbMonitorInfo.EdbInfoType = edb.EdbInfoType edbMonitorInfo.EdbCode = edb.EdbCode edbMonitorInfo.EdbClassifyId = edb.ClassifyId edbMonitorInfo.EdbUniqueCode = edb.UniqueCode edbMonitorInfo.Source = edb.Source edbMonitorInfo.SubSource = edb.SubSource edbMonitorInfo.EdbLatestDate = edb.LatestDate edbMonitorInfo.EdbLatestValue = edb.LatestValue } if edbMonitorInfo.EdbMonitorName != req.EdbMonitorName { updateCols = append(updateCols, "edb_monitor_name") edbMonitorInfo.EdbMonitorName = req.EdbMonitorName } if edbMonitorInfo.EdbMonitorClassifyId != req.ClassifyId { updateCols = append(updateCols, "edb_monitor_classify_id") edbMonitorInfo.EdbMonitorClassifyId = req.ClassifyId } if edbMonitorInfo.MonitorType != req.MonitorType { updateCols = append(updateCols, "monitor_type") edbMonitorInfo.MonitorType = req.MonitorType } monitorData, _ := strconv.ParseFloat(req.MonitorData, 64) if edbMonitorInfo.MonitorData != monitorData { updateCols = append(updateCols, "monitor_data") edbMonitorInfo.MonitorData = monitorData } if edbMonitorInfo.MonitorLevel != req.MonitorLevel { updateCols = append(updateCols, "monitor_level") edbMonitorInfo.MonitorLevel = req.MonitorLevel } if len(updateCols) > 0 { updateCols = append(updateCols, "modify_time") edbMonitorInfo.ModifyTime = time.Now() er := edbMonitorInfo.Update(updateCols) if er != nil { msg = "编辑指标预警失败" err = fmt.Errorf("UpdateEdbMonitorInfoById err:%w", er) return } } } else { edbMonitorInfo = new(edbmonitor.EdbMonitorInfo) edbMonitorInfo.EdbMonitorClassifyId = req.ClassifyId edbMonitorInfo.EdbMonitorName = req.EdbMonitorName edbMonitorInfo.EdbInfoId = req.EdbInfoId edbMonitorInfo.EdbInfoType = edb.EdbInfoType edbMonitorInfo.EdbUniqueCode = edb.UniqueCode edbMonitorInfo.EdbClassifyId = edb.ClassifyId edbMonitorInfo.EdbCode = edb.EdbCode edbMonitorInfo.Source = edb.Source edbMonitorInfo.SubSource = edb.SubSource edbMonitorInfo.EdbLatestDate = edb.LatestDate edbMonitorInfo.EdbLatestValue = edb.LatestValue edbMonitorInfo.MonitorType = req.MonitorType monitorData, _ := strconv.ParseFloat(req.MonitorData, 64) edbMonitorInfo.MonitorData = monitorData edbMonitorInfo.MonitorLevel = req.MonitorLevel edbMonitorInfo.CreateUserId = adminId edbMonitorInfo.CreateTime = time.Now() edbMonitorInfo.ModifyTime = time.Now() insertId, er := edbMonitorInfo.Insert() if er != nil { msg = "添加指标预警失败" err = fmt.Errorf("insert err:%w", er) return } edbMonitorInfo.EdbMonitorId = int(insertId) } err = utils.Rc.SAdd(EDB_MONITOR_ID_SET_CACHE, edbMonitorInfo.EdbInfoId) if err != nil { utils.FileLog.Info("监控指标添加缓存失败", err) } EdbLocalSet.Add(edbMonitorInfo.EdbInfoId) err = ModifyEdbMonitorStateAndSendMsg(edbMonitorInfo, edb.EdbCode, edb.Source, edb.SubSource) if err != nil { msg = "更新指标预警失败" err = fmt.Errorf("ModifyEdbMonitorState err:%w", err) return } return } func ModifyEdbMonitorStateAndSendMsg(edbMonitorInfo *edbmonitor.EdbMonitorInfo, edbCode string, source, subSource int) (err error) { cond := ` AND edb_code = ? ` pars := []interface{}{edbCode} latestTwoData, er := data_manage.GetEdbDataListByCondition(cond, pars, source, subSource, 2, 0) if er != nil { err = fmt.Errorf("GetEdbDataListByCondition err:%w", er) return } state, err := ModifyEdbMonitorState(edbMonitorInfo, latestTwoData) if err != nil { return } if state == EDB_MONITOR_STATE_TRIGGER_SUCCESS { SendAndLogMessage(edbMonitorInfo) } return } func GetTwoEdbDataByDataTime(edbCode, dataTime string, source, subSource int) (twoData []*data_manage.EdbData, err error) { cond := ` AND edb_code = ? AND data_time <= ? ` pars := []interface{}{edbCode, dataTime} twoData, er := data_manage.GetEdbDataListByCondition(cond, pars, source, subSource, 2, 0) if er != nil { err = fmt.Errorf("GetEdbDataListByCondition err:%w", er) return } return } func ModifyEdbMonitorState(edbMonitorInfo *edbmonitor.EdbMonitorInfo, latestTwoData []*data_manage.EdbData) (state int, err error) { var updateCols []string edbMonitorInfo.EdbLatestDate = latestTwoData[0].DataTime edbMonitorInfo.EdbLatestValue = latestTwoData[0].Value updateCols = append(updateCols, []string{"edb_latest_date", "edb_latest_value"}...) state = cmpEdbMonitorState(latestTwoData, edbMonitorInfo.MonitorType, edbMonitorInfo.MonitorData) if state == EDB_MONITOR_STATE_TRIGGER_SUCCESS { tmpTime, _ := time.Parse(utils.FormatDate, latestTwoData[0].DataTime) edbMonitorInfo.EdbTriggerDate = tmpTime edbMonitorInfo.MonitorTriggerTime = time.Now() updateCols = append(updateCols, []string{"edb_trigger_date", "monitor_trigger_time"}...) } if edbMonitorInfo.State == EDB_MONITOR_STATE_NO_TRIGGER || edbMonitorInfo.State == EDB_MONITOR_STATE_CLOSE { edbMonitorInfo.State = state updateCols = append(updateCols, "state") } err = edbMonitorInfo.Update(updateCols) if err != nil { return } return } func SendAndLogMessage(edbMonitorInfo *edbmonitor.EdbMonitorInfo) (err error) { triggerTime := edbMonitorInfo.MonitorTriggerTime.Format(utils.FormatDateTime) err = SendMessages(edbMonitorInfo.CreateUserId, edbMonitorInfo.EdbInfoId, edbMonitorInfo.EdbInfoType, edbMonitorInfo.EdbClassifyId, edbMonitorInfo.EdbUniqueCode, edbMonitorInfo.EdbMonitorName, triggerTime) isRead := 1 if err != nil { err = nil isRead = 0 } err = LogMessage(edbMonitorInfo.EdbMonitorName, edbMonitorInfo.EdbUniqueCode, edbMonitorInfo.MonitorTriggerTime, edbMonitorInfo.EdbInfoId, edbMonitorInfo.EdbInfoType, edbMonitorInfo.CreateUserId, isRead, edbMonitorInfo.EdbClassifyId) return } func cmpEdbMonitorState(twoData []*data_manage.EdbData, monitorType int, monitorData float64) int { if len(twoData) < 2 { return EDB_MONITOR_STATE_NO_TRIGGER } switch monitorType { case EDB_MONITOR_TYPE_UP: if twoData[0].Value >= monitorData && twoData[1].Value < monitorData { return EDB_MONITOR_STATE_TRIGGER_SUCCESS } else { return EDB_MONITOR_STATE_NO_TRIGGER } case EDB_MONITOR_TYPE_DOWN: if twoData[0].Value <= monitorData && twoData[1].Value > monitorData { return EDB_MONITOR_STATE_TRIGGER_SUCCESS } else { return EDB_MONITOR_STATE_NO_TRIGGER } default: return EDB_MONITOR_STATE_NO_TRIGGER } } func OperatePermissionCheck(edbMonitorId int, adminId int) (ok bool, msg string, err error) { monitorInfo, err := edbmonitor.GetEdbMonitorInfoById(edbMonitorId) if err != nil { if err.Error() == utils.ErrNoRow() { msg = "指标预警不存在,请刷新重试" return } msg = "删除失败" err = fmt.Errorf("获取预警详情失败, err:%w", err) return } if monitorInfo.CreateUserId != adminId { userInfo, er := system.GetSysAdminById(adminId) if er != nil { msg = "删除失败" err = fmt.Errorf("查询用户信息失败 err:%w", er) return } if userInfo.Role != utils.ROLE_TYPE_CODE_ADMIN { msg = "无权限操作" err = fmt.Errorf("无权限操作") return } } ok = true return } func DeleteEdbMonitorInfo(req request.EdbMonitorInfoDeleteReq, adminId int) (msg string, err error) { ok, msg, err := OperatePermissionCheck(req.EdbMonitorId, adminId) if !ok { if msg == "" { msg = "删除失败" } if err == nil { err = fmt.Errorf("权限校验失败") } return } err = edbmonitor.DeleteEdbMonitorInfoById(req.EdbMonitorId) if err != nil { msg = "删除失败" err = fmt.Errorf("删除预警失败 err:%w", err) } return } func GetEdbMonitorLevelList() (list []string, msg string, err error) { list, err = edbmonitor.GetEdbMonitorLevelList() if err != nil { msg = "获取等级等级列表失败" err = fmt.Errorf("GetEdbMonitorLevelList err:%w", err) return } return } func CloseEdbMonitorInfo(req request.EdbMonitorInfoCloseReq, adminId int) (msg string, err error) { edbMonitor, er := edbmonitor.GetEdbMonitorInfoById(req.EdbMonitorId) if er != nil { if er.Error() == utils.ErrNoRow() { msg = "指标预警不存在,请刷新重试" err = er } msg = "关闭失败" err = fmt.Errorf("获取预警详情失败, err:%w", er) return } ok, msg, err := OperatePermissionCheck(req.EdbMonitorId, adminId) if !ok { if msg == "" { msg = "删除失败" } if err == nil { err = fmt.Errorf("权限校验失败") } return } if edbMonitor.State == EDB_MONITOR_STATE_CLOSE { msg = "预警已关闭" err = fmt.Errorf("预警已关闭") return } edbMonitor.State = EDB_MONITOR_STATE_CLOSE edbMonitor.ModifyTime = time.Now() er = edbMonitor.Update([]string{"state", "modify_time"}) if er != nil { msg = "关闭失败" err = fmt.Errorf("修改预警状态失败, err:%w", er) return } return } func RestartEdbMonitorInfo(req request.EdbMonitorInfoRestartReq, adminId int) (msg string, err error) { edbMonitor, er := edbmonitor.GetEdbMonitorInfoById(req.EdbMonitorId) if er != nil { if er.Error() == utils.ErrNoRow() { msg = "指标预警不存在,请刷新重试" err = er } msg = "重启失败" err = fmt.Errorf("获取预警详情失败, err:%w", er) return } ok, msg, err := OperatePermissionCheck(req.EdbMonitorId, adminId) if !ok { if msg == "" { msg = "删除失败" } if err == nil { err = fmt.Errorf("权限校验失败") } return } if edbMonitor.State != EDB_MONITOR_STATE_CLOSE { msg = "预警未关闭,无需重启" err = fmt.Errorf("预警未关闭,无需重启") return } edbMonitor.EdbTriggerDate = time.Time{} edbMonitor.MonitorTriggerTime = time.Time{} edbMonitor.ModifyTime = time.Now() err = ModifyEdbMonitorStateAndSendMsg(edbMonitor, edbMonitor.EdbCode, edbMonitor.Source, edbMonitor.SubSource) if err != nil { msg = "重启失败" err = fmt.Errorf("修改预警状态失败, err:%w", err) return } return } func GetEdbMonitorInfoUserList() (resp response.EdbMonitorInfoCreateUserResp, msg string, err error) { userIdList, err := edbmonitor.GetEdbMonitorCreateUserId() if err != nil { msg = "获取用户列表失败" return } adminList, err := system.GetAdminItemByIdList(userIdList) if err != nil { msg = "获取用户列表失败" return } createUserItem := make([]*response.EdbMonitorCreateUserItem, 0) for _, v := range adminList { tmp := new(response.EdbMonitorCreateUserItem) tmp.AdminId = v.AdminId tmp.RealName = v.RealName createUserItem = append(createUserItem, tmp) } resp.List = createUserItem return } func InitEdbMonitorInfo() { edbMonitorList, err := edbmonitor.GetEdbMonitorEdbInfoList() if err != nil { utils.FileLog.Error("获取预警列表失败, err:%w", err) } edbInfoIdList := make([]interface{}, 0) for _, v := range edbMonitorList { if v.EdbInfoId != 0 { EdbLocalSet.Add(v.EdbInfoId) edbInfoIdList = append(edbInfoIdList, v.EdbInfoId) } } utils.Rc.SAdd(EDB_MONITOR_ID_SET_CACHE, edbInfoIdList...) } func HandleEdbMonitorEdbInfo() { InitEdbMonitorInfo() for { utils.Rc.Brpop(EDB_MONITOR_HANDLE_LIST_CACHE, func(b []byte) { edbInfo := new(EdbInfoBingLog) if err := json.Unmarshal(b, &edbInfo); err != nil { return } edbMonitorList, err := edbmonitor.GetEdbMonitorInfoByEdbInfoId(edbInfo.EdbInfoId) if err != nil { utils.FileLog.Error("获取预警列表失败, err:%w, edbInfoId:%d", err, edbInfo.EdbInfoId) return } if len(edbMonitorList) == 0 { utils.Rc.SRem(EDB_MONITOR_ID_SET_CACHE, edbInfo.EdbInfoId) EdbLocalSet.Remove(edbInfo.EdbInfoId) return } for _, v := range edbMonitorList { twoData, err := GetTwoEdbDataByDataTime(v.EdbCode, edbInfo.EndDate, v.Source, v.SubSource) if err != nil { utils.FileLog.Error("获取数据失败, err:%w, edbInfoId:%d", err, edbInfo.EdbInfoId) continue } state, err := ModifyEdbMonitorState(v, twoData) if err != nil { utils.FileLog.Error("更新预警状态失败, err:%w, edbMonitorId:%d", err, v.EdbMonitorId) continue } if state == EDB_MONITOR_STATE_TRIGGER_SUCCESS { err = SendAndLogMessage(v) if err != nil { utils.FileLog.Error("发送预警消息失败, err:%w, edbMonitorId:%d", err, v.EdbMonitorId) continue } } } }) } } func toEdbMonitorInfoItems(edbmonitor []*edbmonitor.EdbMonitorInfo, userMap, classifyPathMap, infoMap map[int]string) []*response.EdbMonitorInfoItem { res := make([]*response.EdbMonitorInfoItem, 0, len(edbmonitor)) for _, v := range edbmonitor { tmp := new(response.EdbMonitorInfoItem) tmp.EdbMonitorId = v.EdbMonitorId tmp.EdbMonitorName = v.EdbMonitorName tmp.EdbMonitorClassifyId = v.EdbMonitorClassifyId tmp.EdbMonitorClassifyName = classifyPathMap[v.EdbMonitorClassifyId] tmp.EdbInfoId = v.EdbInfoId tmp.EdbInfoName = infoMap[v.EdbInfoId] tmp.EdbUniqueCode = v.EdbUniqueCode tmp.EdbClassifyId = v.EdbClassifyId tmp.EdbInfoType = v.EdbInfoType tmp.EdbCode = v.EdbCode tmp.Source = v.Source tmp.SubSource = v.SubSource tmp.EdbLatestDate = v.EdbLatestDate tmp.EdbLatestValue = v.EdbLatestValue tmp.MonitorType = v.MonitorType tmp.MonitorData = v.MonitorData tmp.MonitorLevel = v.MonitorLevel tmp.State = v.State tmp.EdbTriggerDate = utils.TimeTransferString(utils.FormatDate, v.EdbTriggerDate) tmp.MonitorTriggerTime = utils.TimeTransferString(utils.FormatDateTime, v.MonitorTriggerTime) tmp.CreateUserId = v.CreateUserId tmp.CreateUserName = userMap[v.CreateUserId] tmp.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime) tmp.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime) res = append(res, tmp) } return res }