diff --git a/pkg/leakybucket/blackhole.go b/pkg/leakybucket/blackhole.go index bda2e7c9ed1..95ea18f723b 100644 --- a/pkg/leakybucket/blackhole.go +++ b/pkg/leakybucket/blackhole.go @@ -21,7 +21,6 @@ type Blackhole struct { func NewBlackhole(bucketFactory *BucketFactory) (*Blackhole, error) { duration, err := time.ParseDuration(bucketFactory.Blackhole) if err != nil { - bucketFactory.logger.Warning("Blackhole duration not valid, using 1h") return nil, fmt.Errorf("blackhole duration not valid '%s'", bucketFactory.Blackhole) } return &Blackhole{ diff --git a/pkg/leakybucket/manager_load.go b/pkg/leakybucket/manager_load.go index 6e601bb2ec1..13ce1df75ae 100644 --- a/pkg/leakybucket/manager_load.go +++ b/pkg/leakybucket/manager_load.go @@ -405,11 +405,22 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error { if bucketFactory.Distinct != "" { bucketFactory.logger.Tracef("Adding a non duplicate filter") bucketFactory.processors = append(bucketFactory.processors, &Uniq{}) + bucketFactory.logger.Infof("Compiling distinct '%s'", bucketFactory.Distinct) + //we're compiling and discarding the expression to be able to detect it during loading + _, err = expr.Compile(bucketFactory.Distinct, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...) + if err != nil { + return fmt.Errorf("invalid distinct '%s' in %s: %w", bucketFactory.Distinct, bucketFactory.Filename, err) + } } if bucketFactory.CancelOnFilter != "" { bucketFactory.logger.Tracef("Adding a cancel_on filter") bucketFactory.processors = append(bucketFactory.processors, &CancelOnFilter{}) + //we're compiling and discarding the expression to be able to detect it during loading + _, err = expr.Compile(bucketFactory.CancelOnFilter, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...) + if err != nil { + return fmt.Errorf("invalid cancel_on '%s' in %s: %w", bucketFactory.CancelOnFilter, bucketFactory.Filename, err) + } } if bucketFactory.OverflowFilter != "" { @@ -439,6 +450,11 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error { if bucketFactory.ConditionalOverflow != "" { bucketFactory.logger.Tracef("Adding conditional overflow") bucketFactory.processors = append(bucketFactory.processors, &ConditionalOverflow{}) + //we're compiling and discarding the expression to be able to detect it during loading + _, err = expr.Compile(bucketFactory.ConditionalOverflow, exprhelpers.GetExprOptions(map[string]interface{}{"queue": &types.Queue{}, "leaky": &Leaky{}, "evt": &types.Event{}})...) + if err != nil { + return fmt.Errorf("invalid condition '%s' in %s: %w", bucketFactory.ConditionalOverflow, bucketFactory.Filename, err) + } } if bucketFactory.BayesianThreshold != 0 { diff --git a/pkg/leakybucket/manager_load_test.go b/pkg/leakybucket/manager_load_test.go index 9d207da164e..6b40deb8c9e 100644 --- a/pkg/leakybucket/manager_load_test.go +++ b/pkg/leakybucket/manager_load_test.go @@ -64,10 +64,24 @@ func TestLeakyBucketsConfig(t *testing.T) { {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true"}, true, true}, // leaky with invalid filter {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "xu"}, false, true}, + // leaky with invalid uniq + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", Distinct: "foo"}, false, true}, + // leaky with valid uniq + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", Distinct: "evt.Parsed.foobar"}, true, true}, // leaky with valid filter {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true"}, true, true}, // leaky with bad overflow filter {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", OverflowFilter: "xu"}, false, true}, + // leaky with valid overflow filter + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", OverflowFilter: "true"}, true, true}, + // leaky with invalid cancel_on filter + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", CancelOnFilter: "xu"}, false, true}, + // leaky with valid cancel_on filter + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", CancelOnFilter: "true"}, true, true}, + // leaky with invalid conditional overflow filter + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", ConditionalOverflow: "xu"}, false, true}, + // leaky with valid conditional overflow filter + {BucketFactory{Name: "test", Description: "test1", Type: "leaky", Capacity: 1, LeakSpeed: "1s", Filter: "true", ConditionalOverflow: "true"}, true, true}, } if err := runTest(CfgTests); err != nil { diff --git a/pkg/leakybucket/uniq.go b/pkg/leakybucket/uniq.go index 3a4683ae309..8a97f30b092 100644 --- a/pkg/leakybucket/uniq.go +++ b/pkg/leakybucket/uniq.go @@ -60,9 +60,6 @@ func (u *Uniq) AfterBucketPour(bucketFactory *BucketFactory) func(types.Event, * } func (u *Uniq) OnBucketInit(bucketFactory *BucketFactory) error { - var err error - var compiledExpr *vm.Program - if uniqExprCache == nil { uniqExprCache = make(map[string]vm.Program) } @@ -74,14 +71,17 @@ func (u *Uniq) OnBucketInit(bucketFactory *BucketFactory) error { } else { uniqExprCacheLock.Unlock() //release the lock during compile - compiledExpr, err = expr.Compile(bucketFactory.Distinct, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...) + compiledExpr, err := expr.Compile(bucketFactory.Distinct, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...) + if err != nil { + return err + } u.DistinctCompiled = compiledExpr uniqExprCacheLock.Lock() uniqExprCache[bucketFactory.Distinct] = *compiledExpr uniqExprCacheLock.Unlock() } u.KeyCache = make(map[string]bool) - return err + return nil } // getElement computes a string from an event and a filter