Skip to content

Commit cd0964d

Browse files
author
Cairry
committed
✨ Add alert rule batch modify api
1 parent c3fe422 commit cd0964d

File tree

4 files changed

+143
-1
lines changed

4 files changed

+143
-1
lines changed

api/rule.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func (ruleController ruleController) API(gin *gin.RouterGroup) {
4949
{
5050
c.POST("import", ruleController.Import)
5151
c.POST("ruleChangeStatus", ruleController.ChangeStatus)
52+
c.POST("change", ruleController.Change)
5253
}
5354
}
5455

@@ -147,3 +148,21 @@ func (ruleController ruleController) Import(ctx *gin.Context) {
147148
return services.RuleService.Import(r)
148149
})
149150
}
151+
152+
func (ruleController ruleController) Change(ctx *gin.Context) {
153+
r := new(types.RequestRuleChange)
154+
BindJson(ctx, r)
155+
156+
Service(ctx, func() (interface{}, interface{}) {
157+
tokenStr := ctx.Request.Header.Get("Authorization")
158+
if len(tokenStr) <= 0 {
159+
return nil, errors.New("用户未登录")
160+
}
161+
r.UpdateBy = tools.GetUser(tokenStr)
162+
163+
tid, _ := ctx.Get("TenantID")
164+
r.TenantId = tid.(string)
165+
166+
return services.RuleService.Change(r)
167+
})
168+
}

internal/repo/rule.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package repo
22

33
import (
4-
"gorm.io/gorm"
54
"watchAlert/internal/models"
5+
6+
"gorm.io/gorm"
67
)
78

89
type (

internal/services/rule.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type InterRuleService interface {
2727
Get(req interface{}) (interface{}, interface{})
2828
ChangeStatus(req interface{}) (interface{}, interface{})
2929
Import(req interface{}) (interface{}, interface{})
30+
Change(req interface{}) (interface{}, interface{})
3031
}
3132

3233
func newInterRuleService(ctx *ctx.Context) InterRuleService {
@@ -404,3 +405,116 @@ func (rs ruleService) Import(req interface{}) (interface{}, interface{}) {
404405

405406
return nil, nil
406407
}
408+
409+
func (rs ruleService) Change(req interface{}) (interface{}, interface{}) {
410+
r := req.(*types.RequestRuleChange)
411+
412+
if len(r.RuleIds) == 0 {
413+
return nil, fmt.Errorf("rule_ids 不能为空")
414+
}
415+
416+
if len(r.Change) == 0 {
417+
return nil, fmt.Errorf("change 参数不能为空")
418+
}
419+
420+
// 遍历所有要更新的规则ID
421+
for _, ruleId := range r.RuleIds {
422+
// 获取当前规则
423+
rule := models.AlertRule{}
424+
err := rs.ctx.DB.DB().Model(&models.AlertRule{}).
425+
Where("tenant_id = ? AND rule_id = ?", r.TenantId, ruleId).
426+
First(&rule).Error
427+
if err != nil {
428+
return nil, fmt.Errorf("获取规则失败, ruleId: %s, error: %v", ruleId, err)
429+
}
430+
431+
rule.UpdateAt = time.Now().Unix()
432+
rule.UpdateBy = r.UpdateBy
433+
434+
// 根据 change 参数动态更新字段
435+
for field, value := range r.Change {
436+
switch field {
437+
case "rule_group_id":
438+
if v, ok := value.(string); ok {
439+
rule.RuleGroupId = v
440+
} else {
441+
return nil, fmt.Errorf("字段 %s 的值类型错误", field)
442+
}
443+
break
444+
case "datasource_ids":
445+
if v, ok := value.([]interface{}); ok {
446+
var datasourceIds []string
447+
for _, val := range v {
448+
datasourceIds = append(datasourceIds, fmt.Sprintf("%v", val))
449+
}
450+
rule.DatasourceIdList = datasourceIds
451+
} else if v, ok := value.([]string); ok {
452+
rule.DatasourceIdList = v
453+
} else {
454+
return nil, fmt.Errorf("字段 %s 的值类型错误", field)
455+
}
456+
break
457+
case "fault_center_id":
458+
if v, ok := value.(string); ok {
459+
rule.FaultCenterId = v
460+
} else {
461+
return nil, fmt.Errorf("필드 %s 의 값 타입이 잘못되었습니다", field)
462+
}
463+
break
464+
case "enabled":
465+
if v, ok := value.(bool); ok {
466+
isEnabled := v
467+
rule.Enabled = &isEnabled
468+
} else {
469+
return nil, fmt.Errorf("필드 %s 의 값 타입이 잘못되었습니다", field)
470+
}
471+
break
472+
default:
473+
return nil, fmt.Errorf("지원되지 않는 필드: %s", field)
474+
}
475+
}
476+
477+
// 데이터베이스 업데이트
478+
err = rs.ctx.DB.Rule().Update(rule)
479+
if err != nil {
480+
return nil, fmt.Errorf("규칙 업데이트 실패, ruleId: %s, 오류: %v", ruleId, err)
481+
}
482+
483+
// 규칙 활성화 상태에 따라 적절한 처리
484+
if *rule.Enabled {
485+
if alert.IsLeader() {
486+
// 리더: 기존 평가 고루틴을 중지하고 새로운 것을 시작합니다
487+
alert.AlertRule.Stop(ruleId)
488+
alert.AlertRule.Submit(rule)
489+
} else {
490+
tools.PublishReloadMessage(rs.ctx.Ctx, client.Redis, tools.ChannelRuleReload, tools.ReloadMessage{
491+
Action: tools.ActionUpdate,
492+
ID: rule.RuleId,
493+
TenantID: rule.TenantId,
494+
Name: rule.RuleName,
495+
})
496+
}
497+
} else {
498+
// 删除缓存
499+
fingerprints := rs.ctx.Redis.Alert().GetFingerprintsByRuleId(r.TenantId, rule.FaultCenterId, rule.RuleId)
500+
for _, fingerprint := range fingerprints {
501+
rs.ctx.Redis.Alert().RemoveAlertEvent(r.TenantId, rule.FaultCenterId, fingerprint)
502+
}
503+
504+
if alert.IsLeader() {
505+
// 리더: 평가 고루틴 중지
506+
alert.AlertRule.Stop(ruleId)
507+
} else {
508+
// 팔로워: 비활성화 메시지를 발행하여 리더에게 알림
509+
tools.PublishReloadMessage(rs.ctx.Ctx, client.Redis, tools.ChannelRuleReload, tools.ReloadMessage{
510+
Action: tools.ActionDisable,
511+
ID: rule.RuleId,
512+
TenantID: rule.TenantId,
513+
Name: rule.RuleName,
514+
})
515+
}
516+
}
517+
}
518+
519+
return nil, nil
520+
}

internal/types/rule.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,11 @@ func (r Rule) GetEnable() *bool {
144144
var enable = false
145145
return &enable
146146
}
147+
148+
// RequestRuleChange 请求修改规则的任意字段
149+
type RequestRuleChange struct {
150+
TenantId string `json:"tenantId"`
151+
RuleIds []string `json:"rule_ids"`
152+
Change map[string]interface{} `json:"change"`
153+
UpdateBy string `json:"updateBy"`
154+
}

0 commit comments

Comments
 (0)