mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 10:49:03 +08:00
feat: add runningDiff function (#5667)
This commit is contained in:
parent
06c075466b
commit
4489df6f39
@ -23,6 +23,10 @@ export const metricQueryFunctionOptions: SelectOption<string, string>[] = [
|
|||||||
value: QueryFunctionsTypes.ABSOLUTE,
|
value: QueryFunctionsTypes.ABSOLUTE,
|
||||||
label: 'Absolute',
|
label: 'Absolute',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: QueryFunctionsTypes.RUNNING_DIFF,
|
||||||
|
label: 'Running Diff',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: QueryFunctionsTypes.LOG_2,
|
value: QueryFunctionsTypes.LOG_2,
|
||||||
label: 'Log2',
|
label: 'Log2',
|
||||||
@ -103,6 +107,9 @@ export const queryFunctionsTypesConfig: QueryFunctionConfigType = {
|
|||||||
absolute: {
|
absolute: {
|
||||||
showInput: false,
|
showInput: false,
|
||||||
},
|
},
|
||||||
|
runningDiff: {
|
||||||
|
showInput: false,
|
||||||
|
},
|
||||||
log2: {
|
log2: {
|
||||||
showInput: false,
|
showInput: false,
|
||||||
},
|
},
|
||||||
|
@ -158,6 +158,7 @@ export enum QueryFunctionsTypes {
|
|||||||
CLAMP_MIN = 'clampMin',
|
CLAMP_MIN = 'clampMin',
|
||||||
CLAMP_MAX = 'clampMax',
|
CLAMP_MAX = 'clampMax',
|
||||||
ABSOLUTE = 'absolute',
|
ABSOLUTE = 'absolute',
|
||||||
|
RUNNING_DIFF = 'runningDiff',
|
||||||
LOG_2 = 'log2',
|
LOG_2 = 'log2',
|
||||||
LOG_10 = 'log10',
|
LOG_10 = 'log10',
|
||||||
CUMULATIVE_SUM = 'cumSum',
|
CUMULATIVE_SUM = 'cumSum',
|
||||||
|
@ -70,6 +70,22 @@ func funcAbsolute(result *v3.Result) *v3.Result {
|
|||||||
return 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
|
// funcLog2 returns the log2 of each point
|
||||||
func funcLog2(result *v3.Result) *v3.Result {
|
func funcLog2(result *v3.Result) *v3.Result {
|
||||||
for _, series := range result.Series {
|
for _, series := range result.Series {
|
||||||
@ -256,6 +272,8 @@ func ApplyFunction(fn v3.Function, result *v3.Result) *v3.Result {
|
|||||||
}
|
}
|
||||||
case v3.FunctionNameAbsolute:
|
case v3.FunctionNameAbsolute:
|
||||||
return funcAbsolute(result)
|
return funcAbsolute(result)
|
||||||
|
case v3.FunctionNameRunningDiff:
|
||||||
|
return funcRunningDiff(result)
|
||||||
case v3.FunctionNameLog2:
|
case v3.FunctionNameLog2:
|
||||||
return funcLog2(result)
|
return funcLog2(result)
|
||||||
case v3.FunctionNameLog10:
|
case v3.FunctionNameLog10:
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,10 +13,20 @@ func AdjustedMetricTimeRange(start, end, step int64, mq v3.BuilderQuery) (int64,
|
|||||||
start = start - (start % (step * 1000))
|
start = start - (start % (step * 1000))
|
||||||
// if the query is a rate query, we adjust the start time by one more step
|
// 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
|
// 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()) &&
|
if (mq.AggregateOperator.IsRateOperator() || mq.TimeAggregation.IsRateOperator()) &&
|
||||||
mq.Temporality != v3.Delta {
|
mq.Temporality != v3.Delta {
|
||||||
start -= step * 1000
|
start -= step * 1000
|
||||||
}
|
}
|
||||||
|
if hasRunningDiff {
|
||||||
|
start -= step * 1000
|
||||||
|
}
|
||||||
// align the end to the nearest minute
|
// align the end to the nearest minute
|
||||||
adjustStep := int64(math.Min(float64(step), 60))
|
adjustStep := int64(math.Min(float64(step), 60))
|
||||||
end = end - (end % (adjustStep * 1000))
|
end = end - (end % (adjustStep * 1000))
|
||||||
|
@ -632,6 +632,7 @@ const (
|
|||||||
FunctionNameClampMin FunctionName = "clampMin"
|
FunctionNameClampMin FunctionName = "clampMin"
|
||||||
FunctionNameClampMax FunctionName = "clampMax"
|
FunctionNameClampMax FunctionName = "clampMax"
|
||||||
FunctionNameAbsolute FunctionName = "absolute"
|
FunctionNameAbsolute FunctionName = "absolute"
|
||||||
|
FunctionNameRunningDiff FunctionName = "runningDiff"
|
||||||
FunctionNameLog2 FunctionName = "log2"
|
FunctionNameLog2 FunctionName = "log2"
|
||||||
FunctionNameLog10 FunctionName = "log10"
|
FunctionNameLog10 FunctionName = "log10"
|
||||||
FunctionNameCumSum FunctionName = "cumSum"
|
FunctionNameCumSum FunctionName = "cumSum"
|
||||||
@ -651,6 +652,7 @@ func (f FunctionName) Validate() error {
|
|||||||
FunctionNameClampMin,
|
FunctionNameClampMin,
|
||||||
FunctionNameClampMax,
|
FunctionNameClampMax,
|
||||||
FunctionNameAbsolute,
|
FunctionNameAbsolute,
|
||||||
|
FunctionNameRunningDiff,
|
||||||
FunctionNameLog2,
|
FunctionNameLog2,
|
||||||
FunctionNameLog10,
|
FunctionNameLog10,
|
||||||
FunctionNameCumSum,
|
FunctionNameCumSum,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user