Merge pull request #7838 from zhaoxiangchun/bugfix/zxc-monitor-alert

commonalert bugfix:
This commit is contained in:
yunion-ci-robot
2020-09-10 09:46:54 +08:00
committed by GitHub
8 changed files with 94 additions and 62 deletions
+8 -6
View File
@@ -165,12 +165,14 @@ type ResultLogEntry struct {
// EvalMatch represents the series violating the threshold.
type EvalMatch struct {
Condition string `json:"condition"`
Value *float64 `json:"value"`
ValueStr string `json:"value_str"`
Metric string `json:"metric"`
Tags map[string]string `json:"tags"`
Unit string `json:"unit"`
Condition string `json:"condition"`
Value *float64 `json:"value"`
ValueStr string `json:"value_str"`
Metric string `json:"metric"`
MeasurementDesc string `json:"measurement_desc"`
FieldDesc string `json:"field_desc"`
Tags map[string]string `json:"tags"`
Unit string `json:"unit"`
}
type AlertTestRunOutput struct {
+2
View File
@@ -21,6 +21,8 @@ const (
//metirc fields 之间的运算
CommonAlertFieldOpt_Division = "/"
DEFAULT_SEND_NOTIFY_CHANNEL = "users"
)
var CommonAlertLevels = []string{"normal", "important", "fatal"}
+8 -8
View File
@@ -143,13 +143,12 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.Conditio
//the relation metas with series is 1 to more
meta = &metas[0]
}
if evalMatch {
evalMatch, err := c.NewEvalMatch(context, *series, meta, reducedValue)
if err != nil {
return nil, errors.Wrap(err, "NewEvalMatch error")
}
matches = append(matches, evalMatch)
match, err := c.NewEvalMatch(context, *series, meta, reducedValue)
if err != nil {
return nil, errors.Wrap(err, "NewEvalMatch error")
}
matches = append(matches, match)
}
// handle no series special case
@@ -181,8 +180,7 @@ func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.Conditio
}
func (c *QueryCondition) NewEvalMatch(context *alerting.EvalContext, series tsdb.TimeSeries,
meta *tsdb.QueryResultMeta, value *float64) (*monitor.EvalMatch,
error) {
meta *tsdb.QueryResultMeta, value *float64) (*monitor.EvalMatch, error) {
evalMatch := new(monitor.EvalMatch)
alert, err := models.CommonAlertManager.GetAlert(context.Rule.Id)
if err != nil {
@@ -208,6 +206,8 @@ func (c *QueryCondition) NewEvalMatch(context *alerting.EvalContext, series tsdb
evalMatch.Unit = alertDetails.FieldDescription.Unit
evalMatch.Value = value
evalMatch.ValueStr = c.RationalizeValueFromUnit(*value, alertDetails.FieldDescription.Unit)
evalMatch.MeasurementDesc = alertDetails.MeasurementDisplayName
evalMatch.FieldDesc = alertDetails.FieldDescription.DisplayName
return evalMatch, nil
}
+57 -29
View File
@@ -115,10 +115,6 @@ func GetNotifyTemplateConfig(ctx *alerting.EvalContext) monitor.NotificationTemp
// Notify sends the alert notification.
func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONObject) error {
//onecloud 默认向webconsole发送消息
//if err := WebConsoleNotify(ctx, oc.Setting.UserIds); err != nil {
// log.Errorf("failed to send webconsole %s: %v", oc.GetNotifierId(), err)
//}
log.Infof("Sending alert notification %s to onecloud", ctx.GetRuleTitle())
config := GetNotifyTemplateConfig(ctx)
contentConfig := oc.buildContent(config)
@@ -142,35 +138,67 @@ func (oc *OneCloudNotifier) Notify(ctx *alerting.EvalContext, _ jsonutils.JSONOb
Priority: notify.TNotifyPriority(config.Priority),
Msg: content,
}
//系统报警UserIds 为空
if len(oc.Setting.UserIds) == 0 {
notifyclient.SystemNotify(notify.TNotifyPriority(msg.Priority), msg.Topic, jsonutils.NewString(content))
return nil
}
return notify.Notifications.Send(oc.session, msg)
factory := new(sendBodyFactory)
sendImp := factory.newSendnotify(oc, msg)
return sendImp.send()
}
func (oc *OneCloudNotifier) buildContent(config monitor.NotificationTemplateConfig) *templates.TemplateConfig {
return templates.NewTemplateConfig(config)
}
func WebConsoleNotify(ctx *alerting.EvalContext, ids []string) error {
log.Infof("Sending alert notification %s to webconsole", ctx.GetRuleTitle())
config := GetNotifyTemplateConfig(ctx)
contentConfig := templates.NewTemplateConfig(config)
content, err := contentConfig.GenerateMarkdown()
if err != nil {
return errors.Wrap(err, "build content")
}
msg := notify.SNotifyMessage{
Uid: ids,
ContactType: notify.NotifyByWebConsole,
Topic: config.Title,
Priority: notify.TNotifyPriority(config.Priority),
Msg: content,
Broadcast: true,
}
session := auth.GetAdminSession(ctx.Ctx, "", "")
return notify.Notifications.Send(session, msg)
type sendBodyFactory struct {
}
func (f *sendBodyFactory) newSendnotify(notifier *OneCloudNotifier, message notify.SNotifyMessage) Isendnotify {
def := new(sendnotifyBase)
def.OneCloudNotifier = notifier
def.msg = message
if len(notifier.Setting.UserIds) == 0 {
sys := new(sendSysImpl)
sys.sendnotifyBase = def
return sys
}
switch notifier.Setting.Channel {
case monitor.DEFAULT_SEND_NOTIFY_CHANNEL:
user := new(sendUserImpl)
user.sendnotifyBase = def
return user
default:
return def
}
}
type Isendnotify interface {
send() error
}
type sendnotifyBase struct {
*OneCloudNotifier
msg notify.SNotifyMessage
}
func (s *sendnotifyBase) send() error {
return notify.Notifications.Send(s.session, s.msg)
}
type sendUserImpl struct {
*sendnotifyBase
}
func (s *sendUserImpl) send() error {
return notifyclient.NotifyAllWithoutRobot(s.Setting.UserIds, false, notify.TNotifyPriority(s.msg.Priority), s.msg.Topic,
jsonutils.NewString(s.msg.Msg))
}
type sendSysImpl struct {
*sendnotifyBase
}
func (s *sendSysImpl) send() error {
notifyclient.SystemNotify(notify.TNotifyPriority(s.msg.Priority), s.msg.Topic,
jsonutils.NewString(s.msg.Msg))
return nil
}
+11
View File
@@ -80,6 +80,11 @@ func (man *SCommonAlertManager) ValidateCreateData(
if data.Level == "" {
return data, httperrors.NewInputParameterError("level is empty")
}
if len(data.Channel) == 0 {
data.Channel = []string{monitor.DEFAULT_SEND_NOTIFY_CHANNEL}
} else {
data.Channel = append(data.Channel, monitor.DEFAULT_SEND_NOTIFY_CHANNEL)
}
if !utils.IsInStringArray(data.Level, monitor.CommonAlertLevels) {
return data, httperrors.NewInputParameterError("Invalid level format: %s", data.Level)
}
@@ -594,6 +599,12 @@ func (alert *SCommonAlert) ValidateUpdateData(
data.Set("frequency", jsonutils.NewInt(freqSpec))
}
}
if channel, _ := data.GetArray("channel"); len(channel) > 0 {
channels := jsonutils.NewArray()
channels.Add(channel...)
channels.Add(jsonutils.NewString(monitor.DEFAULT_SEND_NOTIFY_CHANNEL))
data.Set("channel", channels)
}
if metric_query, _ := data.GetArray("metric_query"); len(metric_query) > 0 {
for i, _ := range metric_query {
query := new(monitor.CommonAlertQuery)
+1 -8
View File
@@ -433,7 +433,6 @@ func (self *SDataSourceManager) getFromAndToFromParam(query jsonutils.JSONObject
func (self *SDataSourceManager) getFilterMeasurementsAsyn(from, to string,
measurements []monitor.InfluxMeasurement, db influxdb.SInfluxdb, tagFilter string) ([]monitor.InfluxMeasurement, error) {
log.Errorln("start asynchronous task")
filterMeasurements := make([]monitor.InfluxMeasurement, 0)
queryChan := new(influxdbQueryChan)
queryChan.queryRtnChan = make(chan monitor.InfluxMeasurement, len(measurements))
@@ -647,11 +646,7 @@ func (self *SDataSourceManager) filterTagValue(measurement monitor.InfluxMeasure
close(tagValChan2.rtnChan)
return nil
})
err := tagValGroup2.Wait()
if err == nil {
log.Errorln("filterTagValue end ")
}
return err
return tagValGroup2.Wait()
}
func tagValUnion(measurement *monitor.InfluxMeasurement, rtn map[string][]string) {
@@ -751,7 +746,6 @@ func getAttributesOnMeasurement(database, tp string, output *monitor.InfluxMeasu
if err != nil {
return errors.Wrap(err, "SHOW MEASUREMENTS")
}
log.Errorf("SHOW %s KEYS ON %s FROM %s", tp, database, output.Measurement)
if len(dbRtn) == 0 || len(dbRtn[0]) == 0 {
return nil
}
@@ -827,7 +821,6 @@ func (self *SDataSourceManager) getFilterMeasurementTagValue(tagValueChan *influ
}
buffer.WriteString(fmt.Sprintf(` GROUP BY %q`, tagKey))
rtn, err := db.Query(buffer.String())
log.Errorf("sql:", buffer.String())
if err != nil {
return errors.Wrap(err, "getFilterMeasurementTagValue query error")
}
+6 -6
View File
@@ -462,9 +462,7 @@ func (manager *SMetricMeasurementManager) initMetrics(ctx context.Context, metri
func (manager *SMetricMeasurementManager) initMeasurementAndFieldInfo(createInput monitor.MetricCreateInput) error {
userCred := auth.AdminCredential()
listInput := new(monitor.MetricListInput)
listInput.Measurement.Names = []string{createInput.Measurement.Name}
measurements, err := manager.getMeasurementByName(userCred, *listInput)
measurements, err := manager.getMeasurementByName(createInput.Measurement.Name)
if err != nil {
return errors.Wrap(err, "join query get measurement error")
}
@@ -486,10 +484,12 @@ func (manager *SMetricMeasurementManager) initMeasurementAndFieldInfo(createInpu
return measurements[0].insertOrUpdateMetric(userCred, createInput, updateFields)
}
func (manager *SMetricMeasurementManager) getMeasurementByName(userCred mcclient.TokenCredential,
listInput monitor.MetricListInput) ([]SMetricMeasurement, error) {
func (manager *SMetricMeasurementManager) getMeasurementByName(names ...string) ([]SMetricMeasurement, error) {
userCred := auth.AdminCredential()
listInput := new(monitor.MetricListInput)
listInput.Measurement.Names = names
query, err := MetricMeasurementManager.ListItemFilter(context.Background(), MetricMeasurementManager.Query(), userCred,
listInput)
*listInput)
if err != nil {
return nil, err
}
+1 -5
View File
@@ -13,7 +13,6 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
mq "yunion.io/x/onecloud/pkg/monitor/metricquery"
"yunion.io/x/onecloud/pkg/monitor/tsdb"
"yunion.io/x/onecloud/pkg/monitor/validators"
@@ -338,10 +337,7 @@ func setSerieRowName(series *tsdb.TimeSeriesSlice, groupTag []string) {
}
measurement := strings.Split(serie.Name, ".")[0]
//sep measurement set RowName by spe param
userCred := auth.AdminCredential()
listInput := new(monitor.MetricListInput)
listInput.Measurement.Names = []string{measurement}
measurements, _ := MetricMeasurementManager.getMeasurementByName(userCred, *listInput)
measurements, _ := MetricMeasurementManager.getMeasurementByName(measurement)
if len(measurements) != 0 {
if key, ok := monitor.MEASUREMENT_TAG_KEYWORD[measurements[0].ResType]; ok {
serie.RawName = fmt.Sprintf("%d: %s", index, serie.Tags[key])