feat: 删除不需要文件夹
This commit is contained in:
700
features/fm/alarm.go
Normal file
700
features/fm/alarm.go
Normal file
@@ -0,0 +1,700 @@
|
||||
package fm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/global"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/lib/services"
|
||||
"ems.agt/restagent/config"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
const (
|
||||
AlarmStatusClear = 0
|
||||
AlarmStatusActive = 1
|
||||
)
|
||||
|
||||
const (
|
||||
ClearTypeUnclear = 0
|
||||
ClearTypeAutoClear = 1
|
||||
ClearTypeManualClear = 2
|
||||
)
|
||||
|
||||
const (
|
||||
AckStateUnacked = 0
|
||||
AckStateAcked = 1
|
||||
)
|
||||
|
||||
const (
|
||||
AlarmTypeCommunicationAlarm = 1
|
||||
AlarmTypeEquipmentAlarm = 2
|
||||
AlarmTypeProcessingFailure = 3
|
||||
AlarmTypeEnvironmentalAlarm = 4
|
||||
AlarmTypeQualityOfServiceAlarm = 5
|
||||
)
|
||||
|
||||
const (
|
||||
AlarmPerceivedSeverityCritical = 1
|
||||
AlarmPerceivedSeverityMajor = 2
|
||||
AlarmPerceivedSeverityMinor = 3
|
||||
AlarmPerceivedSeverityWarning = 4
|
||||
AlarmPerceivedSeverityEvent = 5
|
||||
)
|
||||
|
||||
const (
|
||||
AlarmSeqBeginNumber = 1
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type Alarm struct {
|
||||
AlarmSeq int `json:"alarmSeq"`
|
||||
AlarmId string `json:"alarmId" xorm:"alarm_id"`
|
||||
NeId string `json:"neId"`
|
||||
AlarmCode int `json:"alarmCode"`
|
||||
AlarmTitle string `json:"alarmTitle"`
|
||||
EventTime string `json:"eventTime"`
|
||||
AlarmType string `json:"alarmType"`
|
||||
OrigSeverity string `json:"origSeverity"`
|
||||
PerceivedSeverity string `json:"perceivedSeverity"`
|
||||
PVFlag string `json:"pvFlag" xorm:"pv_flag"`
|
||||
NeName string `json:"neName"`
|
||||
NeType string `json:"neType"`
|
||||
ObjectUid string `json:"objectUid" xorm:"object_uid"`
|
||||
ObjectName string `json:"objectName" xorm:"object_name"`
|
||||
ObjectType string `json:"objectType" xorm:"object_type"`
|
||||
LocationInfo string `json:"locationInfo"`
|
||||
Province string `json:"province"`
|
||||
AlarmStatus int `json:"alarmStatus"`
|
||||
SpecificProblem string `json:"specificProblem"`
|
||||
SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
|
||||
AddInfo string `json:"addInfo"`
|
||||
|
||||
AckState int `json:"ackState"`
|
||||
AckTime sql.NullTime `json:"ackTime"`
|
||||
AckUser string `json:"ackUser"`
|
||||
ClearType int `json:"clearType"` // 0: Unclear, 1: Auto clear, 2: Manual clear
|
||||
ClearTime sql.NullTime `json:"clearTime"`
|
||||
}
|
||||
|
||||
type AlarmLog struct {
|
||||
NeType string `json:"neType" xorm:"ne_type"`
|
||||
NeId string `json:"neId" xorm:"ne_id"`
|
||||
AlarmSeq int `json:"alarmSeq" xorm:"alarm_seq"`
|
||||
AlarmId string `json:"alarmId" xorm:"alarm_id"`
|
||||
AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
|
||||
AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
|
||||
EventTime string `json:"eventTime" xorm:"event_time"`
|
||||
// ClearTime sql.NullTime `json:"clearTime" xorm:"clear_time"`
|
||||
LogTime string `json:"logTime" xorm:"-"`
|
||||
}
|
||||
|
||||
var (
|
||||
// alarm management
|
||||
UriAlarms = config.DefaultUriPrefix + "/faultManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/alarms"
|
||||
UriAlarmsFmt = config.DefaultUriPrefix + "/faultManagement/v1/elementType/%s/objectType/alarms"
|
||||
|
||||
CustomUriAlarms = config.UriPrefix + "/faultManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/alarms"
|
||||
CustomUriAlarmsFmt = config.UriPrefix + "/faultManagement/v1/elementType/%s/objectType/alarms"
|
||||
)
|
||||
|
||||
var xEngine *xorm.Engine
|
||||
|
||||
type DatabaseClient struct {
|
||||
dbType string
|
||||
dbUrl string
|
||||
dbConnMaxLifetime time.Duration
|
||||
dbMaxIdleConns int
|
||||
dbMaxOpenConns int
|
||||
IsShowSQL bool
|
||||
|
||||
XEngine *xorm.Engine
|
||||
}
|
||||
|
||||
var DbClient DatabaseClient
|
||||
|
||||
func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
|
||||
DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
|
||||
dbUser, dbPassword, dbHost, dbPort, dbName)
|
||||
DbClient.dbType = dbType
|
||||
DbClient.dbConnMaxLifetime = 0
|
||||
DbClient.dbMaxIdleConns = 0
|
||||
DbClient.dbMaxOpenConns = 0
|
||||
if log.GetLevel() == log.LOG_TRACE {
|
||||
DbClient.IsShowSQL = true
|
||||
}
|
||||
log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8&parseTime=true&loc=Local",
|
||||
dbType, dbUser, dbHost, dbPort, dbName)
|
||||
|
||||
var err error
|
||||
DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
|
||||
if err != nil {
|
||||
log.Error("Failed to connet database:", err)
|
||||
return err
|
||||
}
|
||||
DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
|
||||
DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
|
||||
DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
|
||||
if DbClient.IsShowSQL {
|
||||
DbClient.XEngine.ShowSQL(true)
|
||||
}
|
||||
xEngine = DbClient.XEngine
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func XormConnectDatabase(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) (*xorm.Engine, error) {
|
||||
sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
|
||||
dbUser, dbPassword, dbHost, dbPort, dbName)
|
||||
log.Debugf("dbType:%s Connect to:%s:******@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
|
||||
dbType, dbUser, dbHost, dbPort, dbName)
|
||||
var err error
|
||||
xEngine, err = xorm.NewEngine(dbType, sqlStr) //1、Create xorm engine
|
||||
if err != nil {
|
||||
log.Error("Failed to connect database:", err)
|
||||
return nil, err
|
||||
}
|
||||
if log.GetLevel() == log.LOG_TRACE {
|
||||
xEngine.ShowSQL(true)
|
||||
}
|
||||
return xEngine, nil
|
||||
}
|
||||
|
||||
func IsNeedToAckAlarm(valueJson *dborm.ValueJson, alarm *Alarm) bool {
|
||||
log.Info("IsNeedToAckAlarm processing... ")
|
||||
if valueJson != nil {
|
||||
status, _ := strconv.Atoi(valueJson.AlarmStatus)
|
||||
log.Tracef("alarm.AlarmStatus=%d, alarm.AlarmType=%s, alarm.OrigSeverity=%s", alarm.AlarmStatus, alarm.AlarmType, alarm.OrigSeverity)
|
||||
log.Tracef("status=%d, valueJson.AlarmType=%s, valueJson.OrigSeverity=%s", status, valueJson.AlarmType, valueJson.OrigSeverity)
|
||||
|
||||
if alarm.AlarmStatus == status &&
|
||||
alarm.AlarmType == valueJson.AlarmType &&
|
||||
alarm.OrigSeverity == valueJson.OrigSeverity {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func SetAlarmAckInfo(valueJson *dborm.ValueJson, alarm *Alarm) {
|
||||
log.Info("SetAlarmAckInfo processing... ")
|
||||
alarm.AckState = AckStateAcked
|
||||
alarm.AckTime.Valid = true
|
||||
alarm.AckTime.Time = time.Now()
|
||||
alarm.AckUser = valueJson.AckUser
|
||||
}
|
||||
|
||||
// process alarm post message from NFs
|
||||
func PostAlarmFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PostAlarmFromNF processing... ")
|
||||
|
||||
vars := mux.Vars(r)
|
||||
apiVer := vars["apiVersion"]
|
||||
if apiVer != global.ApiVersionV1 {
|
||||
log.Error("Uri api version is invalid. apiVersion:", apiVer)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug("Request body:", string(body))
|
||||
alarmArray := new([]Alarm)
|
||||
|
||||
err = json.Unmarshal(body, &alarmArray)
|
||||
if err != nil {
|
||||
log.Error("Failed to Unmarshal:", err)
|
||||
services.ResponseBadRequest400InvalidJson(w)
|
||||
return
|
||||
}
|
||||
|
||||
valueJson, err := dborm.XormGetAAConfig()
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAAConfig:", err)
|
||||
//services.ResponseInternalServerError500ProcessError(w, err)
|
||||
//return
|
||||
}
|
||||
log.Trace("valueJson:", valueJson)
|
||||
// session := xEngine.NewSession()
|
||||
// defer session.Close()
|
||||
var activeAlarmNum int = 0
|
||||
for _, alarmData := range *alarmArray {
|
||||
log.Debug("alarmData:", alarmData)
|
||||
|
||||
session := xEngine.NewSession()
|
||||
defer session.Close()
|
||||
if alarmData.AlarmStatus == AlarmStatusClear {
|
||||
alarmData.ClearType = ClearTypeAutoClear
|
||||
alarmData.ClearTime.Valid = true
|
||||
tm, _ := time.Parse(time.RFC3339, alarmData.EventTime)
|
||||
log.Debugf("EventTime:%s tm:%d tm-datetime:%s", alarmData.EventTime, tm, tm.Local().Format(time.DateTime))
|
||||
alarmData.ClearTime.Time = tm
|
||||
if IsNeedToAckAlarm(valueJson, &alarmData) == true {
|
||||
SetAlarmAckInfo(valueJson, &alarmData)
|
||||
affected, err := session.Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Cols("alarm_status", "clear_type", "clear_time", "ack_state", "ack_time", "ack_user").
|
||||
Update(alarmData)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to update alarm data:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
affected, err := session.Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Cols("alarm_status", "clear_type", "clear_time").
|
||||
Update(alarmData)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to update alarm data:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
}
|
||||
log.Trace("alarmData:", alarmData)
|
||||
var currentSeq string
|
||||
var seq int
|
||||
has, err := xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
|
||||
Desc("alarm_seq").
|
||||
Cols("alarm_seq").
|
||||
Limit(1).
|
||||
Get(¤tSeq)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
if has == true {
|
||||
seq, _ = strconv.Atoi(currentSeq)
|
||||
}
|
||||
|
||||
eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
|
||||
alarmLog := new(AlarmLog)
|
||||
alarmLog.NeType = alarmData.NeType
|
||||
alarmLog.NeId = alarmData.NeId
|
||||
alarmLog.AlarmSeq = seq
|
||||
alarmLog.AlarmId = alarmData.AlarmId
|
||||
alarmLog.AlarmCode = alarmData.AlarmCode
|
||||
alarmLog.AlarmStatus = alarmData.AlarmStatus
|
||||
alarmLog.EventTime = eventTime
|
||||
log.Debug("alarmLog:", alarmLog)
|
||||
|
||||
affected, err := session.Insert(alarmLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert alarm_log:", err)
|
||||
}
|
||||
|
||||
// todo: PerceivedSeverity set color
|
||||
var severity string
|
||||
has, err = xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
//OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
|
||||
Asc("orig_severity").
|
||||
Cols("orig_severity").
|
||||
Limit(1).
|
||||
Get(&severity)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
|
||||
|
||||
if has == true && severity > alarmData.OrigSeverity {
|
||||
// update exist record
|
||||
_, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
Update(&Alarm{PerceivedSeverity: severity})
|
||||
if err != nil {
|
||||
log.Error("Failed to update alarm:", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
session.Commit()
|
||||
// for alarm forward time format
|
||||
alarmData.EventTime = eventTime
|
||||
} else {
|
||||
activeAlarmNum++
|
||||
has, err := xEngine.Table("alarm").
|
||||
Where("alarm_id=? and ne_type=? and ne_id=? and alarm_status=1",
|
||||
alarmData.AlarmId, alarmData.NeType, alarmData.NeId).
|
||||
Exist()
|
||||
if err == nil && has == true {
|
||||
log.Warn("Exist the same alarm")
|
||||
continue
|
||||
}
|
||||
|
||||
var currentSeq string
|
||||
has, err = xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
|
||||
Desc("alarm_seq").
|
||||
//Desc("event_time").
|
||||
Cols("alarm_seq").
|
||||
Limit(1).
|
||||
Get(¤tSeq)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, currentSeq=%s activeAlarmNum=%d",
|
||||
alarmData.NeType, alarmData.NeId, currentSeq, activeAlarmNum)
|
||||
|
||||
if has == true {
|
||||
seq, _ := strconv.Atoi(currentSeq)
|
||||
alarmData.AlarmSeq = seq + 1
|
||||
if alarmData.AlarmSeq > global.MaxInt32Number {
|
||||
alarmData.AlarmSeq = AlarmSeqBeginNumber
|
||||
}
|
||||
} else {
|
||||
alarmData.AlarmSeq = AlarmSeqBeginNumber
|
||||
}
|
||||
|
||||
// todo: PerceivedSeverity set color
|
||||
var severity string
|
||||
has, err = xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
//OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
|
||||
Asc("orig_severity").
|
||||
Cols("orig_severity").
|
||||
Limit(1).
|
||||
Get(&severity)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
|
||||
|
||||
if has == false || severity == alarmData.OrigSeverity {
|
||||
alarmData.PerceivedSeverity = alarmData.OrigSeverity
|
||||
} else if severity > alarmData.OrigSeverity {
|
||||
alarmData.PerceivedSeverity = alarmData.OrigSeverity
|
||||
} else {
|
||||
alarmData.PerceivedSeverity = severity
|
||||
// update exist record
|
||||
_, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
Update(&Alarm{PerceivedSeverity: alarmData.PerceivedSeverity})
|
||||
if err != nil {
|
||||
log.Error("Failed to update alarm:", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
|
||||
alarmData.ObjectUid = alarmData.NeId
|
||||
alarmData.ObjectType = "VNFM"
|
||||
alarmData.EventTime = eventTime
|
||||
if alarmData.LocationInfo == "" {
|
||||
alarmData.LocationInfo = fmt.Sprintf("Host:%s", r.RemoteAddr)
|
||||
}
|
||||
if alarmData.AddInfo == "" {
|
||||
alarmData.LocationInfo = fmt.Sprintf("subNeInfo:%s", alarmData.NeType)
|
||||
}
|
||||
if IsNeedToAckAlarm(valueJson, &alarmData) == true {
|
||||
SetAlarmAckInfo(valueJson, &alarmData)
|
||||
}
|
||||
log.Debug("alarmData:", alarmData)
|
||||
affected, err := session.Insert(alarmData)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert alarm data:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
alarmLog := new(AlarmLog)
|
||||
alarmLog.NeType = alarmData.NeType
|
||||
alarmLog.NeId = alarmData.NeId
|
||||
alarmLog.AlarmSeq = alarmData.AlarmSeq
|
||||
alarmLog.AlarmId = alarmData.AlarmId
|
||||
alarmLog.AlarmCode = alarmData.AlarmCode
|
||||
alarmLog.AlarmStatus = alarmData.AlarmStatus
|
||||
alarmLog.EventTime = eventTime
|
||||
log.Trace("alarmLog:", alarmLog)
|
||||
|
||||
affected, err = session.Insert(alarmLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert alarm_log:", err)
|
||||
}
|
||||
session.Commit()
|
||||
}
|
||||
if config.GetYamlConfig().Alarm.ForwardAlarm {
|
||||
if err = AlarmEmailForward(&alarmData); err != nil {
|
||||
log.Error("Failed to AlarmEmailForward:", err)
|
||||
}
|
||||
if err = AlarmForwardBySMS(&alarmData); err != nil {
|
||||
log.Error("Failed to AlarmForwardBySMS:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
services.ResponseStatusOK200Null(w)
|
||||
}
|
||||
|
||||
// process alarm get from NFs
|
||||
func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("GetAlarmFromNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
//var neInfo *dborm.NeInfo
|
||||
var nes []dborm.NeInfo
|
||||
_, err = dborm.XormGetAllNeInfo(&nes)
|
||||
if err != nil {
|
||||
log.Error("Failed to get all ne info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ne := range nes {
|
||||
hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
|
||||
apiUri := fmt.Sprintf(UriAlarmsFmt, strings.ToLower(ne.NeType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF: Get ", requestURI2NF)
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get:", err)
|
||||
//services.ResponseInternalServerError500ProcessError(w, err)
|
||||
continue
|
||||
}
|
||||
body := response.Body()
|
||||
log.Debug("Request body:", string(body))
|
||||
alarmArray := new([]Alarm)
|
||||
err = json.Unmarshal(body, &alarmArray)
|
||||
if err != nil {
|
||||
log.Error("Failed to Unmarshal:", err)
|
||||
//services.ResponseInternalServerError500ProcessError(w, err)
|
||||
continue
|
||||
}
|
||||
valueJson, err := dborm.XormGetAAConfig()
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAAConfig:", err)
|
||||
//services.ResponseInternalServerError500ProcessError(w, err)
|
||||
continue
|
||||
}
|
||||
if alarmArray == nil {
|
||||
log.Info("Not found sync alarms, neType=%s, neId=%s", ne.NeType, ne.NeId)
|
||||
//services.ResponseInternalServerError500ProcessError(w, err)
|
||||
continue
|
||||
}
|
||||
// session := xEngine.NewSession()
|
||||
// defer session.Close()
|
||||
var activeAlarmNum int = 0
|
||||
for _, alarmData := range *alarmArray {
|
||||
log.Debug("alarmData:", alarmData)
|
||||
|
||||
session := xEngine.NewSession()
|
||||
defer session.Close()
|
||||
// todo: clear alarm ....
|
||||
if alarmData.AlarmStatus == AlarmStatusClear {
|
||||
exist, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Exist()
|
||||
if err == nil || exist == false {
|
||||
log.Info("Not found active alarm: ne_id=%s, alarm_id=%s", alarmData.NeId, alarmData.AlarmId)
|
||||
continue
|
||||
}
|
||||
alarmData.ClearType = ClearTypeAutoClear
|
||||
alarmData.ClearTime.Valid = true
|
||||
tm, _ := time.Parse(time.RFC3339, alarmData.EventTime)
|
||||
log.Debugf("EventTime:%s tm:%d tm-datetime:%s", alarmData.EventTime, tm, tm.Local().Format(time.DateTime))
|
||||
alarmData.ClearTime.Time = tm
|
||||
if IsNeedToAckAlarm(valueJson, &alarmData) == true {
|
||||
SetAlarmAckInfo(valueJson, &alarmData)
|
||||
log.Debug("alarmData:", alarmData)
|
||||
affected, err := session.
|
||||
Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Cols("alarm_status", "clear_type", "clear_time", "ack_state", "ack_time", "ack_user").
|
||||
Update(alarmData)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to update alarm data:", err)
|
||||
//services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
affected, err := session.
|
||||
Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
|
||||
Cols("alarm_status", "clear_type", "clear_time").
|
||||
Update(alarmData)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to update alarm data:", err)
|
||||
//services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
|
||||
alarmLog := new(AlarmLog)
|
||||
alarmLog.NeType = alarmData.NeType
|
||||
alarmLog.NeId = alarmData.NeId
|
||||
alarmLog.AlarmSeq = alarmData.AlarmSeq
|
||||
alarmLog.AlarmId = alarmData.AlarmId
|
||||
alarmLog.AlarmCode = alarmData.AlarmCode
|
||||
alarmLog.AlarmStatus = alarmData.AlarmStatus
|
||||
alarmLog.EventTime = eventTime
|
||||
log.Debug("alarmLog:", alarmLog)
|
||||
|
||||
affected, err := session.Insert(alarmLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert alarm_log:", err)
|
||||
}
|
||||
|
||||
// todo: PerceivedSeverity set color
|
||||
var severity string
|
||||
has, err := xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
//OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
|
||||
Asc("orig_severity").
|
||||
Cols("orig_severity").
|
||||
Limit(1).
|
||||
Get(&severity)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
|
||||
|
||||
if has == true && severity > alarmData.OrigSeverity {
|
||||
// update exist record
|
||||
_, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=?", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
Update(&Alarm{PerceivedSeverity: severity})
|
||||
if err != nil {
|
||||
log.Error("Failed to update alarm:", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
session.Commit()
|
||||
// for alarm forward time format
|
||||
alarmData.EventTime = eventTime
|
||||
} else {
|
||||
activeAlarmNum++
|
||||
has, err := xEngine.Table("alarm").
|
||||
Where("alarm_id=? and ne_type=? and ne_id=? and alarm_status=1",
|
||||
alarmData.AlarmId, alarmData.NeType, alarmData.NeId).
|
||||
Exist()
|
||||
if err == nil && has == true {
|
||||
log.Warn("Exist the same alarm")
|
||||
continue
|
||||
}
|
||||
|
||||
var currentSeq string
|
||||
has, err = xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
|
||||
Desc("alarm_seq").
|
||||
//Desc("event_time").
|
||||
Cols("alarm_seq").
|
||||
Limit(1).
|
||||
Get(¤tSeq)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, currentSeq=%s, activeAlarmNum=%d",
|
||||
alarmData.NeType, alarmData.NeId, currentSeq, activeAlarmNum)
|
||||
|
||||
if has == true {
|
||||
seq, _ := strconv.Atoi(currentSeq)
|
||||
alarmData.AlarmSeq = seq + 1
|
||||
if alarmData.AlarmSeq > global.MaxInt32Number {
|
||||
alarmData.AlarmSeq = AlarmSeqBeginNumber
|
||||
}
|
||||
} else {
|
||||
alarmData.AlarmSeq = AlarmSeqBeginNumber
|
||||
}
|
||||
|
||||
// todo: PerceivedSeverity set color
|
||||
var severity string
|
||||
has, err = xEngine.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
//OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
|
||||
Asc("orig_severity").
|
||||
Cols("orig_severity").
|
||||
Limit(1).
|
||||
Get(&severity)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
|
||||
|
||||
if has == false || severity == alarmData.OrigSeverity {
|
||||
alarmData.PerceivedSeverity = alarmData.OrigSeverity
|
||||
} else if severity > alarmData.OrigSeverity {
|
||||
alarmData.PerceivedSeverity = alarmData.OrigSeverity
|
||||
} else {
|
||||
alarmData.PerceivedSeverity = severity
|
||||
// update exist record
|
||||
_, err := session.Table("alarm").
|
||||
Where("ne_type=? and ne_id=? and event_time=?", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
|
||||
Update(&Alarm{PerceivedSeverity: alarmData.PerceivedSeverity})
|
||||
if err != nil {
|
||||
log.Error("Failed to update alarm:", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
alarmData.ObjectUid = alarmData.NeId
|
||||
alarmData.ObjectType = "VNFM"
|
||||
alarmData.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
|
||||
if IsNeedToAckAlarm(valueJson, &alarmData) == true {
|
||||
SetAlarmAckInfo(valueJson, &alarmData)
|
||||
}
|
||||
log.Trace("alarmData:", alarmData)
|
||||
affected, err := session.Insert(alarmData)
|
||||
if err == nil && affected > 0 {
|
||||
alarmLog := new(AlarmLog)
|
||||
alarmLog.NeType = alarmData.NeType
|
||||
alarmLog.NeId = alarmData.NeId
|
||||
alarmLog.AlarmSeq = alarmData.AlarmSeq
|
||||
alarmLog.AlarmId = alarmData.AlarmId
|
||||
alarmLog.AlarmCode = alarmData.AlarmCode
|
||||
alarmLog.AlarmStatus = alarmData.AlarmStatus
|
||||
alarmLog.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
|
||||
log.Debug("alarmLog:", alarmLog)
|
||||
affected, err = session.Insert(alarmLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
//services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
continue
|
||||
}
|
||||
session.Commit()
|
||||
if config.GetYamlConfig().Alarm.ForwardAlarm {
|
||||
if err = AlarmEmailForward(&alarmData); err != nil {
|
||||
log.Error("Failed to AlarmEmailForward:", err)
|
||||
}
|
||||
if err = AlarmForwardBySMS(&alarmData); err != nil {
|
||||
log.Error("Failed to AlarmForwardBySMS:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Warn("Failed to insert alarm data:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
services.ResponseStatusOK200Null(w)
|
||||
}
|
||||
111
features/fm/email.go
Normal file
111
features/fm/email.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package fm
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/restagent/config"
|
||||
|
||||
"gopkg.in/gomail.v2"
|
||||
)
|
||||
|
||||
func AlarmEmailForward(alarmData *Alarm) error {
|
||||
log.Info("AlarmEmailForward processing... ")
|
||||
|
||||
message := `
|
||||
<p> Hello information,</p>
|
||||
test, test
|
||||
<p style="text-indent:2em">Best Wishes!</p>
|
||||
`
|
||||
|
||||
// QQ 邮箱:
|
||||
// SMTP 服务器地址:smtp.qq.com(SSL协议端口:465/994 | 非SSL协议端口:25)
|
||||
// 163 邮箱:
|
||||
// SMTP 服务器地址:smtp.163.com(端口:25)
|
||||
// host := "mail.agrandtech.com"
|
||||
// port := 25
|
||||
// userName := "smtpext@agrandtech.com"
|
||||
// password := "1000smtp@omc!"
|
||||
|
||||
host := config.GetYamlConfig().Alarm.Email.Smtp
|
||||
port := int(config.GetYamlConfig().Alarm.Email.Port)
|
||||
userName := config.GetYamlConfig().Alarm.Email.User
|
||||
password := config.GetYamlConfig().Alarm.Email.Password
|
||||
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", userName) // 发件人
|
||||
//m.SetHeader("From", "alias"+"<"+"aliastest"+">") // 增加发件人别名
|
||||
|
||||
emails, err := dborm.XormGetAlarmForward("Email")
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAlarmForward:", err)
|
||||
return err
|
||||
} else if emails == nil || len(*emails) == 0 {
|
||||
err := errors.New("not found forward email list")
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
forwardLog := &dborm.AlarmForwardLog{
|
||||
NeType: alarmData.NeType,
|
||||
NeID: alarmData.NeId,
|
||||
AlarmID: alarmData.AlarmId,
|
||||
AlarmTitle: alarmData.AlarmTitle,
|
||||
AlarmSeq: alarmData.AlarmSeq,
|
||||
EventTime: alarmData.EventTime,
|
||||
ToUser: strings.Join(*emails, ","),
|
||||
}
|
||||
for _, email := range *emails {
|
||||
m.SetHeader("To", email) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
|
||||
}
|
||||
|
||||
//m.SetHeader("To", "zhangshuzhong@agrandtech.com", "simonzhangsz@outlook.com") // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
|
||||
//m.SetHeader("Cc", "******@qq.com") // 抄送,可以多个
|
||||
//m.SetHeader("Bcc", "******@qq.com") // 暗送,可以多个
|
||||
m.SetHeader("Subject", "Alarm from OMC!") // 邮件主题
|
||||
|
||||
// text/html 的意思是将文件的 content-type 设置为 text/html 的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。
|
||||
// 可以通过 text/html 处理文本格式进行特殊处理,如换行、缩进、加粗等等
|
||||
//m.SetBody("text/html", fmt.Sprintf(message, *alarm))
|
||||
m.SetBody("text/html", message)
|
||||
|
||||
// text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理
|
||||
// m.SetBody("text/plain", "纯文本")
|
||||
// m.Attach("test.sh") // 附件文件,可以是文件,照片,视频等等
|
||||
// m.Attach("lolcatVideo.mp4") // 视频
|
||||
// m.Attach("lolcat.jpg") // 照片
|
||||
|
||||
d := gomail.NewDialer(
|
||||
host,
|
||||
port,
|
||||
userName,
|
||||
password,
|
||||
)
|
||||
// 关闭SSL协议认证
|
||||
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
operResult := fmt.Sprintf("Failed to DialAndSend:%v", err)
|
||||
log.Error(operResult)
|
||||
forwardLog.OperResult = operResult
|
||||
affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
operResult := fmt.Sprintf("Email sent successfully!:", err)
|
||||
log.Error(operResult)
|
||||
forwardLog.OperResult = operResult
|
||||
affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
103
features/fm/smsforward.go
Normal file
103
features/fm/smsforward.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package fm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/restagent/config"
|
||||
)
|
||||
|
||||
func AlarmForwardBySMS(alarmData *Alarm) error {
|
||||
log.Info("AlarmForwardBySMS processing... ")
|
||||
|
||||
SMSFforwardconfig := config.GetYamlConfig().Alarm.SMS
|
||||
// 阿里云短信API的请求地址
|
||||
apiURL := SMSFforwardconfig.ApiURL
|
||||
|
||||
// 阿里云短信API的AccessKey ID和AccessKey Secret
|
||||
//accessKeyID := SMSFforwardconfig.AccessKeyID
|
||||
accessKeySecret := SMSFforwardconfig.AccessKeySecret
|
||||
|
||||
toUsers, err := dborm.XormGetAlarmForward("SMS")
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAlarmForward:", err)
|
||||
return err
|
||||
} else if toUsers == nil {
|
||||
err := errors.New("not found forward phone number")
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
for _, toUser := range *toUsers {
|
||||
// 短信相关参数
|
||||
params := url.Values{}
|
||||
params.Set("PhoneNumbers", toUser)
|
||||
params.Set("SignName", SMSFforwardconfig.SignName)
|
||||
params.Set("TemplateCode", SMSFforwardconfig.TemplateCode)
|
||||
params.Set("TemplateParam", `{"message":"alarm"}`)
|
||||
|
||||
// 构建请求URL
|
||||
reqURL := apiURL + "?Action=SendSms&" + params.Encode()
|
||||
|
||||
// 创建HTTP请求
|
||||
req, err := http.NewRequest("GET", reqURL, nil)
|
||||
if err != nil {
|
||||
log.Error("Failed to create request:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加请求头部
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Authorization", "APPCODE "+accessKeySecret)
|
||||
|
||||
forwardLog := &dborm.AlarmForwardLog{
|
||||
NeType: alarmData.NeType,
|
||||
NeID: alarmData.NeId,
|
||||
AlarmID: alarmData.AlarmId,
|
||||
AlarmTitle: alarmData.AlarmTitle,
|
||||
AlarmSeq: alarmData.AlarmSeq,
|
||||
EventTime: alarmData.EventTime,
|
||||
ToUser: toUser,
|
||||
}
|
||||
// 发送请求
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
operResult := fmt.Sprintf("Failed to send request:%v", err)
|
||||
log.Error(operResult)
|
||||
forwardLog.OperResult = operResult
|
||||
affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 解析响应
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
log.Info("SMS sent successfully!")
|
||||
operResult := fmt.Sprintf("SMS sent successfully!")
|
||||
forwardLog.OperResult = operResult
|
||||
affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
operResult := fmt.Sprintf("Failed to send SMS, StatusCode=%d", resp.StatusCode)
|
||||
log.Error(operResult)
|
||||
forwardLog.OperResult = operResult
|
||||
affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
|
||||
if err != nil && affected <= 0 {
|
||||
log.Error("Failed to insert data:", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user