Skip to content

Commit

Permalink
refactor pkg/parser: extract processGrok (#3080)
Browse files Browse the repository at this point in the history
* pkg/parser: extract method processGrok()

* early return

* early return/2
  • Loading branch information
mmetc authored Jun 12, 2024
1 parent fd433a7 commit 73792ea
Showing 1 changed file with 79 additions and 69 deletions.
148 changes: 79 additions & 69 deletions pkg/parser/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,84 @@ func (n *Node) processWhitelist(cachedExprEnv map[string]interface{}, p *types.E
return isWhitelisted, nil
}

func (n *Node) process(p *types.Event, ctx UnixParserCtx, expressionEnv map[string]interface{}) (bool, error) {

func (n *Node) processGrok(p *types.Event, cachedExprEnv map[string]any) (bool, bool, error) {
// Process grok if present, should be exclusive with nodes :)
clog := n.Logger
var NodeHasOKGrok bool
gstr := ""

if n.Grok.RunTimeRegexp == nil {
clog.Tracef("! No grok pattern : %p", n.Grok.RunTimeRegexp)
return true, false, nil
}

clog.Tracef("Processing grok pattern : %s : %p", n.Grok.RegexpName, n.Grok.RunTimeRegexp)
// for unparsed, parsed etc. set sensible defaults to reduce user hassle
if n.Grok.TargetField != "" {
// it's a hack to avoid using real reflect
if n.Grok.TargetField == "Line.Raw" {
gstr = p.Line.Raw
} else if val, ok := p.Parsed[n.Grok.TargetField]; ok {
gstr = val
} else {
clog.Debugf("(%s) target field '%s' doesn't exist in %v", n.rn, n.Grok.TargetField, p.Parsed)
return false, false, nil
}
} else if n.Grok.RunTimeValue != nil {
output, err := exprhelpers.Run(n.Grok.RunTimeValue, cachedExprEnv, clog, n.Debug)
if err != nil {
clog.Warningf("failed to run RunTimeValue : %v", err)
return false, false, nil
}

switch out := output.(type) {
case string:
gstr = out
case int:
gstr = fmt.Sprintf("%d", out)
case float64, float32:
gstr = fmt.Sprintf("%f", out)
default:
clog.Errorf("unexpected return type for RunTimeValue : %T", output)
}
}

var groklabel string
if n.Grok.RegexpName == "" {
groklabel = fmt.Sprintf("%5.5s...", n.Grok.RegexpValue)
} else {
groklabel = n.Grok.RegexpName
}

grok := n.Grok.RunTimeRegexp.Parse(gstr)

if len(grok) == 0 {
// grok failed, node failed
clog.Debugf("+ Grok '%s' didn't return data on '%s'", groklabel, gstr)
return false, false, nil
}

/*tag explicitly that the *current* node had a successful grok pattern. it's important to know success state*/
NodeHasOKGrok = true

clog.Debugf("+ Grok '%s' returned %d entries to merge in Parsed", groklabel, len(grok))
// We managed to grok stuff, merged into parse
for k, v := range grok {
clog.Debugf("\t.Parsed['%s'] = '%s'", k, v)
p.Parsed[k] = v
}
// if the grok succeed, process associated statics
err := n.ProcessStatics(n.Grok.Statics, p)
if err != nil {
clog.Errorf("(%s) Failed to process statics : %v", n.rn, err)
return false, false, err
}

return true, NodeHasOKGrok, nil
}

func (n *Node) process(p *types.Event, ctx UnixParserCtx, expressionEnv map[string]interface{}) (bool, error) {
clog := n.Logger

cachedExprEnv := expressionEnv
Expand All @@ -229,74 +304,9 @@ func (n *Node) process(p *types.Event, ctx UnixParserCtx, expressionEnv map[stri
return false, err
}

// Process grok if present, should be exclusive with nodes :)
gstr := ""

if n.Grok.RunTimeRegexp != nil {
clog.Tracef("Processing grok pattern : %s : %p", n.Grok.RegexpName, n.Grok.RunTimeRegexp)
// for unparsed, parsed etc. set sensible defaults to reduce user hassle
if n.Grok.TargetField != "" {
// it's a hack to avoid using real reflect
if n.Grok.TargetField == "Line.Raw" {
gstr = p.Line.Raw
} else if val, ok := p.Parsed[n.Grok.TargetField]; ok {
gstr = val
} else {
clog.Debugf("(%s) target field '%s' doesn't exist in %v", n.rn, n.Grok.TargetField, p.Parsed)

NodeState = false
}
} else if n.Grok.RunTimeValue != nil {
output, err := exprhelpers.Run(n.Grok.RunTimeValue, cachedExprEnv, clog, n.Debug)
if err != nil {
clog.Warningf("failed to run RunTimeValue : %v", err)

NodeState = false
}

switch out := output.(type) {
case string:
gstr = out
case int:
gstr = fmt.Sprintf("%d", out)
case float64, float32:
gstr = fmt.Sprintf("%f", out)
default:
clog.Errorf("unexpected return type for RunTimeValue : %T", output)
}
}

var groklabel string
if n.Grok.RegexpName == "" {
groklabel = fmt.Sprintf("%5.5s...", n.Grok.RegexpValue)
} else {
groklabel = n.Grok.RegexpName
}

grok := n.Grok.RunTimeRegexp.Parse(gstr)
if len(grok) > 0 {
/*tag explicitly that the *current* node had a successful grok pattern. it's important to know success state*/
NodeHasOKGrok = true

clog.Debugf("+ Grok '%s' returned %d entries to merge in Parsed", groklabel, len(grok))
// We managed to grok stuff, merged into parse
for k, v := range grok {
clog.Debugf("\t.Parsed['%s'] = '%s'", k, v)
p.Parsed[k] = v
}
// if the grok succeed, process associated statics
err := n.ProcessStatics(n.Grok.Statics, p)
if err != nil {
clog.Errorf("(%s) Failed to process statics : %v", n.rn, err)
return false, err
}
} else {
// grok failed, node failed
clog.Debugf("+ Grok '%s' didn't return data on '%s'", groklabel, gstr)
NodeState = false
}
} else {
clog.Tracef("! No grok pattern : %p", n.Grok.RunTimeRegexp)
NodeState, NodeHasOKGrok, err := n.processGrok(p, cachedExprEnv)
if err != nil {
return false, err
}

// Process the stash (data collection) if : a grok was present and succeeded, or if there is no grok
Expand Down

0 comments on commit 73792ea

Please sign in to comment.