diff --git a/pkg/stanza/operator/parser/keyvalue/config_test.go b/pkg/stanza/operator/parser/keyvalue/config_test.go index 2531835ffe92..9af7fb200300 100644 --- a/pkg/stanza/operator/parser/keyvalue/config_test.go +++ b/pkg/stanza/operator/parser/keyvalue/config_test.go @@ -21,7 +21,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper/operatortest" ) -func TestKVParserConfig(t *testing.T) { +func TestConfig(t *testing.T) { cases := []operatortest.ConfigUnmarshalTest{ { Name: "default", @@ -29,7 +29,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "parse_from_simple", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() cfg.ParseFrom = entry.NewBodyField("from") return cfg @@ -37,7 +37,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "parse_to_simple", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() cfg.ParseTo = entry.NewBodyField("log") return cfg @@ -45,7 +45,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "on_error_drop", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() cfg.OnError = "drop" return cfg @@ -53,7 +53,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "timestamp", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() parseField := entry.NewBodyField("timestamp_field") newTime := helper.TimeParser{ @@ -67,7 +67,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "severity", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() parseField := entry.NewBodyField("severity_field") severityField := helper.NewSeverityConfig() @@ -85,7 +85,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "delimiter", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() cfg.Delimiter = ";" return cfg @@ -93,7 +93,7 @@ func TestKVParserConfig(t *testing.T) { }, { Name: "pair_delimiter", - Expect: func() *KVParserConfig { + Expect: func() *Config { cfg := defaultCfg() cfg.PairDelimiter = ";" return cfg @@ -108,6 +108,6 @@ func TestKVParserConfig(t *testing.T) { } } -func defaultCfg() *KVParserConfig { - return NewKVParserConfig("key_value_parser") +func defaultCfg() *Config { + return NewConfig() } diff --git a/pkg/stanza/operator/parser/keyvalue/keyvalue.go b/pkg/stanza/operator/parser/keyvalue/keyvalue.go index aff6badaf938..b0f260448f47 100644 --- a/pkg/stanza/operator/parser/keyvalue/keyvalue.go +++ b/pkg/stanza/operator/parser/keyvalue/keyvalue.go @@ -28,20 +28,27 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" ) +const operatorType = "key_value_parser" + func init() { - operator.Register("key_value_parser", func() operator.Builder { return NewKVParserConfig("") }) + operator.Register(operatorType, func() operator.Builder { return NewConfig() }) +} + +// NewConfig creates a new key value parser config with default values +func NewConfig() *Config { + return NewConfigWithID(operatorType) } -// NewKVParserConfig creates a new key value parser config with default values -func NewKVParserConfig(operatorID string) *KVParserConfig { - return &KVParserConfig{ - ParserConfig: helper.NewParserConfig(operatorID, "key_value_parser"), +// NewConfigWithID creates a new key value parser config with default values +func NewConfigWithID(operatorID string) *Config { + return &Config{ + ParserConfig: helper.NewParserConfig(operatorID, operatorType), Delimiter: "=", } } -// KVParserConfig is the configuration of a key value parser operator. -type KVParserConfig struct { +// Config is the configuration of a key value parser operator. +type Config struct { helper.ParserConfig `mapstructure:",squash" yaml:",inline"` Delimiter string `mapstructure:"delimiter" yaml:"delimiter"` @@ -49,7 +56,7 @@ type KVParserConfig struct { } // Build will build a key value parser operator. -func (c KVParserConfig) Build(logger *zap.SugaredLogger) (operator.Operator, error) { +func (c Config) Build(logger *zap.SugaredLogger) (operator.Operator, error) { parserOperator, err := c.ParserConfig.Build(logger) if err != nil { return nil, err @@ -72,27 +79,27 @@ func (c KVParserConfig) Build(logger *zap.SugaredLogger) (operator.Operator, err } } - return &KVParser{ + return &Parser{ ParserOperator: parserOperator, delimiter: c.Delimiter, pairSplitFunc: pairSplitFunc, }, nil } -// KVParser is an operator that parses key value pairs. -type KVParser struct { +// Parser is an operator that parses key value pairs. +type Parser struct { helper.ParserOperator delimiter string pairSplitFunc func(input string) []string } // Process will parse an entry for key value pairs. -func (kv *KVParser) Process(ctx context.Context, entry *entry.Entry) error { +func (kv *Parser) Process(ctx context.Context, entry *entry.Entry) error { return kv.ParserOperator.ProcessWith(ctx, entry, kv.parse) } // parse will parse a value as key values. -func (kv *KVParser) parse(value interface{}) (interface{}, error) { +func (kv *Parser) parse(value interface{}) (interface{}, error) { switch m := value.(type) { case string: return kv.parser(m, kv.delimiter) @@ -101,7 +108,7 @@ func (kv *KVParser) parse(value interface{}) (interface{}, error) { } } -func (kv *KVParser) parser(input string, delimiter string) (map[string]interface{}, error) { +func (kv *Parser) parser(input string, delimiter string) (map[string]interface{}, error) { if input == "" { return nil, fmt.Errorf("parse from field %s is empty", kv.ParseFrom.String()) } diff --git a/pkg/stanza/operator/parser/keyvalue/keyvalue_test.go b/pkg/stanza/operator/parser/keyvalue/keyvalue_test.go index a21b12b0bbe4..d17ab4ba986d 100644 --- a/pkg/stanza/operator/parser/keyvalue/keyvalue_test.go +++ b/pkg/stanza/operator/parser/keyvalue/keyvalue_test.go @@ -27,11 +27,11 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/testutil" ) -func newTestParser(t *testing.T) *KVParser { - config := NewKVParserConfig("test") +func newTestParser(t *testing.T) *Parser { + config := NewConfigWithID("test") op, err := config.Build(testutil.Logger(t)) require.NoError(t, err) - return op.(*KVParser) + return op.(*Parser) } func TestInit(t *testing.T) { @@ -40,15 +40,15 @@ func TestInit(t *testing.T) { require.Equal(t, "key_value_parser", builder().Type()) } -func TestKVParserConfigBuild(t *testing.T) { - config := NewKVParserConfig("test") +func TestConfigBuild(t *testing.T) { + config := NewConfigWithID("test") op, err := config.Build(testutil.Logger(t)) require.NoError(t, err) - require.IsType(t, &KVParser{}, op) + require.IsType(t, &Parser{}, op) } -func TestKVParserConfigBuildFailure(t *testing.T) { - config := NewKVParserConfig("test") +func TestConfigBuildFailure(t *testing.T) { + config := NewConfigWithID("test") config.OnError = "invalid_on_error" _, err := config.Build(testutil.Logger(t)) require.Error(t, err) @@ -56,19 +56,19 @@ func TestKVParserConfigBuildFailure(t *testing.T) { } func TestBuild(t *testing.T) { - basicConfig := func() *KVParserConfig { - cfg := NewKVParserConfig("test_operator_id") + basicConfig := func() *Config { + cfg := NewConfigWithID("test_operator_id") return cfg } cases := []struct { name string - input *KVParserConfig + input *Config expectErr bool }{ { "default", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() return cfg }(), @@ -76,7 +76,7 @@ func TestBuild(t *testing.T) { }, { "delimiter", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() cfg.Delimiter = "/" return cfg @@ -85,7 +85,7 @@ func TestBuild(t *testing.T) { }, { "missing-delimiter", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() cfg.Delimiter = "" return cfg @@ -94,7 +94,7 @@ func TestBuild(t *testing.T) { }, { "pair-delimiter", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() cfg.PairDelimiter = "|" return cfg @@ -103,7 +103,7 @@ func TestBuild(t *testing.T) { }, { "same-delimiter-and-pair-delimiter", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() cfg.Delimiter = "|" cfg.PairDelimiter = cfg.Delimiter @@ -113,7 +113,7 @@ func TestBuild(t *testing.T) { }, { "unset-delimiter", - func() *KVParserConfig { + func() *Config { cfg := basicConfig() cfg.Delimiter = "" cfg.PairDelimiter = "!" @@ -136,14 +136,14 @@ func TestBuild(t *testing.T) { } } -func TestKVParserStringFailure(t *testing.T) { +func TestParserStringFailure(t *testing.T) { parser := newTestParser(t) _, err := parser.parse("invalid") require.Error(t, err) require.Contains(t, err.Error(), fmt.Sprintf("expected '%s' to split by '%s' into two items, got", "invalid", parser.delimiter)) } -func TestKVParserInvalidType(t *testing.T) { +func TestParserInvalidType(t *testing.T) { parser := newTestParser(t) _, err := parser.parse([]int{}) require.Error(t, err) @@ -151,13 +151,13 @@ func TestKVParserInvalidType(t *testing.T) { } func TestKVImplementations(t *testing.T) { - require.Implements(t, (*operator.Operator)(nil), new(KVParser)) + require.Implements(t, (*operator.Operator)(nil), new(Parser)) } -func TestKVParser(t *testing.T) { +func TestParser(t *testing.T) { cases := []struct { name string - configure func(*KVParserConfig) + configure func(*Config) input *entry.Entry expect *entry.Entry expectError bool @@ -165,7 +165,7 @@ func TestKVParser(t *testing.T) { }{ { "simple", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: "name=stanza age=2", }, @@ -181,7 +181,7 @@ func TestKVParser(t *testing.T) { }, { "parse-from", - func(kv *KVParserConfig) { + func(kv *Config) { kv.ParseFrom = entry.NewBodyField("test") }, &entry.Entry{ @@ -203,7 +203,7 @@ func TestKVParser(t *testing.T) { }, { "parse-to", - func(kv *KVParserConfig) { + func(kv *Config) { kv.ParseTo = entry.NewBodyField("test") }, &entry.Entry{ @@ -222,7 +222,7 @@ func TestKVParser(t *testing.T) { }, { "from-to", - func(kv *KVParserConfig) { + func(kv *Config) { kv.ParseFrom = entry.NewAttributeField("from") kv.ParseTo = entry.NewBodyField("to") }, @@ -247,7 +247,7 @@ func TestKVParser(t *testing.T) { }, { "user-agent", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `requestClientApplication="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"`, }, @@ -262,7 +262,7 @@ func TestKVParser(t *testing.T) { }, { "double-quotes-removed", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: "name=\"stanza\" age=2", }, @@ -278,7 +278,7 @@ func TestKVParser(t *testing.T) { }, { "single-quotes-removed", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: "description='stanza deployment number 5' x=y", }, @@ -294,7 +294,7 @@ func TestKVParser(t *testing.T) { }, { "double-quotes-spaces-removed", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `name=" stanza " age=2`, }, @@ -310,7 +310,7 @@ func TestKVParser(t *testing.T) { }, { "leading-and-trailing-space", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `" name "=" stanza " age=2`, }, @@ -326,7 +326,7 @@ func TestKVParser(t *testing.T) { }, { "delimiter", - func(kv *KVParserConfig) { + func(kv *Config) { kv.Delimiter = "|" kv.ParseFrom = entry.NewBodyField("testfield") kv.ParseTo = entry.NewBodyField("testparsed") @@ -351,7 +351,7 @@ func TestKVParser(t *testing.T) { }, { "double-delimiter", - func(kv *KVParserConfig) { + func(kv *Config) { kv.Delimiter = "==" }, &entry.Entry{ @@ -370,7 +370,7 @@ func TestKVParser(t *testing.T) { }, { "pair-delimiter", - func(kv *KVParserConfig) { + func(kv *Config) { kv.PairDelimiter = "|" }, &entry.Entry{ @@ -389,7 +389,7 @@ func TestKVParser(t *testing.T) { }, { "large", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: "name=stanza age=1 job=\"software engineering\" location=\"grand rapids michigan\" src=\"10.3.3.76\" dst=172.217.0.10 protocol=udp sport=57112 dport=443 translated_src_ip=96.63.176.3 translated_port=57112", }, @@ -414,7 +414,7 @@ func TestKVParser(t *testing.T) { }, { "dell-sonic-wall", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `id=LVM_Sonicwall sn=22255555 time="2021-09-22 16:30:31" fw=14.165.177.10 pri=6 c=1024 gcat=2 m=97 msg="Web site hit" srcMac=6c:0b:84:3f:fa:63 src=192.168.50.2:52006:X0 srcZone=LAN natSrc=14.165.177.10:58457 dstMac=08:b2:58:46:30:54 dst=15.159.150.83:443:X1 dstZone=WAN natDst=15.159.150.83:443 proto=tcp/https sent=1422 rcvd=5993 rule="6 (LAN->WAN)" app=48 dstname=example.space.dev.com arg=/ code=27 Category="Information Technology/Computers" note="Policy: a0, Info: 888 " n=3412158`, }, @@ -456,7 +456,7 @@ func TestKVParser(t *testing.T) { }, { "missing-delimiter", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `test text`, }, @@ -468,7 +468,7 @@ func TestKVParser(t *testing.T) { }, { "invalid-pair", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{ Body: `test=text=abc`, }, @@ -480,7 +480,7 @@ func TestKVParser(t *testing.T) { }, { "empty-input", - func(kv *KVParserConfig) {}, + func(kv *Config) {}, &entry.Entry{}, &entry.Entry{}, true, @@ -488,7 +488,7 @@ func TestKVParser(t *testing.T) { }, { "same-delimiter-and-pair-delimiter", - func(kv *KVParserConfig) { + func(kv *Config) { kv.Delimiter = "!" kv.PairDelimiter = kv.Delimiter }, @@ -503,7 +503,7 @@ func TestKVParser(t *testing.T) { }, { "unset-delimiter", - func(kv *KVParserConfig) { + func(kv *Config) { kv.Delimiter = "" kv.PairDelimiter = "!" }, @@ -520,7 +520,7 @@ func TestKVParser(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - cfg := NewKVParserConfig("test") + cfg := NewConfigWithID("test") cfg.OutputIDs = []string{"fake"} tc.configure(cfg)