Przeglądaj źródła

fix awkward stacktrace in conditional filter (#2145)

Thibault "bui" Koechlin 2 lat temu
rodzic
commit
169b844212
2 zmienionych plików z 30 dodań i 18 usunięć
  1. 26 9
      pkg/leakybucket/conditional.go
  2. 4 9
      pkg/leakybucket/manager_load.go

+ 26 - 9
pkg/leakybucket/conditional.go

@@ -2,6 +2,7 @@ package leakybucket
 
 import (
 	"fmt"
+	"sync"
 	"time"
 
 	"github.com/antonmedv/expr"
@@ -10,24 +11,40 @@ import (
 	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
+var conditionalExprCache map[string]vm.Program
+var conditionalExprCacheLock sync.Mutex
+
 type ConditionalOverflow struct {
 	ConditionalFilter        string
 	ConditionalFilterRuntime *vm.Program
 	DumbProcessor
 }
 
-func NewConditionalOverflow(g *BucketFactory) (*ConditionalOverflow, error) {
+func (c *ConditionalOverflow) OnBucketInit(g *BucketFactory) error {
 	var err error
+	var compiledExpr *vm.Program
 
-	c := ConditionalOverflow{}
-	c.ConditionalFilter = g.ConditionalOverflow
-	c.ConditionalFilterRuntime, err = expr.Compile(c.ConditionalFilter, expr.Env(exprhelpers.GetExprEnv(map[string]interface{}{
-		"queue": &Queue{}, "leaky": &Leaky{}})))
-	if err != nil {
-		g.logger.Errorf("Unable to compile condition expression for conditional bucket : %s", err)
-		return nil, fmt.Errorf("unable to compile condition expression for conditional bucket : %v", err)
+	if conditionalExprCache == nil {
+		conditionalExprCache = make(map[string]vm.Program)
+	}
+	conditionalExprCacheLock.Lock()
+	if compiled, ok := conditionalExprCache[g.ConditionalOverflow]; ok {
+		conditionalExprCacheLock.Unlock()
+		c.ConditionalFilterRuntime = &compiled
+	} else {
+		conditionalExprCacheLock.Unlock()
+		//release the lock during compile
+		compiledExpr, err = expr.Compile(g.ConditionalOverflow, expr.Env(exprhelpers.GetExprEnv(map[string]interface{}{
+			"queue": &Queue{}, "leaky": &Leaky{}, "evt": &types.Event{}})))
+		if err != nil {
+			return fmt.Errorf("conditional compile error : %w", err)
+		}
+		c.ConditionalFilterRuntime = compiledExpr
+		conditionalExprCacheLock.Lock()
+		conditionalExprCache[g.ConditionalOverflow] = *compiledExpr
+		conditionalExprCacheLock.Unlock()
 	}
-	return &c, nil
+	return err
 }
 
 func (c *ConditionalOverflow) AfterBucketPour(b *BucketFactory) func(types.Event, *Leaky) *types.Event {

+ 4 - 9
pkg/leakybucket/manager_load.go

@@ -321,12 +321,12 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error {
 	}
 
 	if bucketFactory.Distinct != "" {
-		bucketFactory.logger.Tracef("Adding a non duplicate filter on %s.", bucketFactory.Name)
+		bucketFactory.logger.Tracef("Adding a non duplicate filter")
 		bucketFactory.processors = append(bucketFactory.processors, &Uniq{})
 	}
 
 	if bucketFactory.CancelOnFilter != "" {
-		bucketFactory.logger.Tracef("Adding a cancel_on filter on %s.", bucketFactory.Name)
+		bucketFactory.logger.Tracef("Adding a cancel_on filter")
 		bucketFactory.processors = append(bucketFactory.processors, &CancelOnFilter{})
 	}
 
@@ -351,13 +351,8 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error {
 	}
 
 	if bucketFactory.ConditionalOverflow != "" {
-		bucketFactory.logger.Tracef("Adding conditional overflow.")
-		condovflw, err := NewConditionalOverflow(bucketFactory)
-		if err != nil {
-			bucketFactory.logger.Errorf("Error creating conditional overflow : %s", err)
-			return fmt.Errorf("error creating conditional overflow : %s", err)
-		}
-		bucketFactory.processors = append(bucketFactory.processors, condovflw)
+		bucketFactory.logger.Tracef("Adding conditional overflow")
+		bucketFactory.processors = append(bucketFactory.processors, &ConditionalOverflow{})
 	}
 
 	if len(bucketFactory.Data) > 0 {