mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-21 00:25:59 +08:00
feat(monitor): query reduce percentile
1.增加reduce.type == percentile ,进行对应数值处理
This commit is contained in:
@@ -13,8 +13,13 @@ import (
|
||||
type mathReducer struct {
|
||||
// Type is how the timeseries should be reduced.
|
||||
// Ex: avg, sum, max, min, count
|
||||
Type string
|
||||
Opt string
|
||||
Type string
|
||||
Opt string
|
||||
Params []float64
|
||||
}
|
||||
|
||||
func (s *mathReducer) GetParams() []float64 {
|
||||
return s.Params
|
||||
}
|
||||
|
||||
func (s *mathReducer) GetType() string {
|
||||
@@ -169,8 +174,9 @@ func (reducer *mathReducer) mathValue(values []float64) (float64, error) {
|
||||
|
||||
func newMathReducer(cond *monitor.Condition) (*mathReducer, error) {
|
||||
return &mathReducer{
|
||||
Type: cond.Type,
|
||||
Opt: cond.Operators[0],
|
||||
Type: cond.Type,
|
||||
Opt: cond.Operators[0],
|
||||
Params: cond.Params,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -29,13 +29,19 @@ import (
|
||||
type Reducer interface {
|
||||
Reduce(series *tsdb.TimeSeries) (*float64, []string)
|
||||
GetType() string
|
||||
GetParams() []float64
|
||||
}
|
||||
|
||||
// queryReducer reduces an timeseries to a float
|
||||
type queryReducer struct {
|
||||
// Type is how the timeseries should be reduced.
|
||||
// Ex: avg, sum, max, min, count
|
||||
Type string
|
||||
Type string
|
||||
Params []float64
|
||||
}
|
||||
|
||||
func (s *queryReducer) GetParams() []float64 {
|
||||
return s.Params
|
||||
}
|
||||
|
||||
func (s *queryReducer) GetType() string {
|
||||
@@ -134,7 +140,7 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) {
|
||||
if value > 0 {
|
||||
allNull = false
|
||||
}
|
||||
case "P95":
|
||||
case "percentile":
|
||||
var values []float64
|
||||
for _, v := range series.Points {
|
||||
if v.IsValid() {
|
||||
@@ -142,10 +148,14 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) {
|
||||
values = append(values, v.Value())
|
||||
}
|
||||
}
|
||||
pNum := float64(95)
|
||||
if len(s.Params) != 0 {
|
||||
pNum = s.Params[0]
|
||||
}
|
||||
if len(values) >= 1 {
|
||||
sort.Float64s(values)
|
||||
length := len(values)
|
||||
index := math.Floor(float64(length) * 0.95)
|
||||
index := math.Floor(float64(length) * pNum / float64(100))
|
||||
value = values[int64(index)]
|
||||
}
|
||||
}
|
||||
@@ -157,8 +167,18 @@ func (s *queryReducer) Reduce(series *tsdb.TimeSeries) (*float64, []string) {
|
||||
return &value, valArr
|
||||
}
|
||||
|
||||
func newSimpleReducer(t string) *queryReducer {
|
||||
return &queryReducer{Type: t}
|
||||
func newSimpleReducer(cond *monitor.Condition) *queryReducer {
|
||||
return &queryReducer{
|
||||
Type: cond.Type,
|
||||
Params: cond.Params,
|
||||
}
|
||||
}
|
||||
|
||||
func newSimpleReducerByType(typ string) *queryReducer {
|
||||
return &queryReducer{
|
||||
Type: typ,
|
||||
Params: []float64{},
|
||||
}
|
||||
}
|
||||
|
||||
func calculateDiff(series *tsdb.TimeSeries, allNull bool, value float64, fn func(float64, float64) float64) (bool, float64) {
|
||||
@@ -199,7 +219,7 @@ var percentDiff = func(newest, oldest float64) float64 {
|
||||
|
||||
func NewAlertReducer(cond *monitor.Condition) (Reducer, error) {
|
||||
if len(cond.Operators) == 0 {
|
||||
return newSimpleReducer(cond.Type), nil
|
||||
return newSimpleReducer(cond), nil
|
||||
}
|
||||
|
||||
if utils.IsInStringArray(cond.Operators[0], validators.CommonAlertReducerFieldOpts) {
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("median should ignore null values", func() {
|
||||
reducer := newSimpleReducer("median")
|
||||
reducer := newSimpleReducerByType("median")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
|
||||
Convey("count_non_null", func() {
|
||||
Convey("with null values and real values", func() {
|
||||
reducer := newSimpleReducer("count_non_null")
|
||||
reducer := newSimpleReducerByType("count_non_null")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("with null values", func() {
|
||||
reducer := newSimpleReducer("count_non_null")
|
||||
reducer := newSimpleReducerByType("count_non_null")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
@@ -118,7 +118,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("avg of number values and null values should ignore nulls", func() {
|
||||
reduer := newSimpleReducer("avg")
|
||||
reduer := newSimpleReducerByType("avg")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("diff with only nulls", func() {
|
||||
reducer := newSimpleReducer("diff")
|
||||
reducer := newSimpleReducerByType("diff")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("percent_diff with only nulls", func() {
|
||||
reducer := newSimpleReducer("percent_diff")
|
||||
reducer := newSimpleReducerByType("percent_diff")
|
||||
series := &tsdb.TimeSeries{
|
||||
Name: "test time serie",
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func TestSimpleReducer(t *testing.T) {
|
||||
}
|
||||
|
||||
func testReducer(reducerType string, datapoints ...float64) float64 {
|
||||
reducer := newSimpleReducer(reducerType)
|
||||
reducer := newSimpleReducerByType(reducerType)
|
||||
serires := &tsdb.TimeSeries{
|
||||
Name: "test time series",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user