chore: add missing shiftby in alert rule (#6239)

This commit is contained in:
Srikanth Chekuri 2024-10-24 02:20:32 +05:30 committed by GitHub
parent 00421235b0
commit 6c7167a224
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 156 additions and 20 deletions

View File

@ -1142,25 +1142,7 @@ func ParseQueryRangeParams(r *http.Request) (*v3.QueryRangeParamsV3, *model.ApiE
}
}
// Remove the time shift function from the list of functions and set the shift by value
var timeShiftBy int64
if len(query.Functions) > 0 {
for idx := range query.Functions {
function := &query.Functions[idx]
if function.Name == v3.FunctionNameTimeShift {
// move the function to the beginning of the list
// so any other function can use the shifted time
var fns []v3.Function
fns = append(fns, *function)
fns = append(fns, query.Functions[:idx]...)
fns = append(fns, query.Functions[idx+1:]...)
query.Functions = fns
timeShiftBy = int64(function.Args[0].(float64))
break
}
}
}
query.ShiftBy = timeShiftBy
query.SetShiftByFromFunc()
if query.Filters == nil || len(query.Filters.Items) == 0 {
continue

View File

@ -297,6 +297,8 @@ func TestParseQueryRangeParamsCompositeQuery(t *testing.T) {
compositeQuery v3.CompositeQuery
expectErr bool
errMsg string
hasShiftBy bool
shiftBy int64
}{
{
desc: "no query in request",
@ -496,6 +498,56 @@ func TestParseQueryRangeParamsCompositeQuery(t *testing.T) {
expectErr: true,
errMsg: "builder query A is invalid: group by is invalid",
},
{
desc: "builder query with shift by",
compositeQuery: v3.CompositeQuery{
PanelType: v3.PanelTypeGraph,
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
QueryName: "A",
DataSource: "logs",
AggregateOperator: "sum",
AggregateAttribute: v3.AttributeKey{Key: "attribute"},
GroupBy: []v3.AttributeKey{{Key: "group_key"}},
Expression: "A",
Functions: []v3.Function{
{
Name: v3.FunctionNameTimeShift,
Args: []interface{}{float64(10)},
},
},
},
},
},
hasShiftBy: true,
shiftBy: 10,
},
{
desc: "builder query with shift by as string",
compositeQuery: v3.CompositeQuery{
PanelType: v3.PanelTypeGraph,
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
QueryName: "A",
DataSource: "logs",
AggregateOperator: "sum",
AggregateAttribute: v3.AttributeKey{Key: "attribute"},
GroupBy: []v3.AttributeKey{{Key: "group_key"}},
Expression: "A",
Functions: []v3.Function{
{
Name: v3.FunctionNameTimeShift,
Args: []interface{}{"3600"},
},
},
},
},
},
hasShiftBy: true,
shiftBy: 3600,
},
}
for _, tc := range reqCases {
@ -514,13 +566,16 @@ func TestParseQueryRangeParamsCompositeQuery(t *testing.T) {
require.NoError(t, err)
req := httptest.NewRequest(http.MethodPost, "/api/v3/query_range", body)
_, apiErr := ParseQueryRangeParams(req)
params, apiErr := ParseQueryRangeParams(req)
if tc.expectErr {
require.Error(t, apiErr)
require.Contains(t, apiErr.Error(), tc.errMsg)
} else {
require.Nil(t, apiErr)
}
if tc.hasShiftBy {
require.Equal(t, tc.shiftBy, params.CompositeQuery.BuilderQueries["A"].ShiftBy)
}
})
}
}

View File

@ -11,6 +11,7 @@ import (
"github.com/google/uuid"
"github.com/pkg/errors"
"go.uber.org/zap"
)
type DataSource string
@ -789,6 +790,38 @@ type BuilderQuery struct {
QueriesUsedInFormula []string
}
func (b *BuilderQuery) SetShiftByFromFunc() {
// Remove the time shift function from the list of functions and set the shift by value
var timeShiftBy int64
if len(b.Functions) > 0 {
for idx := range b.Functions {
function := &b.Functions[idx]
if function.Name == FunctionNameTimeShift {
// move the function to the beginning of the list
// so any other function can use the shifted time
var fns []Function
fns = append(fns, *function)
fns = append(fns, b.Functions[:idx]...)
fns = append(fns, b.Functions[idx+1:]...)
b.Functions = fns
if len(function.Args) > 0 {
if shift, ok := function.Args[0].(float64); ok {
timeShiftBy = int64(shift)
} else if shift, ok := function.Args[0].(string); ok {
shiftBy, err := strconv.ParseFloat(shift, 64)
if err != nil {
zap.L().Error("failed to parse time shift by", zap.String("shift", shift), zap.Error(err))
}
timeShiftBy = int64(shiftBy)
}
}
break
}
}
}
b.ShiftBy = timeShiftBy
}
func (b *BuilderQuery) Clone() *BuilderQuery {
if b == nil {
return nil

View File

@ -152,6 +152,9 @@ func (r *ThresholdRule) prepareQueryRange(ts time.Time) (*v3.QueryRangeParamsV3,
if minStep := common.MinAllowedStepInterval(start, end); q.StepInterval < minStep {
q.StepInterval = minStep
}
q.SetShiftByFromFunc()
if q.DataSource == v3.DataSourceMetrics && constants.UseMetricsPreAggregation() {
// if the time range is greater than 1 day, and less than 1 week set the step interval to be multiple of 5 minutes
// if the time range is greater than 1 week, set the step interval to be multiple of 30 mins

View File

@ -1602,3 +1602,66 @@ func TestThresholdRuleLogsLink(t *testing.T) {
}
}
}
func TestThresholdRuleShiftBy(t *testing.T) {
target := float64(10)
postableRule := PostableRule{
AlertName: "Logs link test",
AlertType: AlertTypeLogs,
RuleType: RuleTypeThreshold,
EvalWindow: Duration(5 * time.Minute),
Frequency: Duration(1 * time.Minute),
RuleCondition: &RuleCondition{
CompositeQuery: &v3.CompositeQuery{
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
QueryName: "A",
StepInterval: 60,
AggregateAttribute: v3.AttributeKey{
Key: "component",
},
AggregateOperator: v3.AggregateOperatorCountDistinct,
DataSource: v3.DataSourceLogs,
Expression: "A",
Filters: &v3.FilterSet{
Operator: "AND",
Items: []v3.FilterItem{
{
Key: v3.AttributeKey{Key: "k8s.container.name", IsColumn: false, Type: v3.AttributeKeyTypeTag, DataType: v3.AttributeKeyDataTypeString},
Value: "testcontainer",
Operator: v3.FilterOperatorEqual,
},
},
},
Functions: []v3.Function{
{
Name: v3.FunctionNameTimeShift,
Args: []interface{}{float64(10)},
},
},
},
},
},
Target: &target,
CompareOp: ValueAboveOrEq,
},
}
rule, err := NewThresholdRule("69", &postableRule, nil, nil, true)
if err != nil {
assert.NoError(t, err)
}
rule.TemporalityMap = map[string]map[v3.Temporality]bool{
"signoz_calls_total": {
v3.Delta: true,
},
}
params, err := rule.prepareQueryRange(time.Now())
if err != nil {
assert.NoError(t, err)
}
assert.Equal(t, int64(10), params.CompositeQuery.BuilderQueries["A"].ShiftBy)
}