From 18b2d11d6e9aaf84d85e83a1246e3094e76f6ed0 Mon Sep 17 00:00:00 2001 From: Sven Rebhan Date: Fri, 11 Oct 2024 16:42:58 +0200 Subject: [PATCH] fix(inputs.win_eventlog): Handle XML data fields' filtering the same way as event fields --- plugins/inputs/win_eventlog/win_eventlog.go | 77 ++++++++--------- .../inputs/win_eventlog/win_eventlog_test.go | 83 +++++++++---------- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/plugins/inputs/win_eventlog/win_eventlog.go b/plugins/inputs/win_eventlog/win_eventlog.go index 48da5fbfe24fc..b0eb3fed0ef22 100644 --- a/plugins/inputs/win_eventlog/win_eventlog.go +++ b/plugins/inputs/win_eventlog/win_eventlog.go @@ -13,7 +13,6 @@ import ( "encoding/xml" "errors" "fmt" - "path/filepath" "reflect" "strings" "syscall" @@ -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" ) @@ -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 @@ -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 } @@ -204,7 +219,6 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error { } } } - default: } if should, where := w.shouldProcessField(fieldName); should { if where == "tags" { @@ -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 } } @@ -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 } @@ -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"}, } }) diff --git a/plugins/inputs/win_eventlog/win_eventlog_test.go b/plugins/inputs/win_eventlog/win_eventlog_test.go index 8d86c0e756573..c7f0f8e4fd02a 100644 --- a/plugins/inputs/win_eventlog/win_eventlog_test.go +++ b/plugins/inputs/win_eventlog/win_eventlog_test.go @@ -7,6 +7,8 @@ package win_eventlog import ( "testing" + + "github.com/stretchr/testify/require" ) func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) { @@ -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) }) } } @@ -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) }) } }