Commit 498bfc45 authored by 李科's avatar 李科

feat: 完善批量推送逻辑

parent 0de4349f
......@@ -6,34 +6,36 @@ import (
// Alert 预警表
type Alert struct {
Id int `json:"id"` // 预警列表ID,主键,自增长
AlertPoint string `json:"alert_point"` // 预警点
AlertRulesId string `json:"alert_rules_id"` // 告警规则id
RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
AlertTime jsontime.Time `json:"alert_time"` // 预警时间
ClassId int `json:"class_id"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name"` // 预警分类名称 TODO 该字段做关联存储或查询
ClassName string `json:"class_name"` // 预警对象名称 TODO 该字段做关联存储或查询
MetricConfigId string `json:"metric_config_id"` // 预警指标id // 预警指标
MetricConfigName string `json:"metric_config_name"` // 预警指标名称
AlertRuleType string `json:"alert_rule_type"` // 预警规则类型id TODO 该字段做关联存储或查询
AlertRuleTypeName string `json:"alert_rule_type_name"` // 预警规则类型名称 TODO 该字段做关联存储或查询
CurrentValue float64 `json:"current_value"` // 当前报警值
AlertCondition string `json:"alert_condition" xorm:"'alert_condition'"` // 预警规则(预警阈值) 字典值
NotificationCount int `json:"notification_count"` // 通知人数
PushCount int `json:"push_count"` // 推送次数
LastPushTime jsontime.Time `json:"last_push_time"` // 最近推送时间
Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭
DisposedList []DisposedList `json:"disposed_list"` // 处置列表
IsDisposed int `json:"is_disposed"` // 是否处置(工单管理),1:已处置,2:未处置 通过DisposedList逻辑处理回显
CloseRemark string `json:"close_remark"` // 关闭备注(预警关闭提醒)
CloseUser string `json:"close_user"` // 关闭用户,预警关闭提醒
CloseTime jsontime.Time `json:"close_time"` // 关闭关闭时间,预警关闭提醒
DeferPush int `json:"defer_push" xorm:"defer_push"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人
CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间
UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人
UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间
Id int `json:"id"` // 预警列表ID,主键,自增长
AlertPoint string `json:"alert_point"` // 预警点
AlertRulesId string `json:"alert_rules_id"` // 告警规则id
RiskLevel int `json:"risk_level"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
AlertTime jsontime.Time `json:"alert_time"` // 预警时间
ClassId int `json:"class_id"` // 预警对象id(级联:预警分类/预警对象)
ClassParentName string `json:"class_parent_name"` // 预警分类名称 TODO 该字段做关联存储或查询
ClassName string `json:"class_name"` // 预警对象名称 TODO 该字段做关联存储或查询
MetricConfigId string `json:"metric_config_id"` // 预警指标id // 预警指标
MetricConfigName string `json:"metric_config_name"` // 预警指标名称
AlertRuleType string `json:"alert_rule_type"` // 预警规则类型id TODO 该字段做关联存储或查询
AlertRuleTypeName string `json:"alert_rule_type_name"` // 预警规则类型名称 TODO 该字段做关联存储或查询
CurrentValue float64 `json:"current_value"` // 当前报警值
AlertCondition AlertCondition `json:"alert_condition" xorm:"alert_condition"`
NotificationCount int `json:"notification_count"` // 通知人数
PushCount int `json:"push_count"` // 推送次数
LastPushTime jsontime.Time `json:"last_push_time"` // 最近推送时间
Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭
PushRecords []PushRecord `json:"push_records"`
DisposedList []DisposedList `json:"disposed_list"` // 处置列表
IsDisposed int `json:"is_disposed"` // 是否处置(工单管理),1:已处置,2:未处置 通过DisposedList逻辑处理回显
CloseRemark string `json:"close_remark"` // 关闭备注(预警关闭提醒)
CloseUser string `json:"close_user"` // 关闭用户,预警关闭提醒
CloseTime jsontime.Time `json:"close_time"` // 关闭关闭时间,预警关闭提醒
DeferPush int `json:"defer_push" xorm:"defer_push"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人
CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间
UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人
UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间
}
type DisposedList struct {
......@@ -43,6 +45,12 @@ type DisposedList struct {
DisposalTime jsontime.Time `json:"disposal_time"` // 处置时间(工单管理,结果反馈)
}
type OpenSearchIds struct {
Ids struct {
Values []string `json:"values"`
} `json:"ids"`
}
func (a *Alert) TableName() string {
return "alert"
}
......@@ -7,11 +7,13 @@ type PushRecord struct {
AlertId int `json:"alert_id" xorm:"alert_id"` // 告警id
AlertRulesId string `json:"alert_rules_id" xorm:"'alert_rules_id'"` // 告警规则id
RiskLevel int `json:"risk_level" xorm:"'risk_level'"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 dingtalk sms
NotifyMethod []string `json:"notify_method" xorm:"notify_method"` // 预警通知方式 dingtalk sms
SystemAccount string `json:"system_account" xorm:"system_account"` // 预警推送用户
PushTime jsontime.Time `json:"push_time" xorm:"'push_time'"` // 推送时间
PushType int `json:"push_type" xorm:"'push_type'"` // 推送类型,1:自动推送,2:手动推送
Status int `json:"status" xorm:"'status'"` // 推送状态,1:成功,2:失败
UserName string `json:"user_name" xorm:"user_name"` // 推送用户名称
Phone string `json:"phone" xorm:"phone"` // 推送手机号
CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人
CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间
UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人
......
......@@ -11,11 +11,12 @@ type DetailAlert struct {
type UpdateAlert struct {
Id int `json:"id" form:"id" binding:"required"`
//Ids []int `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids
CloseRemark string `json:"close_remark" form:"close_remark"` // 关闭备注
DeferPush int `json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
Status int `json:"status" form:"status" binding:"omitempty,oneof=1 2 3"` // 状态,1:已恢复 2:未恢复 3:已关闭
DisposalContent string `json:"disposal_content" form:"disposal_content"` // 处置内容(工单管理,结果反馈)
CloseRemark string `json:"close_remark" form:"close_remark"` // 关闭备注
DeferPush int `json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现
RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
Status int `json:"status" form:"status" binding:"omitempty,oneof=1 2 3"` // 状态,1:已恢复 2:未恢复 3:已关闭
DisposalContent string `json:"disposal_content" form:"disposal_content"` // 处置内容(工单管理,结果反馈)
PushRecords []entity.PushRecord `json:"push_records" form:"push_records"`
}
type BatchPushAlert struct {
......@@ -34,6 +35,7 @@ type BatchCloseAlert struct {
type ListAlert struct {
Id int `json:"id" form:"id"`
Ids []int `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids
RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险
Status int `json:"status" form:"status" binding:"omitempty,oneof=1 2 3"` // 状态,1:已恢复 2:未恢复 3:已关闭
Keyword string `json:"keyword" form:"keyword"` // 预警点/分类/指标
......
......@@ -5,9 +5,7 @@ import (
)
type AlertItem struct {
entity.Alert `xorm:"extends"`
AlertCondition entity.AlertCondition `json:"alert_condition" xorm:"alert_condition"`
PushRecords []PushRecordItem `json:"push_records"`
entity.Alert `xorm:"extends"`
}
type AlertList struct {
......
......@@ -4,7 +4,6 @@ import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
type PushRecordItem struct {
entity.PushRecord `xorm:"extends"`
NotifyMethod []string `json:"notify_method" xorm:"notify_method"` // 预警通知方式 dingtalk sms
}
type PushRecordList struct {
......
......@@ -3,7 +3,6 @@ package controller
import (
"github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
......@@ -33,12 +32,7 @@ func BatchPushAlert(c *gin.Context) {
}
svc := service.AlertSvc{User: header.GetUser(c)}
db, err := client.GetDbClient()
if err != nil {
SendJsonResponse(c, resp.DbConnectError.WithError(err), nil)
return
}
err = svc.BatchPushAlert(db.NewSession(), req)
err := svc.BatchPushAlert(req)
if err != nil {
SendJsonResponse(c, resp.FAIL.WithError(err), nil)
return
......
......@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"github.com/jinzhu/copier"
json "github.com/json-iterator/go"
"github.com/olivere/elastic/v7"
"github.com/opensearch-project/opensearch-go/opensearchapi"
......@@ -16,14 +15,12 @@ import (
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"go.uber.org/zap"
"io"
"log"
"net/http"
"strings"
"time"
"xorm.io/xorm"
)
type AlertSvc struct {
......@@ -44,7 +41,13 @@ var (
"type": "integer"
},
"alert_point": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"alert_rules_id": {
"type": "keyword"
......@@ -54,29 +57,53 @@ var (
},
"alert_time": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"ignore_malformed": true
},
"class_id": {
"type": "integer"
},
"class_parent_name": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"class_name": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"metric_config_id": {
"type": "keyword"
},
"metric_config_name": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"alert_rule_type": {
"type": "keyword"
},
"alert_rule_type_name": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"current_value": {
"type": "integer"
......@@ -89,28 +116,81 @@ var (
},
"last_push_time": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"ignore_malformed": true
},
"status": {
"type": "integer"
},
"disposed_list": {
"push_records": {
"type": "nested",
"properties": {
"is_disposed": {
"id": {
"type": "integer"
},
"disposal_content": {
"alert_id": {
"type": "integer"
},
"alert_rules_id": {
"type": "keyword"
},
"risk_level": {
"type": "integer"
},
"notify_method": {
"type": "keyword"
},
"system_account": {
"type": "keyword"
},
"push_type": {
"type": "integer"
},
"status": {
"type": "integer"
},
"user_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"phone": {
"type": "keyword"
},
"created_by": {
"type": "keyword"
},
"updated_by": {
"type": "keyword"
}
}
},
"disposed_list": {
"type": "nested",
"properties": {
"disposal_content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"is_disposed": {
"type": "integer"
},
"disposal_user": {
"type": "keyword"
},
"disposal_time": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"ignore_malformed": true
}
}
},
......@@ -118,35 +198,35 @@ var (
"type": "integer"
},
"close_remark": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"close_user": {
"type": "keyword"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"close_time": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"defer_push": {
"type": "integer"
},
"created_by": {
"type": "keyword"
},
"created_at": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"updated_by": {
"type": "keyword"
},
"updated_at": {
"type": "date",
"ignore_malformed": true,
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"alert_condition": {
"properties": {
"thresholds_min": {
......@@ -159,6 +239,31 @@ var (
"type": "integer"
}
}
},
"disposal_content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"created_by": {
"type": "keyword"
},
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"ignore_malformed": true
},
"updated_by": {
"type": "keyword"
},
"updated_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis",
"ignore_malformed": true
}
}
}
......@@ -281,6 +386,22 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
b, _ := json.Marshal(querySource)
log.Printf("es statements: %s\n", string(b))
if len(req.Ids) > 0 {
var idsStr []string
for _, id := range req.Ids {
idsStr = append(idsStr, cast.ToString(id))
}
ids := entity.OpenSearchIds{
Ids: struct {
Values []string `json:"values"`
}{idsStr},
}
b, err = json.Marshal(&ids)
if err != nil {
return
}
}
content := strings.NewReader(fmt.Sprintf(`{
"query": %s,
"from": %d,
......@@ -289,6 +410,7 @@ func (a *AlertSvc) IndexSearch(req request.ListAlert) (resp response.AlertList,
res := opensearchapi.SearchRequest{
Index: []string{OpenSearchIndex},
Body: content,
Sort: []string{"id"},
}
do, err := res.Do(context.Background(), cli)
if err != nil {
......@@ -357,6 +479,10 @@ func (a *AlertSvc) IndexUpdate(req request.UpdateAlert) (err error) {
doc["disposed_list"] = disposedList
}
if len(req.PushRecords) > 0 {
doc["push_records"] = req.PushRecords
}
if len(doc) == 0 {
return errors.New("no updated fields")
}
......@@ -405,17 +531,47 @@ func (a *AlertSvc) Update(req request.UpdateAlert) error {
return err
}
func (a *AlertSvc) BatchPushAlert(session *xorm.Session, req request.BatchPushAlert) error {
func (a *AlertSvc) BatchPushAlert(req request.BatchPushAlert) (err error) {
now := jsontime.Now()
data := entity.PushRecord{
CreatedBy: a.User.SystemAccount,
CreatedAt: now,
UpdatedBy: a.User.SystemAccount,
UpdatedAt: now,
}
_ = copier.Copy(&data, &req)
data.NotifyMethod = util.ConvertToString(req.NotifyMethod)
data.SystemAccount = util.ConvertToString(req.NotifyRecipients) // 循环查询
resp, err := a.IndexSearch(request.ListAlert{Ids: req.Ids})
if err != nil {
return
}
for _, alert := range resp.List {
pushRecords := alert.PushRecords
pushCount := len(alert.PushRecords)
for _, v := range req.NotifyRecipients {
pushCount++
data := entity.PushRecord{
Id: pushCount,
AlertId: alert.Id,
AlertRulesId: alert.AlertRulesId,
RiskLevel: alert.RiskLevel,
NotifyMethod: req.NotifyMethod,
SystemAccount: v.SystemAccount,
PushTime: now,
PushType: 2,
Status: 0, // TODO 需要调用之后更新
UserName: v.UserName,
Phone: v.Phone,
CreatedBy: a.User.SystemAccount,
CreatedAt: now,
UpdatedBy: a.User.SystemAccount,
UpdatedAt: now,
}
pushRecords = append(pushRecords, data)
}
err = a.IndexUpdate(request.UpdateAlert{
Id: alert.Id,
PushRecords: pushRecords,
})
if err != nil {
return
}
}
// TODO 批量推送用户告警
conf.Logger.Info("batch push", zap.Any("payload", req))
time.Sleep(time.Second)
......
......@@ -49,8 +49,10 @@ func (m *PushRecordSvc) GetDataById(req request.DetailPushRecord) (resp response
data := response.PushRecordItem{
PushRecord: entity.PushRecord{
Id: 1,
AlertId: 1,
AlertRulesId: "83343ef6-4a99-47bd-abb4-bcff52feb2ec",
RiskLevel: 1,
NotifyMethod: []string{"dingtalk", "sms"},
SystemAccount: "xiaowang",
PushTime: now,
PushType: 1,
......@@ -60,7 +62,6 @@ func (m *PushRecordSvc) GetDataById(req request.DetailPushRecord) (resp response
UpdatedBy: "admin",
UpdatedAt: now,
},
NotifyMethod: []string{"dingtalk", "sms"},
}
resp = data
return
......@@ -81,8 +82,8 @@ func (m *PushRecordSvc) List(req request.ListPushRecord) (resp response.PushReco
CreatedAt: now,
UpdatedBy: "admin",
UpdatedAt: now,
NotifyMethod: []string{"dingtalk", "sms"},
},
NotifyMethod: []string{"dingtalk", "sms"},
}
data2 := response.PushRecordItem{
PushRecord: entity.PushRecord{
......@@ -97,8 +98,8 @@ func (m *PushRecordSvc) List(req request.ListPushRecord) (resp response.PushReco
CreatedAt: now,
UpdatedBy: "admin",
UpdatedAt: now,
NotifyMethod: []string{"dingtalk", "sms"},
},
NotifyMethod: []string{"dingtalk", "sms"},
}
resp.List = append(resp.List, data1, data2)
resp.TotalCount = int64(len(resp.List))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment