fix(inputs.win_eventlog): Handle XML data fields' filtering the same way as event fields (#16008)
This commit is contained in:
parent
0abd184087
commit
aaae84b67b
|
|
@ -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"},
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue