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"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
@ -22,6 +21,7 @@ import (
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
|
|
||||||
"github.com/influxdata/telegraf"
|
"github.com/influxdata/telegraf"
|
||||||
|
"github.com/influxdata/telegraf/filter"
|
||||||
"github.com/influxdata/telegraf/plugins/inputs"
|
"github.com/influxdata/telegraf/plugins/inputs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -49,6 +49,9 @@ type WinEventLog struct {
|
||||||
subscription EvtHandle
|
subscription EvtHandle
|
||||||
subscriptionFlag EvtSubscribeFlag
|
subscriptionFlag EvtSubscribeFlag
|
||||||
bookmark EvtHandle
|
bookmark EvtHandle
|
||||||
|
tagFilter filter.Filter
|
||||||
|
fieldFilter filter.Filter
|
||||||
|
fieldEmptyFilter filter.Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
const bufferSize = 1 << 14
|
const bufferSize = 1 << 14
|
||||||
|
|
@ -78,6 +81,18 @@ func (w *WinEventLog) Init() error {
|
||||||
}
|
}
|
||||||
w.bookmark = bookmark
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +219,6 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
if should, where := w.shouldProcessField(fieldName); should {
|
if should, where := w.shouldProcessField(fieldName); should {
|
||||||
if where == "tags" {
|
if where == "tags" {
|
||||||
|
|
@ -249,7 +263,13 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
uniqueXMLFields := UniqueFieldNames(xmlFields, fieldsUsage, w.Separator)
|
uniqueXMLFields := UniqueFieldNames(xmlFields, fieldsUsage, w.Separator)
|
||||||
for _, xmlField := range uniqueXMLFields {
|
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
|
fields[xmlField.Name] = xmlField.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,48 +282,32 @@ func (w *WinEventLog) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
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) {
|
func (w *WinEventLog) shouldProcessField(field string) (should bool, list string) {
|
||||||
for _, pattern := range w.EventTags {
|
if w.tagFilter != nil && w.tagFilter.Match(field) {
|
||||||
if matched, err := filepath.Match(pattern, field); matched && err == nil {
|
return true, "tags"
|
||||||
// Tags are not excluded
|
|
||||||
return true, "tags"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pattern := range w.EventFields {
|
if w.fieldFilter.Match(field) {
|
||||||
if matched, err := filepath.Match(pattern, field); matched && err == nil {
|
return true, "fields"
|
||||||
if w.shouldExclude(field) {
|
|
||||||
return false, "excluded"
|
|
||||||
}
|
|
||||||
return true, "fields"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, "excluded"
|
return false, "excluded"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WinEventLog) shouldExcludeEmptyField(field string, fieldType string, fieldValue interface{}) (should bool) {
|
func (w *WinEventLog) shouldExcludeEmptyField(field string, fieldType string, fieldValue interface{}) (should bool) {
|
||||||
for _, pattern := range w.ExcludeEmpty {
|
if w.fieldEmptyFilter == nil || !w.fieldEmptyFilter.Match(field) {
|
||||||
if matched, err := filepath.Match(pattern, field); matched && err == nil {
|
return false
|
||||||
switch fieldType {
|
|
||||||
case "string":
|
|
||||||
return len(fieldValue.(string)) < 1
|
|
||||||
case "int":
|
|
||||||
return fieldValue.(int) == 0
|
|
||||||
case "uint32":
|
|
||||||
return fieldValue.(uint32) == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch fieldType {
|
||||||
|
case "string":
|
||||||
|
return len(fieldValue.(string)) < 1
|
||||||
|
case "int":
|
||||||
|
return fieldValue.(int) == 0
|
||||||
|
case "uint32":
|
||||||
|
return fieldValue.(uint32) == 0
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,7 +572,6 @@ func init() {
|
||||||
OnlyFirstLineOfMessage: true,
|
OnlyFirstLineOfMessage: true,
|
||||||
TimeStampFromEvent: true,
|
TimeStampFromEvent: true,
|
||||||
EventTags: []string{"Source", "EventID", "Level", "LevelText", "Keywords", "Channel", "Computer"},
|
EventTags: []string{"Source", "EventID", "Level", "LevelText", "Keywords", "Channel", "Computer"},
|
||||||
EventFields: []string{"*"},
|
|
||||||
ExcludeEmpty: []string{"Task", "Opcode", "*ActivityID", "UserID"},
|
ExcludeEmpty: []string{"Task", "Opcode", "*ActivityID", "UserID"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ package win_eventlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) {
|
func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) {
|
||||||
|
|
@ -16,59 +18,59 @@ func TestWinEventLog_shouldExcludeEmptyField(t *testing.T) {
|
||||||
fieldValue interface{}
|
fieldValue interface{}
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
w *WinEventLog
|
w *WinEventLog
|
||||||
args args
|
args args
|
||||||
wantShould bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Not in list",
|
name: "Not in list",
|
||||||
args: args{field: "qq", fieldType: "string", fieldValue: ""},
|
args: args{field: "qq", fieldType: "string", fieldValue: ""},
|
||||||
wantShould: false,
|
expected: false,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Empty string",
|
name: "Empty string",
|
||||||
args: args{field: "test", fieldType: "string", fieldValue: ""},
|
args: args{field: "test", fieldType: "string", fieldValue: ""},
|
||||||
wantShould: true,
|
expected: true,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Non-empty string",
|
name: "Non-empty string",
|
||||||
args: args{field: "test", fieldType: "string", fieldValue: "qq"},
|
args: args{field: "test", fieldType: "string", fieldValue: "qq"},
|
||||||
wantShould: false,
|
expected: false,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Zero int",
|
name: "Zero int",
|
||||||
args: args{field: "test", fieldType: "int", fieldValue: int(0)},
|
args: args{field: "test", fieldType: "int", fieldValue: int(0)},
|
||||||
wantShould: true,
|
expected: true,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Non-zero int",
|
name: "Non-zero int",
|
||||||
args: args{field: "test", fieldType: "int", fieldValue: int(-1)},
|
args: args{field: "test", fieldType: "int", fieldValue: int(-1)},
|
||||||
wantShould: false,
|
expected: false,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Zero uint32",
|
name: "Zero uint32",
|
||||||
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0)},
|
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0)},
|
||||||
wantShould: true,
|
expected: true,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Non-zero uint32",
|
name: "Non-zero uint32",
|
||||||
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0xc0fefeed)},
|
args: args{field: "test", fieldType: "uint32", fieldValue: uint32(0xc0fefeed)},
|
||||||
wantShould: false,
|
expected: false,
|
||||||
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
w: &WinEventLog{ExcludeEmpty: []string{"te*"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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 {
|
require.NoError(t, tt.w.Init())
|
||||||
t.Errorf("WinEventLog.shouldExcludeEmptyField() = %v, want %v", gotShould, tt.wantShould)
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
gotShould, gotList := tt.w.shouldProcessField(tt.args.field)
|
require.NoError(t, tt.w.Init())
|
||||||
if gotShould != tt.wantShould {
|
should, list := tt.w.shouldProcessField(tt.args.field)
|
||||||
t.Errorf("WinEventLog.shouldProcessField() gotShould = %v, want %v", gotShould, tt.wantShould)
|
require.Equal(t, tt.wantShould, should)
|
||||||
}
|
require.Equal(t, tt.wantList, list)
|
||||||
if gotList != tt.wantList {
|
|
||||||
t.Errorf("WinEventLog.shouldProcessField() gotList = %v, want %v", gotList, tt.wantList)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue