package service import ( "fmt" "be.ems/src/framework/config" "be.ems/src/framework/constants" "be.ems/src/framework/logger" "be.ems/src/framework/utils/parse" "github.com/tsmask/go-oam" neDataModel "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" neService "be.ems/src/modules/network_element/service" notificationService "be.ems/src/modules/notification/service" traceService "be.ems/src/modules/trace/service" wsService "be.ems/src/modules/ws/service" ) // 实例化服务层 Alarm 结构体 var NewAlarm = &Alarm{ neInfoService: neService.NewNeInfo, wsService: wsService.NewWSSend, alarmService: neDataService.NewAlarm, alarmEventService: neDataService.NewAlarmEvent, alarmLogService: neDataService.NewAlarmLog, alarmForwardLogService: neDataService.NewAlarmForwardLog, } // Alarm 消息处理 type Alarm struct { neInfoService *neService.NeInfo wsService *wsService.WSSend alarmService *neDataService.Alarm alarmEventService *neDataService.AlarmEvent alarmLogService *neDataService.AlarmLog alarmForwardLogService *neDataService.AlarmForwardLog alarm neDataModel.Alarm } // Resolve 接收处理 func (s *Alarm) Resolve(a oam.Alarm) error { // 是否存在网元 neInfo := s.neInfoService.FindByRmuid(a.NeUid) if neInfo.NeType == "" || neInfo.RmUID != a.NeUid { logger.Warnf("resolve alarm network element does not exist %s", a.NeUid) return fmt.Errorf("resolve alarm network element does not exist %s", a.NeUid) } // seq 告警序号 lastSeq := neDataService.NewAlarm.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId) // 告警信息 s.alarm = neDataModel.Alarm{ NeType: neInfo.NeType, NeId: neInfo.NeId, NeName: neInfo.NeName, Province: neInfo.Province, PvFlag: neInfo.PvFlag, AlarmSeq: lastSeq + 1, AlarmId: a.AlarmId, AlarmTitle: a.AlarmTitle, AlarmCode: int64(a.AlarmCode), EventTime: a.AlarmTime, AlarmType: a.AlarmType, OrigSeverity: a.PerceivedSeverity, PerceivedSeverity: a.PerceivedSeverity, ObjectUid: neInfo.RmUID, ObjectName: neInfo.NeName, ObjectType: neInfo.NeType, LocationInfo: a.LocationInfo, AlarmStatus: a.AlarmStatus, SpecificProblem: a.SpecificProblem, SpecificProblemId: a.SpecificProblemID, AddInfo: a.AddInfo, } // 进行清除 if a.AlarmStatus == oam.ALARM_STATUS_CLEAR { if a.PerceivedSeverity == oam.ALARM_SEVERITY_EVENT { if err := s.clearEvent(); err != nil { logger.Warnf("resolve alarm clear event failed: %s", err.Error()) return err } } else { if err := s.clear(); err != nil { logger.Warnf("resolve alarm clear failed: %s", err.Error()) return err } } } // 进行新增 if a.AlarmStatus == oam.ALARM_STATUS_ACTIVE { if a.PerceivedSeverity == oam.ALARM_SEVERITY_EVENT { if err := s.addEvent(); err != nil { logger.Warnf("resolve alarm add event failed: %s", err.Error()) return err } } else { if err := s.add(); err != nil { logger.Warnf("resolve alarm add failed: %s", err.Error()) return err } } } // 记录日志 if err := s.saveLog(); err != nil { logger.Warnf("resolve alarm save log failed: %s", err.Error()) return err } // 推送 s.wsService.ByGroupID(fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId), s.alarm) // 通知 go s.notify(neInfo.IP) return nil } // saveLog 记录日志 func (s *Alarm) saveLog() error { alarmLog := neDataModel.AlarmLog{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmSeq: s.alarm.AlarmSeq, AlarmId: s.alarm.AlarmId, AlarmTitle: s.alarm.AlarmTitle, AlarmCode: s.alarm.AlarmCode, AlarmStatus: s.alarm.AlarmStatus, AlarmType: s.alarm.AlarmType, OrigSeverity: s.alarm.PerceivedSeverity, EventTime: s.alarm.EventTime, } insertId := s.alarmLogService.Insert(alarmLog) if insertId <= 0 { return fmt.Errorf("save alarm log fail") } return nil } // add 新增告警 func (s *Alarm) add() error { // 检查网元告警ID是否唯一 alarmIdArr := s.alarmService.Find(neDataModel.Alarm{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmId: s.alarm.AlarmId, }) if len(alarmIdArr) > 0 { return fmt.Errorf("already exists alarmId:%s", s.alarm.AlarmId) } insertId := s.alarmService.Insert(s.alarm) if insertId > 0 { s.alarm.ID = insertId return nil } return fmt.Errorf("add alarm fail") } // clear 清除告警 func (s *Alarm) clear() error { // 检查网元告警ID是否唯一 alarmIdArr := s.alarmService.Find(neDataModel.Alarm{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmId: s.alarm.AlarmId, }) if len(alarmIdArr) != 1 { return fmt.Errorf("not exists alarmId:%s", s.alarm.AlarmId) } // 告警清除 rows, _ := s.alarmService.ClearByIds([]int64{alarmIdArr[0].ID}, s.alarm.ObjectUid, constants.ALARM_CLEAR_TYPE_AUTO_CLEAR) if rows > 0 { return nil } return fmt.Errorf("clear fail alarmId:%s", s.alarm.AlarmId) } // addEvent 新增告警事件 func (s *Alarm) addEvent() error { // 检查网元告警ID是否唯一 alarmIdArr := s.alarmEventService.Find(neDataModel.AlarmEvent{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmId: s.alarm.AlarmId, }) if len(alarmIdArr) > 0 { return fmt.Errorf("event already exists alarmId:%s", s.alarm.AlarmId) } // seq 告警序号 lastSeq := s.alarmEventService.FindAlarmEventSeqLast(s.alarm.NeType, s.alarm.NeId) alarmEvent := neDataModel.AlarmEvent{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmSeq: lastSeq + 1, AlarmId: s.alarm.AlarmId, AlarmTitle: s.alarm.AlarmTitle, AlarmCode: s.alarm.AlarmCode, EventTime: s.alarm.EventTime, ObjectUid: s.alarm.ObjectUid, ObjectName: s.alarm.ObjectName, ObjectType: s.alarm.ObjectType, LocationInfo: s.alarm.LocationInfo, AlarmStatus: s.alarm.AlarmStatus, SpecificProblem: s.alarm.SpecificProblem, SpecificProblemId: s.alarm.SpecificProblemId, AddInfo: s.alarm.AddInfo, } insertId := s.alarmEventService.Insert(alarmEvent) if insertId > 0 { alarmEvent.ID = insertId // 网元重启后,清除活动告警 if s.alarm.AlarmCode == constants.ALARM_EVENT_REBOOT { rows := s.alarmService.Find(neDataModel.Alarm{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmStatus: oam.ALARM_STATUS_ACTIVE, }) ids := make([]int64, 0) for _, v := range rows { ids = append(ids, v.ID) } s.alarmService.ClearByIds(ids, s.alarm.ObjectUid, constants.ALARM_CLEAR_TYPE_AUTO_CLEAR) } // 网元重启后,有跟踪任务的需要重新补发启动任务 if s.alarm.AlarmCode == constants.ALARM_EVENT_REBOOT { traceService.NewTraceTask.RunUnstopped(s.alarm.NeType, s.alarm.NeId) } return nil } return fmt.Errorf("event add fail") } // clearEvent 清除告警事件 func (s *Alarm) clearEvent() error { alarmEventService := neDataService.NewAlarmEvent // 检查网元告警ID是否唯一 alarmIdArr := alarmEventService.Find(neDataModel.AlarmEvent{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmId: s.alarm.AlarmId, }) if len(alarmIdArr) != 1 { return fmt.Errorf("event not exists alarmId:%s", s.alarm.AlarmId) } // 告警清除 rows, _ := s.alarmEventService.ClearByIds([]int64{alarmIdArr[0].ID}, s.alarm.ObjectUid, constants.ALARM_CLEAR_TYPE_AUTO_CLEAR) if rows > 0 { return nil } return fmt.Errorf("event clear fail alarmId:%s", s.alarm.AlarmId) } // notify 通知 func (s *Alarm) notify(neIp string) { // 邮箱 emailEnable := parse.Boolean(config.Get("notification.email.enable")) if emailEnable { emailList := fmt.Sprint(config.Get("notification.email.emailList")) emailResult := "Sent Successfully!" emailErr := notificationService.EmailAlarm(s.alarm, neIp) if emailErr != nil { emailResult = emailErr.Error() logger.Warnf("alarm notify email failed: %s", emailErr.Error()) } s.notifyLog("EMAIL", emailList, emailResult) } // 短信 smscEnable := parse.Boolean(config.Get("notification.smsc.enable")) if smscEnable { mobileList := fmt.Sprint(config.Get("notification.smsc.mobileList")) smscResult := "Sent Successfully!" smscErr := notificationService.SMSCAlarm(s.alarm, neIp) if smscErr != nil { smscResult = smscErr.Error() logger.Warnf("alarm notify email failed: %s", smscErr.Error()) } s.notifyLog("SMSC", mobileList, smscResult) } } // notifyLog 通知日志 func (s *Alarm) notifyLog(forwardBy, toUser, result string) error { alarmForwardLog := neDataModel.AlarmForwardLog{ NeType: s.alarm.NeType, NeId: s.alarm.NeId, AlarmSeq: s.alarm.AlarmSeq, AlarmId: s.alarm.AlarmId, AlarmTitle: s.alarm.AlarmTitle, AlarmCode: s.alarm.AlarmCode, AlarmStatus: s.alarm.AlarmStatus, AlarmType: s.alarm.AlarmType, OrigSeverity: s.alarm.OrigSeverity, EventTime: s.alarm.EventTime, Type: forwardBy, Target: toUser, Result: result, } // 记录日志 insertId := s.alarmForwardLogService.Insert(alarmForwardLog) if insertId <= 0 { return fmt.Errorf("notify alarm log fail") } return nil }