Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(inputs.win_eventlog): Handle XML data fields' filtering the same way as event fields #16008

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 40 additions & 37 deletions plugins/inputs/win_eventlog/win_eventlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"encoding/xml"
"errors"
"fmt"
"path/filepath"
"reflect"
"strings"
"syscall"
Expand All @@ -22,6 +21,7 @@ import (
"golang.org/x/sys/windows"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/filter"
"github.com/influxdata/telegraf/plugins/inputs"
)

Expand Down Expand Up @@ -49,6 +49,9 @@ type WinEventLog struct {
subscription EvtHandle
subscriptionFlag EvtSubscribeFlag
bookmark EvtHandle
tagFilter filter.Filter
fieldFilter filter.Filter
fieldEmptyFilter filter.Filter
}

const bufferSize = 1 << 14
Expand Down Expand Up @@ -78,6 +81,18 @@ func (w *WinEventLog) Init() error {
}
w.bookmark = bookmark

if w.tagFilter, err = filter.Compile(w.EventTags); err != nil {
return fmt.Errorf("creating tag filter failed: %w", err)
}

if w.fieldFilter, err = filter.NewIncludeExcludeFilter(w.EventFields, w.ExcludeFields); err != nil {
return fmt.Errorf("creating field filter failed: %w", err)
}

if w.fieldEmptyFilter, err = filter.Compile(w.ExcludeEmpty); err != nil {
return fmt.Errorf("creating empty fields filter failed: %w", err)
}

return nil
}

Expand Down Expand Up @@ -204,7 +219,6 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
}
}
}
default:
}
if should, where := w.shouldProcessField(fieldName); should {
if where == "tags" {
Expand Down Expand Up @@ -249,7 +263,13 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
}
uniqueXMLFields := UniqueFieldNames(xmlFields, fieldsUsage, w.Separator)
for _, xmlField := range uniqueXMLFields {
if !w.shouldExclude(xmlField.Name) {
should, where := w.shouldProcessField(xmlField.Name)
if !should {
continue
}
if where == "tags" {
tags[xmlField.Name] = xmlField.Value
} else {
fields[xmlField.Name] = xmlField.Value
}
}
Expand All @@ -262,48 +282,32 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
return nil
}

func (w *WinEventLog) shouldExclude(field string) (should bool) {
for _, excludePattern := range w.ExcludeFields {
// Check if field name matches excluded list
if matched, err := filepath.Match(excludePattern, field); matched && err == nil {
return true
}
}
return false
}

func (w *WinEventLog) shouldProcessField(field string) (should bool, list string) {
for _, pattern := range w.EventTags {
if matched, err := filepath.Match(pattern, field); matched && err == nil {
// Tags are not excluded
return true, "tags"
}
if w.tagFilter != nil && w.tagFilter.Match(field) {
return true, "tags"
}

for _, pattern := range w.EventFields {
if matched, err := filepath.Match(pattern, field); matched && err == nil {
if w.shouldExclude(field) {
return false, "excluded"
}
return true, "fields"
}
if w.fieldFilter.Match(field) {
return true, "fields"
}

return false, "excluded"
}

func (w *WinEventLog) shouldExcludeEmptyField(field string, fieldType string, fieldValue interface{}) (should bool) {
for _, pattern := range w.ExcludeEmpty {
if matched, err := filepath.Match(pattern, field); matched && err == nil {
switch fieldType {
case "string":
return len(fieldValue.(string)) < 1
case "int":
return fieldValue.(int) == 0
case "uint32":
return fieldValue.(uint32) == 0
}
}
if w.fieldEmptyFilter == nil || !w.fieldEmptyFilter.Match(field) {
return false
}

switch fieldType {
case "string":
return len(fieldValue.(string)) < 1
case "int":
return fieldValue.(int) == 0
case "uint32":
return fieldValue.(uint32) == 0
}

return false
}

Expand Down Expand Up @@ -568,7 +572,6 @@ func init() {
OnlyFirstLineOfMessage: true,
TimeStampFromEvent: true,
EventTags: []string{"Source", "EventID", "Level", "LevelText", "Keywords", "Channel", "Computer"},
EventFields: []string{"*"},
ExcludeEmpty: []string{"Task", "Opcode", "*ActivityID", "UserID"},
}
})
Expand Down
83 changes: 41 additions & 42 deletions plugins/inputs/win_eventlog/win_eventlog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package win_eventlog

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) {
Expand All @@ -16,59 +18,59 @@ func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) {
fieldValue interface{}
}
tests := []struct {
name string
w *WinEventLog
args args
wantShould bool
name string
w *WinEventLog
args args
expected bool
}{
{
name: "Not in list",
args: args{field: "qq", fieldType: "string", fieldValue: ""},
wantShould: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Not in list",
args: args{field: "qq", fieldType: "string", fieldValue: ""},
expected: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Empty string",
args: args{field: "test", fieldType: "string", fieldValue: ""},
wantShould: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Empty string",
args: args{field: "test", fieldType: "string", fieldValue: ""},
expected: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Non-empty string",
args: args{field: "test", fieldType: "string", fieldValue: "qq"},
wantShould: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Non-empty string",
args: args{field: "test", fieldType: "string", fieldValue: "qq"},
expected: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Zero int",
args: args{field: "test", fieldType: "int", fieldValue: int(0)},
wantShould: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Zero int",
args: args{field: "test", fieldType: "int", fieldValue: int(0)},
expected: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Non-zero int",
args: args{field: "test", fieldType: "int", fieldValue: int(-1)},
wantShould: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Non-zero int",
args: args{field: "test", fieldType: "int", fieldValue: int(-1)},
expected: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Zero uint32",
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0)},
wantShould: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Zero uint32",
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0)},
expected: true,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
{
name: "Non-zero uint32",
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0xc0fefeed)},
wantShould: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
name: "Non-zero uint32",
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0xc0fefeed)},
expected: false,
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if gotShould := tt.w.shouldExcludeEmptyField(tt.args.field, tt.args.fieldType, tt.args.fieldValue); gotShould != tt.wantShould {
t.Errorf("WinEventLog.shouldExcludeEmptyField() = %v, want %v", gotShould, tt.wantShould)
}
require.NoError(t, tt.w.Init())
actual := tt.w.shouldExcludeEmptyField(tt.args.field, tt.args.fieldType, tt.args.fieldValue)
require.Equal(t, tt.expected, actual)
})
}
}
Expand Down Expand Up @@ -125,13 +127,10 @@ func TestWinEventLog_shouldProcessField(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotShould, gotList := tt.w.shouldProcessField(tt.args.field)
if gotShould != tt.wantShould {
t.Errorf("WinEventLog.shouldProcessField() gotShould = %v, want %v", gotShould, tt.wantShould)
}
if gotList != tt.wantList {
t.Errorf("WinEventLog.shouldProcessField() gotList = %v, want %v", gotList, tt.wantList)
}
require.NoError(t, tt.w.Init())
should, list := tt.w.shouldProcessField(tt.args.field)
require.Equal(t, tt.wantShould, should)
require.Equal(t, tt.wantList, list)
})
}
}
Loading