diff --git a/pkg/query-service/app/logparsingpipeline/pipelineBuilder_test.go b/pkg/query-service/app/logparsingpipeline/pipelineBuilder_test.go index e696d24cc3..c81172dbbc 100644 --- a/pkg/query-service/app/logparsingpipeline/pipelineBuilder_test.go +++ b/pkg/query-service/app/logparsingpipeline/pipelineBuilder_test.go @@ -420,3 +420,65 @@ func TestResourceFiltersWork(t *testing.T) { require.Equal(result[0].Attributes_string["test"], "test-value") } + +func TestPipelineFilterWithStringOpsShouldNotSpamWarningsIfAttributeIsMissing(t *testing.T) { + require := require.New(t) + + for _, operator := range []v3.FilterOperator{ + v3.FilterOperatorContains, + v3.FilterOperatorNotContains, + v3.FilterOperatorRegex, + v3.FilterOperatorNotRegex, + } { + testPipeline := Pipeline{ + OrderId: 1, + Name: "pipeline1", + Alias: "pipeline1", + Enabled: true, + Filter: &v3.FilterSet{ + Operator: "AND", + Items: []v3.FilterItem{ + { + Key: v3.AttributeKey{ + Key: "service", + DataType: v3.AttributeKeyDataTypeString, + Type: v3.AttributeKeyTypeResource, + }, + Operator: operator, + Value: "nginx", + }, + }, + }, + Config: []PipelineOperator{ + { + ID: "add", + Type: "add", + Enabled: true, + Name: "add", + Field: "attributes.test", + Value: "test-value", + }, + }, + } + + testLog := model.SignozLog{ + Timestamp: uint64(time.Now().UnixNano()), + Body: "test log", + Attributes_string: map[string]string{}, + Resources_string: map[string]string{}, + SeverityText: entry.Info.String(), + SeverityNumber: uint8(entry.Info), + SpanID: "", + TraceID: "", + } + + result, collectorWarnAndErrorLogs, err := SimulatePipelinesProcessing( + context.Background(), + []Pipeline{testPipeline}, + []model.SignozLog{testLog}, + ) + require.Nil(err) + require.Equal(0, len(collectorWarnAndErrorLogs), strings.Join(collectorWarnAndErrorLogs, "\n")) + require.Equal(1, len(result)) + } +} diff --git a/pkg/query-service/queryBuilderToExpr/queryBuilderToExpr.go b/pkg/query-service/queryBuilderToExpr/queryBuilderToExpr.go index ed68feb071..45bcc69405 100644 --- a/pkg/query-service/queryBuilderToExpr/queryBuilderToExpr.go +++ b/pkg/query-service/queryBuilderToExpr/queryBuilderToExpr.go @@ -64,6 +64,11 @@ func Parse(filters *v3.FilterSet) (string, error) { filter = fmt.Sprintf("%s %s %s", exprFormattedValue(v.Key.Key), logOperatorsToExpr[v.Operator], getTypeName(v.Key.Type)) default: filter = fmt.Sprintf("%s %s %s", name, logOperatorsToExpr[v.Operator], exprFormattedValue(v.Value)) + + // Avoid running operators on nil values + if v.Operator != v3.FilterOperatorEqual && v.Operator != v3.FilterOperatorNotEqual { + filter = fmt.Sprintf("%s != nil && %s", name, filter) + } } // check if the filter is a correct expression language