fix awkward stacktrace in conditional filter (#2145)

This commit is contained in:
Thibault "bui" Koechlin 2023-03-27 16:01:42 +02:00 committed by GitHub
parent f39fbf07fa
commit 169b844212
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 18 deletions

View file

@ -2,6 +2,7 @@ package leakybucket
import ( import (
"fmt" "fmt"
"sync"
"time" "time"
"github.com/antonmedv/expr" "github.com/antonmedv/expr"
@ -10,24 +11,40 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/types"
) )
var conditionalExprCache map[string]vm.Program
var conditionalExprCacheLock sync.Mutex
type ConditionalOverflow struct { type ConditionalOverflow struct {
ConditionalFilter string ConditionalFilter string
ConditionalFilterRuntime *vm.Program ConditionalFilterRuntime *vm.Program
DumbProcessor DumbProcessor
} }
func NewConditionalOverflow(g *BucketFactory) (*ConditionalOverflow, error) { func (c *ConditionalOverflow) OnBucketInit(g *BucketFactory) error {
var err error var err error
var compiledExpr *vm.Program
c := ConditionalOverflow{} if conditionalExprCache == nil {
c.ConditionalFilter = g.ConditionalOverflow conditionalExprCache = make(map[string]vm.Program)
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)
} }
return &c, nil 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 err
} }
func (c *ConditionalOverflow) AfterBucketPour(b *BucketFactory) func(types.Event, *Leaky) *types.Event { func (c *ConditionalOverflow) AfterBucketPour(b *BucketFactory) func(types.Event, *Leaky) *types.Event {

View file

@ -321,12 +321,12 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error {
} }
if bucketFactory.Distinct != "" { 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{}) bucketFactory.processors = append(bucketFactory.processors, &Uniq{})
} }
if bucketFactory.CancelOnFilter != "" { 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{}) bucketFactory.processors = append(bucketFactory.processors, &CancelOnFilter{})
} }
@ -351,13 +351,8 @@ func LoadBucket(bucketFactory *BucketFactory, tomb *tomb.Tomb) error {
} }
if bucketFactory.ConditionalOverflow != "" { if bucketFactory.ConditionalOverflow != "" {
bucketFactory.logger.Tracef("Adding conditional overflow.") bucketFactory.logger.Tracef("Adding conditional overflow")
condovflw, err := NewConditionalOverflow(bucketFactory) bucketFactory.processors = append(bucketFactory.processors, &ConditionalOverflow{})
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)
} }
if len(bucketFactory.Data) > 0 { if len(bucketFactory.Data) > 0 {