mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-24 23:41:52 +08:00
Merge pull request #8920 from zhaoxiangchun/bugfix/zxc-commonalert
fix(monitor): modify notify alertInfo and alertOk detach resource
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
策略名称: {{.name}}
|
||||
触发时间: {{.start_time}}
|
||||
报警级别: {{.level}}
|
||||
触发条件: {{.description}}
|
||||
触发条件: {{.description | unescaped}}
|
||||
资源数量:{{len .matches}}
|
||||
资源名称:{{.resource_name}}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
AlertName: {{.name}}
|
||||
Time: {{.start_time}}
|
||||
Level: {{.level}}
|
||||
TriggerCondition: {{html .description}}
|
||||
TriggerCondition: {{.description | unescaped}}
|
||||
ResourceCount: {{len .matches}}
|
||||
ResourceName: {{.resource_name}}
|
||||
|
||||
|
||||
@@ -34,7 +34,9 @@ type AlertRecordCreateInput struct {
|
||||
|
||||
type AlertRecordRule struct {
|
||||
Metric string `json:"metric"`
|
||||
Measurement string `json:"measurement"`
|
||||
MeasurementDesc string `json:"measurement_desc"`
|
||||
Field string `json:"field"`
|
||||
FieldDesc string `json:"field_desc"`
|
||||
// 比较运算符, 比如: >, <, >=, <=
|
||||
Comparator string `json:"comparator"`
|
||||
|
||||
@@ -91,7 +91,9 @@ func getTemplate(ctx context.Context, topic string, contType string, channel npk
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmp, err := template.New(key).Parse(string(cont))
|
||||
tmp := template.New(key)
|
||||
tmp.Funcs(template.FuncMap{"unescaped": unescaped})
|
||||
tmp, err = tmp.Parse(string(cont))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -100,6 +102,10 @@ func getTemplate(ctx context.Context, topic string, contType string, channel npk
|
||||
return templatesTable[key], nil
|
||||
}
|
||||
|
||||
func unescaped(str string) template.HTML {
|
||||
return template.HTML(str)
|
||||
}
|
||||
|
||||
func getContent(ctx context.Context, topic string, contType string, channel npk.TNotifyChannel, data jsonutils.JSONObject) (string, error) {
|
||||
if channel == npk.NotifyByWebhook {
|
||||
return "", nil
|
||||
|
||||
@@ -223,11 +223,25 @@ func (c *QueryCondition) NewEvalMatch(context *alerting.EvalContext, series tsdb
|
||||
if alertDetails.GetPointStr {
|
||||
evalMatch.ValueStr = c.jointPointStr(series, evalMatch.ValueStr, valStrArr)
|
||||
}
|
||||
evalMatch.MeasurementDesc = alertDetails.MeasurementDisplayName
|
||||
evalMatch.FieldDesc = alertDetails.FieldDescription.DisplayName
|
||||
c.newRuleDescription(context, alertDetails)
|
||||
return evalMatch, nil
|
||||
}
|
||||
|
||||
func (c *QueryCondition) newRuleDescription(context *alerting.EvalContext, alertDetails *monitor.CommonAlertMetricDetails) {
|
||||
ruleDes := alerting.RuleDescription{
|
||||
AlertRecordRule: monitor.AlertRecordRule{
|
||||
Metric: fmt.Sprintf("%s.%s", alertDetails.Measurement, alertDetails.Field),
|
||||
Measurement: alertDetails.Measurement,
|
||||
MeasurementDesc: alertDetails.MeasurementDisplayName,
|
||||
Field: alertDetails.Field,
|
||||
FieldDesc: alertDetails.FieldDescription.DisplayName,
|
||||
Comparator: alertDetails.Comparator,
|
||||
Threshold: c.RationalizeValueFromUnit(alertDetails.Threshold, alertDetails.FieldDescription.Unit, ""),
|
||||
},
|
||||
}
|
||||
context.RuleDescription = &ruleDes
|
||||
}
|
||||
|
||||
func (c *QueryCondition) jointPointStr(series tsdb.TimeSeries, value string, valStrArr []string) string {
|
||||
str := ""
|
||||
for i := 0; i < len(valStrArr); i++ {
|
||||
|
||||
@@ -42,6 +42,7 @@ type EvalContext struct {
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Rule *Rule
|
||||
RuleDescription *RuleDescription
|
||||
|
||||
NoDataFound bool
|
||||
PrevAlertState monitor.AlertStateType
|
||||
@@ -50,6 +51,10 @@ type EvalContext struct {
|
||||
UserCred mcclient.TokenCredential
|
||||
}
|
||||
|
||||
type RuleDescription struct {
|
||||
monitor.AlertRecordRule
|
||||
}
|
||||
|
||||
// NewEvalContext is the EvalContext constructor.
|
||||
func NewEvalContext(alertCtx context.Context, userCred mcclient.TokenCredential, rule *Rule) *EvalContext {
|
||||
return &EvalContext{
|
||||
|
||||
@@ -17,7 +17,6 @@ package alerting
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -143,32 +142,47 @@ func (n *notificationService) getNeededNotifiers(nIds []string, evalCtx *EvalCon
|
||||
}
|
||||
}
|
||||
if shouldNotify {
|
||||
var matches []*monitor.EvalMatch
|
||||
if evalCtx.Firing {
|
||||
matches = evalCtx.EvalMatches
|
||||
} else {
|
||||
matches = evalCtx.AlertOkEvalMatches
|
||||
}
|
||||
recordCreateInput := monitor.AlertRecordCreateInput{
|
||||
StandaloneResourceCreateInput: apis.StandaloneResourceCreateInput{
|
||||
GenerateName: evalCtx.Rule.Name,
|
||||
},
|
||||
AlertId: evalCtx.Rule.Id,
|
||||
Level: evalCtx.Rule.Level,
|
||||
State: string(evalCtx.Rule.State),
|
||||
EvalData: matches,
|
||||
AlertRule: newAlertRecordRule(evalCtx),
|
||||
}
|
||||
createData := recordCreateInput.JSON(recordCreateInput)
|
||||
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(), createData, evalCtx.UserCred)
|
||||
if err != nil {
|
||||
log.Errorf("create alert record err:%v", err)
|
||||
}
|
||||
record.PostCreate(evalCtx.Ctx, evalCtx.UserCred, evalCtx.UserCred, nil, createData)
|
||||
n.createAlertRecordWhenNotify(evalCtx)
|
||||
}
|
||||
if !shouldNotify && evalCtx.shouldUpdateAlertState() && evalCtx.NoDataFound {
|
||||
n.detachAlertResourceWhenNodata(evalCtx)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (n *notificationService) createAlertRecordWhenNotify(evalCtx *EvalContext) {
|
||||
var matches []*monitor.EvalMatch
|
||||
if evalCtx.Firing {
|
||||
matches = evalCtx.EvalMatches
|
||||
} else {
|
||||
matches = evalCtx.AlertOkEvalMatches
|
||||
}
|
||||
recordCreateInput := monitor.AlertRecordCreateInput{
|
||||
StandaloneResourceCreateInput: apis.StandaloneResourceCreateInput{
|
||||
GenerateName: evalCtx.Rule.Name,
|
||||
},
|
||||
AlertId: evalCtx.Rule.Id,
|
||||
Level: evalCtx.Rule.Level,
|
||||
State: string(evalCtx.Rule.State),
|
||||
EvalData: matches,
|
||||
AlertRule: newAlertRecordRule(evalCtx),
|
||||
}
|
||||
createData := recordCreateInput.JSON(recordCreateInput)
|
||||
record, err := db.DoCreate(models.AlertRecordManager, evalCtx.Ctx, evalCtx.UserCred, jsonutils.NewDict(), createData, evalCtx.UserCred)
|
||||
if err != nil {
|
||||
log.Errorf("create alert record err:%v", err)
|
||||
}
|
||||
record.PostCreate(evalCtx.Ctx, evalCtx.UserCred, evalCtx.UserCred, nil, createData)
|
||||
}
|
||||
|
||||
func (n *notificationService) detachAlertResourceWhenNodata(evalCtx *EvalContext) {
|
||||
errs := models.CommonAlertManager.DetachAlertResourceByAlertId(evalCtx.Ctx, evalCtx.UserCred, evalCtx.Rule.Id)
|
||||
if len(errs) != 0 {
|
||||
log.Errorf("detachAlertResourceWhenNodata err:%#v", errors.NewAggregate(errs))
|
||||
}
|
||||
}
|
||||
|
||||
type NotifierPlugin struct {
|
||||
Type string
|
||||
Factory NotifierFactory
|
||||
@@ -205,25 +219,14 @@ func InitNotifier(config NotificationConfig) (Notifier, error) {
|
||||
|
||||
func newAlertRecordRule(evalCtx *EvalContext) monitor.AlertRecordRule {
|
||||
alertRule := monitor.AlertRecordRule{}
|
||||
if evalCtx.RuleDescription != nil {
|
||||
alertRule = evalCtx.RuleDescription.AlertRecordRule
|
||||
}
|
||||
if evalCtx.Rule.Frequency < 60 {
|
||||
alertRule.Period = fmt.Sprintf("%ds", evalCtx.Rule.Frequency)
|
||||
} else {
|
||||
alertRule.Period = fmt.Sprintf("%dm", evalCtx.Rule.Frequency/60)
|
||||
}
|
||||
ruleStr := evalCtx.Rule.Message
|
||||
ruleElementArr := strings.Split(ruleStr, " ")
|
||||
if len(ruleElementArr) == 3 {
|
||||
alertRule.Metric = ruleElementArr[0]
|
||||
alertRule.Comparator = ruleElementArr[1]
|
||||
alertRule.Threshold = ruleElementArr[2]
|
||||
}
|
||||
if len(evalCtx.EvalMatches) != 0 {
|
||||
alertRule.MeasurementDesc = evalCtx.EvalMatches[0].MeasurementDesc
|
||||
alertRule.FieldDesc = evalCtx.EvalMatches[0].FieldDesc
|
||||
}
|
||||
if len(evalCtx.AlertOkEvalMatches) != 0 {
|
||||
alertRule.MeasurementDesc = evalCtx.AlertOkEvalMatches[0].MeasurementDesc
|
||||
alertRule.FieldDesc = evalCtx.AlertOkEvalMatches[0].FieldDesc
|
||||
}
|
||||
|
||||
return alertRule
|
||||
}
|
||||
|
||||
@@ -992,15 +992,20 @@ func (alert *SCommonAlert) StartDetachTask(ctx context.Context, userCred mcclien
|
||||
|
||||
func (alert *SCommonAlert) DetachAlertResourceOnDisable(ctx context.Context,
|
||||
userCred mcclient.TokenCredential) (errs []error) {
|
||||
resources, err := GetAlertResourceManager().getResourceFromAlertId(alert.Id)
|
||||
return CommonAlertManager.DetachAlertResourceByAlertId(ctx, userCred, alert.Id)
|
||||
}
|
||||
|
||||
func (manager *SCommonAlertManager) DetachAlertResourceByAlertId(ctx context.Context,
|
||||
userCred mcclient.TokenCredential, alertId string) (errs []error) {
|
||||
resources, err := GetAlertResourceManager().getResourceFromAlertId(alertId)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "getResourceFromAlert error"))
|
||||
return
|
||||
}
|
||||
for _, resource := range resources {
|
||||
err := resource.DetachAlert(ctx, userCred, alert.Id)
|
||||
err := resource.DetachAlert(ctx, userCred, alertId)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrapf(err, "resource:%s DetachAlert:%s err", resource.Id, alert.Id))
|
||||
errs = append(errs, errors.Wrapf(err, "resource:%s DetachAlert:%s err", resource.Id, alertId))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user