mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(monitor): modify notify alertInfo and alertOk detach resource
1.修复报警信息中>等被转义的问题 2.针对:host_raid.adapter和smart_device.exit_status 只能出现alerting和nodata 两种报警状态。在queryCondition的查询逻辑下,nodata情况也进行detach操作 3.修复报警记录中报警策略翻译异常的问题
This commit is contained in:
@@ -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