feat: add runningDiff function (#5667)

This commit is contained in:
Srikanth Chekuri 2024-08-09 14:04:29 +05:30 committed by GitHub
parent 06c075466b
commit 4489df6f39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 120 additions and 15 deletions

View File

@ -23,6 +23,10 @@ export const metricQueryFunctionOptions: SelectOption<string, string>[] = [
value: QueryFunctionsTypes.ABSOLUTE,
label: 'Absolute',
},
{
value: QueryFunctionsTypes.RUNNING_DIFF,
label: 'Running Diff',
},
{
value: QueryFunctionsTypes.LOG_2,
label: 'Log2',
@ -103,6 +107,9 @@ export const queryFunctionsTypesConfig: QueryFunctionConfigType = {
absolute: {
showInput: false,
},
runningDiff: {
showInput: false,
},
log2: {
showInput: false,
},

View File

@ -158,6 +158,7 @@ export enum QueryFunctionsTypes {
CLAMP_MIN = 'clampMin',
CLAMP_MAX = 'clampMax',
ABSOLUTE = 'absolute',
RUNNING_DIFF = 'runningDiff',
LOG_2 = 'log2',
LOG_10 = 'log10',
CUMULATIVE_SUM = 'cumSum',

View File

@ -70,6 +70,22 @@ func funcAbsolute(result *v3.Result) *v3.Result {
return result
}
// funcRunningDiff returns the running difference of each point
func funcRunningDiff(result *v3.Result) *v3.Result {
for _, series := range result.Series {
// iterate over the point in reverse order
for idx := len(series.Points) - 1; idx >= 0; idx-- {
if idx > 0 {
series.Points[idx].Value = series.Points[idx].Value - series.Points[idx-1].Value
}
}
// remove the first point
// the timerange is already adjusted in the query range
series.Points = series.Points[1:]
}
return result
}
// funcLog2 returns the log2 of each point
func funcLog2(result *v3.Result) *v3.Result {
for _, series := range result.Series {
@ -256,6 +272,8 @@ func ApplyFunction(fn v3.Function, result *v3.Result) *v3.Result {
}
case v3.FunctionNameAbsolute:
return funcAbsolute(result)
case v3.FunctionNameRunningDiff:
return funcRunningDiff(result)
case v3.FunctionNameLog2:
return funcLog2(result)
case v3.FunctionNameLog10:

View File

@ -602,3 +602,70 @@ func TestFuncMedian5(t *testing.T) {
}
}
}
func TestFuncRunningDiff(t *testing.T) {
type args struct {
result *v3.Result
}
tests := []struct {
name string
args args
want *v3.Result
}{
{
name: "test funcRunningDiff",
args: args{
result: &v3.Result{
Series: []*v3.Series{
{
Points: []v3.Point{{Timestamp: 1, Value: 1}, {Timestamp: 2, Value: 2}, {Timestamp: 3, Value: 3}},
},
},
},
},
want: &v3.Result{
Series: []*v3.Series{
{
Points: []v3.Point{{Timestamp: 2, Value: 1}, {Timestamp: 3, Value: 1}},
},
},
},
},
{
name: "test funcRunningDiff with start number as 8",
args: args{
result: &v3.Result{
Series: []*v3.Series{
{
Points: []v3.Point{{Timestamp: 1, Value: 8}, {Timestamp: 2, Value: 8}, {Timestamp: 3, Value: 8}},
},
},
},
},
want: &v3.Result{
Series: []*v3.Series{
{
Points: []v3.Point{{Timestamp: 2, Value: 0}, {Timestamp: 3, Value: 0}},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := funcRunningDiff(tt.args.result)
for j, series := range got.Series {
if len(series.Points) != len(tt.want.Series[j].Points) {
t.Errorf("funcRunningDiff() = len(series.Points) %v, len(tt.want.Series[j].Points) %v", len(series.Points), len(tt.want.Series[j].Points))
}
for k, point := range series.Points {
if point.Value != tt.want.Series[j].Points[k].Value {
t.Errorf("funcRunningDiff() = %v, want %v", point.Value, tt.want.Series[j].Points[k].Value)
}
}
}
})
}
}

View File

@ -13,10 +13,20 @@ func AdjustedMetricTimeRange(start, end, step int64, mq v3.BuilderQuery) (int64,
start = start - (start % (step * 1000))
// if the query is a rate query, we adjust the start time by one more step
// so that we can calculate the rate for the first data point
hasRunningDiff := false
for _, fn := range mq.Functions {
if fn.Name == v3.FunctionNameRunningDiff {
hasRunningDiff = true
break
}
}
if (mq.AggregateOperator.IsRateOperator() || mq.TimeAggregation.IsRateOperator()) &&
mq.Temporality != v3.Delta {
start -= step * 1000
}
if hasRunningDiff {
start -= step * 1000
}
// align the end to the nearest minute
adjustStep := int64(math.Min(float64(step), 60))
end = end - (end % (adjustStep * 1000))

View File

@ -627,21 +627,22 @@ func GetPercentileFromOperator(operator SpaceAggregation) float64 {
type FunctionName string
const (
FunctionNameCutOffMin FunctionName = "cutOffMin"
FunctionNameCutOffMax FunctionName = "cutOffMax"
FunctionNameClampMin FunctionName = "clampMin"
FunctionNameClampMax FunctionName = "clampMax"
FunctionNameAbsolute FunctionName = "absolute"
FunctionNameLog2 FunctionName = "log2"
FunctionNameLog10 FunctionName = "log10"
FunctionNameCumSum FunctionName = "cumSum"
FunctionNameEWMA3 FunctionName = "ewma3"
FunctionNameEWMA5 FunctionName = "ewma5"
FunctionNameEWMA7 FunctionName = "ewma7"
FunctionNameMedian3 FunctionName = "median3"
FunctionNameMedian5 FunctionName = "median5"
FunctionNameMedian7 FunctionName = "median7"
FunctionNameTimeShift FunctionName = "timeShift"
FunctionNameCutOffMin FunctionName = "cutOffMin"
FunctionNameCutOffMax FunctionName = "cutOffMax"
FunctionNameClampMin FunctionName = "clampMin"
FunctionNameClampMax FunctionName = "clampMax"
FunctionNameAbsolute FunctionName = "absolute"
FunctionNameRunningDiff FunctionName = "runningDiff"
FunctionNameLog2 FunctionName = "log2"
FunctionNameLog10 FunctionName = "log10"
FunctionNameCumSum FunctionName = "cumSum"
FunctionNameEWMA3 FunctionName = "ewma3"
FunctionNameEWMA5 FunctionName = "ewma5"
FunctionNameEWMA7 FunctionName = "ewma7"
FunctionNameMedian3 FunctionName = "median3"
FunctionNameMedian5 FunctionName = "median5"
FunctionNameMedian7 FunctionName = "median7"
FunctionNameTimeShift FunctionName = "timeShift"
)
func (f FunctionName) Validate() error {
@ -651,6 +652,7 @@ func (f FunctionName) Validate() error {
FunctionNameClampMin,
FunctionNameClampMax,
FunctionNameAbsolute,
FunctionNameRunningDiff,
FunctionNameLog2,
FunctionNameLog10,
FunctionNameCumSum,