From bfaca8823d723afc09db960eac27afeea12fcd4a Mon Sep 17 00:00:00 2001 From: liugq Date: Thu, 23 Jun 2022 12:22:04 +0800 Subject: [PATCH] add template func add,sub, div, mul --- model/alerting/metric.go | 1 + plugin/api/alerting/rule.go | 2 +- service/alerting/funcs/function.go | 4 ++ service/alerting/funcs/numberic.go | 96 +++++++++++++++++++++++++++++- 4 files changed, 101 insertions(+), 2 deletions(-) diff --git a/model/alerting/metric.go b/model/alerting/metric.go index 5336d628..80f082ab 100644 --- a/model/alerting/metric.go +++ b/model/alerting/metric.go @@ -16,6 +16,7 @@ type Metric struct { Expression string `json:"expression" elastic_mapping:"expression:{type:keyword,copy_to:search_text}"` //告警表达式,自动生成 eg: avg(cpu) > 80 Title string `json:"title"` //text template Message string `json:"message"` // text template + FormatType string `json:"format_type,omitempty"` } func (m *Metric) GenerateExpression() (string, error){ if len(m.Items) == 1 { diff --git a/plugin/api/alerting/rule.go b/plugin/api/alerting/rule.go index c08ab234..057dd414 100644 --- a/plugin/api/alerting/rule.go +++ b/plugin/api/alerting/rule.go @@ -794,7 +794,7 @@ func getRuleMetricData( rule *alerting.Rule, filterParam *alerting.FilterParam) Label: label, Group: rule.ID, TickFormat: "0,0.[00]", - FormatType: "num", + FormatType: rule.Metrics.FormatType, }, }) } diff --git a/service/alerting/funcs/function.go b/service/alerting/funcs/function.go index f6fcaba6..558a1aa3 100644 --- a/service/alerting/funcs/function.go +++ b/service/alerting/funcs/function.go @@ -27,4 +27,8 @@ var genericMap = map[string]interface{}{ "datetime_in_zone": datetimeInZone, "to_upper": strings.ToUpper, "to_lower": strings.ToLower, + "add": add, + "sub": sub, + "div": div, + "mul": mul, } diff --git a/service/alerting/funcs/numberic.go b/service/alerting/funcs/numberic.go index daf7a74b..8f9be6f9 100644 --- a/service/alerting/funcs/numberic.go +++ b/service/alerting/funcs/numberic.go @@ -4,8 +4,102 @@ package funcs -import "infini.sh/framework/core/util" +import ( + "encoding/json" + "fmt" + "infini.sh/framework/core/util" + "reflect" + "strconv" +) func toFixed(precision int, num float64) float64{ return util.ToFixed(num, precision) } +func add(a, b interface{}) float64{ + av := ToFloat64(a) + bv := ToFloat64(b) + return av + bv +} +func sub(a, b interface{}) float64 { return ToFloat64(a) - ToFloat64(b) } +func div(a, b interface{}) float64 { return ToFloat64(a) / ToFloat64(b) } +func mul(a interface{}, v ...interface{}) float64 { + val := ToFloat64(a) + for _, b := range v { + val = val * ToFloat64(b) + } + return val +} + +// ToFloat64 casts an interface to a float64 type. +func ToFloat64(i interface{}) float64 { + v, _ := ToFloat64E(i) + return v +} + +func indirect(a interface{}) interface{} { + if a == nil { + return nil + } + if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr { + // Avoid creating a reflect.Value if it's not a pointer. + return a + } + v := reflect.ValueOf(a) + for v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + return v.Interface() +} + +// ToFloat64E casts an interface to a float64 type. +func ToFloat64E(i interface{}) (float64, error) { + i = indirect(i) + + switch s := i.(type) { + case float64: + return s, nil + case float32: + return float64(s), nil + case int: + return float64(s), nil + case int64: + return float64(s), nil + case int32: + return float64(s), nil + case int16: + return float64(s), nil + case int8: + return float64(s), nil + case uint: + return float64(s), nil + case uint64: + return float64(s), nil + case uint32: + return float64(s), nil + case uint16: + return float64(s), nil + case uint8: + return float64(s), nil + case string: + v, err := strconv.ParseFloat(s, 64) + if err == nil { + return v, nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) + case json.Number: + v, err := s.Float64() + if err == nil { + return v, nil + } + return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) + case bool: + if s { + return 1, nil + } + return 0, nil + case nil: + return 0, nil + default: + return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i) + } +} \ No newline at end of file