// Copyright 2019 Yunion // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package monitor import ( "strings" ) const ( NodeAlertTypeGuest = "guest" NodeAlertTypeHost = "host" ) type ResourceAlertV1CreateInput struct { AlertCreateInput // 查询指标周期 Period string `json:"period"` // 每隔多久查询一次 Window string `json:"window"` // 比较运算符, 比如: >, <, >=, <= Comparator string `json:"comparator"` // 报警阀值 Threshold float64 `json:"threshold"` // 通知方式, 比如: email, mobile Channel string `json:"channel"` // 通知接受者 Recipients string `json:"recipients"` } type NodeAlertCreateInput struct { ResourceAlertV1CreateInput // 监控指标名称 Metric string `json:"metric"` // 监控资源类型, 比如: guest, host Type string `json:"type"` // 监控资源名称 NodeName string `json:"node_name"` // 监控资源 Id NodeId string `json:"node_id"` // CommonAlertCreateInput injected by server and do not pass it through API CommonAlertCreateInput *CommonAlertCreateInput `json:"common_alert_create_input,omitempty"` } func (input NodeAlertCreateInput) ToCommonAlertCreateInput( name string, field string, measurement string, db string) CommonAlertCreateInput { ret := CommonAlertCreateInput{ AlertCreateInput: AlertCreateInput{ Name: name, Level: input.Level, }, CommonAlertCreateBaseInput: CommonAlertCreateBaseInput{ Channel: strings.Split(input.Channel, ","), Recipients: strings.Split(input.Recipients, ","), AlertType: CommonAlertNomalAlertType, }, CommonMetricInputQuery: CommonMetricInputQuery{ MetricQuery: []*CommonAlertQuery{ { AlertQuery: &AlertQuery{ Model: input.GetQuery(field, measurement, db), From: input.Period, To: "now", }, Comparator: input.Comparator, Threshold: input.Threshold, ConditionType: "query", Reduce: "avg", }, }, }, Period: input.Window, } ret.UsedBy = AlertNotificationUsedByNodeAlert return ret } // func (input NodeAlertCreateInput) ToAlertCreateInput( // name string, // field string, // measurement string, // db string) AlertCreateInput { // freq, _ := time.ParseDuration(input.Window) // ret := AlertCreateInput{ // Name: name, // Frequency: int64(freq / time.Second), // Level: input.Level, // Settings: AlertSetting{ // Conditions: []AlertCondition{ // { // Type: "query", // Operator: "and", // Query: AlertQuery{ // Model: input.GetQuery(field, measurement, db), // From: input.Period, // To: "now", // }, // Evaluator: input.GetEvaluator(), // Reducer: Condition{ // Type: "avg", // }, // }, // }, // }, // } // return ret // } func (input NodeAlertCreateInput) GetQuery(field, measurement, db string) MetricQuery { return GetNodeAlertQuery(input.Type, field, measurement, db, input.NodeId) } func GetNodeAlertQuery(typ, field, measurement, db, nodeId string) MetricQuery { var idField string switch typ { case NodeAlertTypeGuest: idField = "vm_id" case NodeAlertTypeHost: idField = "host_id" } sels := make([]MetricQuerySelect, 0) sels = append(sels, NewMetricQuerySelect(MetricQueryPart{Type: "field", Params: []string{field}})) return MetricQuery{ Selects: sels, Tags: []MetricQueryTag{ { Key: idField, Operator: "=", Value: nodeId, }, }, GroupBy: []MetricQueryPart{ { Type: "field", Params: []string{"*"}, }, }, Measurement: measurement, Database: db, } } func (input NodeAlertCreateInput) GetEvaluator() Condition { return GetNodeAlertEvaluator(input.Comparator, input.Threshold) } const ( ConditionGreaterThan = "gt" ConditionLessThan = "lt" ) func GetNodeAlertEvaluator(comparator string, threshold float64) Condition { typ := EvaluatorType(ConditionGreaterThan) switch comparator { case ">=", ">": typ = EvaluatorType(ConditionGreaterThan) case "<=", "<": typ = EvaluatorType(ConditionLessThan) } return Condition{ Type: string(typ), Params: []float64{threshold}, } } type V1AlertListInput struct { AlertListInput } type NodeAlertListInput struct { AlertListInput // 监控指标名称 Metric string `json:"metric"` // 监控资源类型, 比如: guest, host Type string `json:"type"` // 监控资源名称 NodeName string `json:"node_name"` // 监控资源 Id NodeId string `json:"node_id"` } func (o NodeAlertListInput) ToCommonAlertListInput() CommonAlertListInput { return CommonAlertListInput{ AlertListInput: o.AlertListInput, Metric: o.Metric, } } type AlertV1Details struct { AlertDetails Name string `json:"name"` Period string `json:"period"` Window string `json:"window"` Comparator string `json:"comparator"` Threshold float64 `json:"threshold"` Recipients string `json:"recipients"` Level string `json:"level"` Channel string `json:"channel"` DB string `json:"db"` Measurement string `json:"measurement"` Field string `json:"field"` NotifierId string `json:"notifier_id"` Status string `json:"status"` } type NodeAlertDetails struct { AlertV1Details Type string `json:"type"` Metric string `json:"metric"` NodeId string `json:"node_id"` NodeName string `json:"node_name"` } type NodeAlertUpdateInput struct { AlertUpdateInput // 监控指标名称 Metric *string `json:"metric"` // 监控资源类型, 比如: guest, host Type *string `json:"type"` // 监控资源名称 NodeName *string `json:"node_name"` // 监控资源 Id NodeId *string `json:"node_id"` // 查询指标周期 Period *string `json:"period"` // 每隔多久查询一次 Window *string `json:"window"` // 比较运算符, 比如: >, <, >=, <= Comparator *string `json:"comparator"` // 报警阀值 Threshold *float64 `json:"threshold"` // 报警级别 Level *string `json:"level"` // 通知方式, 比如: email, mobile Channel *string `json:"channel"` // 通知接受者 Recipients *string `json:"recipients"` } type V1AlertUpdateInput struct { AlertUpdateInput }