Skip to content

Commit

Permalink
Add Condition to check if a list of fields exists
Browse files Browse the repository at this point in the history
- Create condition to check whether the give list of fields exist in the event
- Add Tests for the created condition
- Add Documentation for the created condition
- closes - elastic#6285
  • Loading branch information
sriranganathan committed Mar 28, 2018
1 parent 78f817f commit 1994899
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
18 changes: 18 additions & 0 deletions libbeat/docs/processors-using.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ The supported conditions are:
* <<condition-contains,`contains`>>
* <<condition-regexp,`regexp`>>
* <<condition-range, `range`>>
* <<condition-has_fields, `has_fields`>>
* <<condition-or, `or`>>
* <<condition-and, `and`>>
* <<condition-not, `not`>>
Expand Down Expand Up @@ -157,6 +158,23 @@ range:
------


[float]
[[condition-has_fields]]
===== `has_fields`

The `has_fields` condition checks if the given fields exist in the
event. The condition accepts a list of string values denoting the field names.

For example, the following condition checks if the `http.response.code` field
is present in the event.


[source,yaml]
------
has_fields: ['http.response.code']
------


[float]
[[condition-or]]
===== `or`
Expand Down
22 changes: 21 additions & 1 deletion libbeat/processors/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type Condition struct {
name string
filters map[string]match.Matcher
}
hasfields struct {
fields []string
}
rangexp map[string]RangeValue
or []Condition
and []Condition
Expand Down Expand Up @@ -82,6 +85,8 @@ func NewCondition(config *ConditionConfig) (*Condition, error) {
c.matches.filters, err = compileMatches(config.Regexp.fields, match.Compile)
case config.Range != nil:
err = c.setRange(config.Range)
case config.HasFields != nil:
c.hasfields.fields = config.HasFields
case len(config.OR) > 0:
c.or, err = NewConditionList(config.OR)
case len(config.AND) > 0:
Expand Down Expand Up @@ -226,7 +231,8 @@ func (c *Condition) Check(event ValuesMap) bool {

return c.checkEquals(event) &&
c.checkMatches(event) &&
c.checkRange(event)
c.checkRange(event) &&
c.checkHasFields(event)
}

func (c *Condition) checkOR(event ValuesMap) bool {
Expand Down Expand Up @@ -399,6 +405,17 @@ func (c *Condition) checkRange(event ValuesMap) bool {
return true
}

func (c *Condition) checkHasFields(event ValuesMap) bool {
for _, field := range c.hasfields.fields {
_, err := event.GetValue(field)
if err != nil {
logp.Info("Field %v not present in the event", field)
return false
}
}
return true
}

func (c Condition) String() string {
s := ""

Expand All @@ -411,6 +428,9 @@ func (c Condition) String() string {
if len(c.rangexp) > 0 {
s = s + fmt.Sprintf("range: %v", c.rangexp)
}
if len(c.hasfields.fields) > 0 {
s = s + fmt.Sprintf("has_fields: %v", c.hasfields.fields)
}
if len(c.or) > 0 {
for _, cond := range c.or {
s = s + cond.String() + " or "
Expand Down
24 changes: 24 additions & 0 deletions libbeat/processors/condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ func TestCondition(t *testing.T) {
},
result: true,
},
{
config: ConditionConfig{
HasFields: []string{"proc.cmdline"},
},
result: true,
},
{
config: ConditionConfig{
HasFields: []string{"cpu"},
},
result: false,
},
}

event := &beat.Event{
Expand Down Expand Up @@ -581,6 +593,18 @@ func TestWhenProcessor(t *testing.T) {
[]common.MapStr{{"i": 10}},
1,
},
{
"condition_matches",
config{"when.has_fields": []string{"i"}},
[]common.MapStr{{"i": 10}},
1,
},
{
"condition_fails",
config{"when.has_fields": []string{"j"}},
[]common.MapStr{{"i": 10}},
0,
},
}

for i, test := range tests {
Expand Down
15 changes: 8 additions & 7 deletions libbeat/processors/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (
)

type ConditionConfig struct {
Equals *ConditionFields `config:"equals"`
Contains *ConditionFields `config:"contains"`
Regexp *ConditionFields `config:"regexp"`
Range *ConditionFields `config:"range"`
OR []ConditionConfig `config:"or"`
AND []ConditionConfig `config:"and"`
NOT *ConditionConfig `config:"not"`
Equals *ConditionFields `config:"equals"`
Contains *ConditionFields `config:"contains"`
Regexp *ConditionFields `config:"regexp"`
Range *ConditionFields `config:"range"`
HasFields []string `config:"has_fields"`
OR []ConditionConfig `config:"or"`
AND []ConditionConfig `config:"and"`
NOT *ConditionConfig `config:"not"`
}

type ConditionFields struct {
Expand Down

0 comments on commit 1994899

Please sign in to comment.