diff --git a/processor/attributesprocessor/config_test.go b/processor/attributesprocessor/config_test.go index 32916b5d1e631..597ef5f6d4d00 100644 --- a/processor/attributesprocessor/config_test.go +++ b/processor/attributesprocessor/config_test.go @@ -18,197 +18,224 @@ import ( "path/filepath" "testing" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/service/servicetest" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/attraction" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterconfig" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterset" ) -func TestLoadingConfig(t *testing.T) { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config.yaml"), factories) - assert.NoError(t, err) - require.NotNil(t, cfg) - - p0 := cfg.Processors[config.NewComponentIDWithName(typeStr, "insert")] - assert.Equal(t, p0, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "insert")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "attribute1", Value: 123, Action: attraction.INSERT}, - {Key: "string key", FromAttribute: "anotherkey", Action: attraction.INSERT}, +func TestLoadConfig(t *testing.T) { + t.Parallel() + + tests := []struct { + id config.ComponentID + expected config.Processor + }{ + { + id: config.NewComponentIDWithName(typeStr, "insert"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "attribute1", Value: 123, Action: attraction.INSERT}, + {Key: "string key", FromAttribute: "anotherkey", Action: attraction.INSERT}, + }, + }, }, }, - }) - - p1 := cfg.Processors[config.NewComponentIDWithName(typeStr, "update")] - assert.Equal(t, p1, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "update")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "boo", FromAttribute: "foo", Action: attraction.UPDATE}, - {Key: "db.secret", Value: "redacted", Action: attraction.UPDATE}, + { + id: config.NewComponentIDWithName(typeStr, "update"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "boo", FromAttribute: "foo", Action: attraction.UPDATE}, + {Key: "db.secret", Value: "redacted", Action: attraction.UPDATE}, + }, + }, }, }, - }) - - p2 := cfg.Processors[config.NewComponentIDWithName(typeStr, "upsert")] - assert.Equal(t, p2, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "upsert")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "region", Value: "planet-earth", Action: attraction.UPSERT}, - {Key: "new_user_key", FromAttribute: "user_key", Action: attraction.UPSERT}, + { + id: config.NewComponentIDWithName(typeStr, "upsert"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "region", Value: "planet-earth", Action: attraction.UPSERT}, + {Key: "new_user_key", FromAttribute: "user_key", Action: attraction.UPSERT}, + }, + }, }, }, - }) - - p3 := cfg.Processors[config.NewComponentIDWithName(typeStr, "delete")] - assert.Equal(t, p3, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "delete")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "credit_card", Action: attraction.DELETE}, - {Key: "duplicate_key", Action: attraction.DELETE}, + { + id: config.NewComponentIDWithName(typeStr, "delete"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "credit_card", Action: attraction.DELETE}, + {Key: "duplicate_key", Action: attraction.DELETE}, + }, + }, }, }, - }) - - p4 := cfg.Processors[config.NewComponentIDWithName(typeStr, "hash")] - assert.Equal(t, p4, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "hash")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "user.email", Action: attraction.HASH}, + { + id: config.NewComponentIDWithName(typeStr, "hash"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "user.email", Action: attraction.HASH}, + }, + }, }, }, - }) - - p5 := cfg.Processors[config.NewComponentIDWithName(typeStr, "excludemulti")] - assert.Equal(t, p5, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "excludemulti")), - MatchConfig: filterconfig.MatchConfig{ - Exclude: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Strict), - Services: []string{"svcA", "svcB"}, - Attributes: []filterconfig.Attribute{ - {Key: "env", Value: "dev"}, - {Key: "test_request"}, + { + id: config.NewComponentIDWithName(typeStr, "excludemulti"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + MatchConfig: filterconfig.MatchConfig{ + Exclude: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Strict), + Services: []string{"svcA", "svcB"}, + Attributes: []filterconfig.Attribute{ + {Key: "env", Value: "dev"}, + {Key: "test_request"}, + }, + }, + }, + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "credit_card", Action: attraction.DELETE}, + {Key: "duplicate_key", Action: attraction.DELETE}, + }, }, }, }, - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "credit_card", Action: attraction.DELETE}, - {Key: "duplicate_key", Action: attraction.DELETE}, + { + id: config.NewComponentIDWithName(typeStr, "includeservices"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + MatchConfig: filterconfig.MatchConfig{ + Include: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Regexp), + Services: []string{"auth.*", "login.*"}, + }, + }, + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "credit_card", Action: attraction.DELETE}, + {Key: "duplicate_key", Action: attraction.DELETE}, + }, + }, }, }, - }) - - p6 := cfg.Processors[config.NewComponentIDWithName(typeStr, "includeservices")] - assert.Equal(t, p6, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeservices")), - MatchConfig: filterconfig.MatchConfig{ - Include: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Regexp), - Services: []string{"auth.*", "login.*"}, + { + id: config.NewComponentIDWithName(typeStr, "selectiveprocessing"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + MatchConfig: filterconfig.MatchConfig{ + Include: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Strict), + Services: []string{"svcA", "svcB"}, + }, + Exclude: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Strict), + Attributes: []filterconfig.Attribute{ + {Key: "redact_trace", Value: false}, + }, + }, + }, + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "credit_card", Action: attraction.DELETE}, + {Key: "duplicate_key", Action: attraction.DELETE}, + }, + }, }, }, - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "credit_card", Action: attraction.DELETE}, - {Key: "duplicate_key", Action: attraction.DELETE}, + { + id: config.NewComponentIDWithName(typeStr, "complex"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "operation", Value: "default", Action: attraction.INSERT}, + {Key: "svc.operation", FromAttribute: "operation", Action: attraction.UPSERT}, + {Key: "operation", Action: attraction.DELETE}, + }, + }, }, }, - }) - - p7 := cfg.Processors[config.NewComponentIDWithName(typeStr, "selectiveprocessing")] - assert.Equal(t, p7, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "selectiveprocessing")), - MatchConfig: filterconfig.MatchConfig{ - Include: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Strict), - Services: []string{"svcA", "svcB"}, - }, - Exclude: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Strict), - Attributes: []filterconfig.Attribute{ - {Key: "redact_trace", Value: false}, + { + id: config.NewComponentIDWithName(typeStr, "example"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "db.table", Action: attraction.DELETE}, + {Key: "redacted_span", Value: true, Action: attraction.UPSERT}, + {Key: "copy_key", FromAttribute: "key_original", Action: attraction.UPDATE}, + {Key: "account_id", Value: 2245, Action: attraction.INSERT}, + {Key: "account_password", Action: attraction.DELETE}, + }, }, }, }, - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "credit_card", Action: attraction.DELETE}, - {Key: "duplicate_key", Action: attraction.DELETE}, + { + id: config.NewComponentIDWithName(typeStr, "regexp"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + MatchConfig: filterconfig.MatchConfig{ + Include: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Regexp), + Services: []string{"auth.*"}, + }, + Exclude: &filterconfig.MatchProperties{ + Config: *createConfig(filterset.Regexp), + SpanNames: []string{"login.*"}, + }, + }, + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "password", Action: attraction.UPDATE, Value: "obfuscated"}, + {Key: "token", Action: attraction.DELETE}, + }, + }, }, }, - }) - - p8 := cfg.Processors[config.NewComponentIDWithName(typeStr, "complex")] - assert.Equal(t, p8, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "complex")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "operation", Value: "default", Action: attraction.INSERT}, - {Key: "svc.operation", FromAttribute: "operation", Action: attraction.UPSERT}, - {Key: "operation", Action: attraction.DELETE}, + { + id: config.NewComponentIDWithName(typeStr, "convert"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Settings: attraction.Settings{ + Actions: []attraction.ActionKeyValue{ + {Key: "http.status_code", Action: attraction.CONVERT, ConvertedType: "int"}, + }, + }, }, }, - }) + } - p9 := cfg.Processors[config.NewComponentIDWithName(typeStr, "example")] - assert.Equal(t, p9, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "example")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "db.table", Action: attraction.DELETE}, - {Key: "redacted_span", Value: true, Action: attraction.UPSERT}, - {Key: "copy_key", FromAttribute: "key_original", Action: attraction.UPDATE}, - {Key: "account_id", Value: 2245, Action: attraction.INSERT}, - {Key: "account_password", Action: attraction.DELETE}, - }, - }, - }) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) - p10 := cfg.Processors[config.NewComponentIDWithName(typeStr, "regexp")] - assert.Equal(t, p10, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "regexp")), - MatchConfig: filterconfig.MatchConfig{ - Include: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Regexp), - Services: []string{"auth.*"}, - }, - Exclude: &filterconfig.MatchProperties{ - Config: *createConfig(filterset.Regexp), - SpanNames: []string{"login.*"}, - }, - }, - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "password", Action: attraction.UPDATE, Value: "obfuscated"}, - {Key: "token", Action: attraction.DELETE}, - }, - }, - }) + factory := NewFactory() + cfg := factory.CreateDefaultConfig() - p11 := cfg.Processors[config.NewComponentIDWithName(typeStr, "convert")] - assert.Equal(t, p11, &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "convert")), - Settings: attraction.Settings{ - Actions: []attraction.ActionKeyValue{ - {Key: "http.status_code", Action: attraction.CONVERT, ConvertedType: "int"}, - }, - }, - }) + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) + }) + } } diff --git a/processor/attributesprocessor/testdata/config.yaml b/processor/attributesprocessor/testdata/config.yaml index 708828e39361b..6ba4f89b639ad 100644 --- a/processor/attributesprocessor/testdata/config.yaml +++ b/processor/attributesprocessor/testdata/config.yaml @@ -1,372 +1,356 @@ -processors: - # The following example demonstrates inserting keys/values into spans. - attributes/insert: - actions: - # The following inserts a new attribute {"attribute1": 123} to spans where - # the key "attribute1" doesn't exist. - # The type of `attribute1` is inferred by the configuration. - # `123` is an integer and is stored as an integer in the attributes. - # This demonstrates how to backfill spans with an attribute that may - # not have been sent by all clients. - - key: "attribute1" - value: 123 - action: insert - # The following uses the value from attribute "anotherkey" to insert a new - # attribute {"string key": } to spans - # where the key "string key" does not exist. If the attribute "anotherkey" - # doesn't exist, no new attribute is inserted to spans. - - key: "string key" - from_attribute: "anotherkey" - action: insert - - # The following example demonstrates using regex to create new attributes - # based on the value of another attribute. - attributes/regex_insert: - actions: - # The following uses the value from `key:http.url` to upsert attributes - # to the target keys specified in the `rule`. - # (Insert attributes for target keys that do not exist and update keys - # that exist.) - # Given http.url = http://example.com/path?queryParam1=value1,queryParam2=value2 - # then the following attributes will be inserted: - # http_protocol: http - # http_domain: example.com - # http_path: path - # http_query_params=queryParam1=value1,queryParam2=value2 - # http.url value does NOT change. - # Note: Similar to the Span Procesor, if a target key already exists, - # it will be updated. - - key: "http.url" - pattern: ^(?P.*):\/\/(?P.*)\/(?P.*)(\?|\&)(?P.*) - action: extract - - # The following demonstrates configuring the processor to only update existing - # keys in an attribute. - # Note: `action: update` must be set. - attributes/update: - actions: - # The following updates the attribute 'boo' using the value from attribute - # 'foo'. Spans without the attribute 'boo' will not change. - - key: "boo" - from_attribute: "foo" - action: update - # The following updates the attribute to { "db.secret": "redacted"}. - # This demonstrates sanitizing spans of sensitive data. - - key: db.secret - value: redacted - action: update - - # The following demonstrates setting an attribute on both spans where the - # key does exist and the key doesn't exist. - attributes/upsert: - actions: - # The following demonstrates how to set an attribute on all spans. - # Any spans that already had `region` now have value `planet-earth`. - # This can be done to set properties for all traces without - # requiring an instrumentation change. - - key: region - value: "planet-earth" - action: upsert - - # The following demonstrates copying a value to a new key. - # Note: If a span doesn't contain `user_key`, no new attribute `new_user_key` - # is created. - - key: new_user_key - from_attribute: user_key - action: upsert - - # The following demonstrates deleting keys from an attribute. - attributes/delete: - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete - - # The following demonstrates hash existing attribute values. - attributes/hash: - actions: - - key: user.email - action: hash +# The following example demonstrates inserting keys/values into spans. +attributes/insert: + actions: + # The following inserts a new attribute {"attribute1": 123} to spans where + # the key "attribute1" doesn't exist. + # The type of `attribute1` is inferred by the configuration. + # `123` is an integer and is stored as an integer in the attributes. + # This demonstrates how to backfill spans with an attribute that may + # not have been sent by all clients. + - key: "attribute1" + value: 123 + action: insert + # The following uses the value from attribute "anotherkey" to insert a new + # attribute {"string key": } to spans + # where the key "string key" does not exist. If the attribute "anotherkey" + # doesn't exist, no new attribute is inserted to spans. + - key: "string key" + from_attribute: "anotherkey" + action: insert - # The following demonstrates converting the type of existing attribute values. - attributes/convert: - actions: - - key: http.status_code - action: convert - converted_type: int +# The following example demonstrates using regex to create new attributes +# based on the value of another attribute. +attributes/regex_insert: + actions: + # The following uses the value from `key:http.url` to upsert attributes + # to the target keys specified in the `rule`. + # (Insert attributes for target keys that do not exist and update keys + # that exist.) + # Given http.url = http://example.com/path?queryParam1=value1,queryParam2=value2 + # then the following attributes will be inserted: + # http_protocol: http + # http_domain: example.com + # http_path: path + # http_query_params=queryParam1=value1,queryParam2=value2 + # http.url value does NOT change. + # Note: Similar to the Span Procesor, if a target key already exists, + # it will be updated. + - key: "http.url" + pattern: ^(?P.*):\/\/(?P.*)\/(?P.*)(\?|\&)(?P.*) + action: extract +# The following demonstrates configuring the processor to only update existing +# keys in an attribute. +# Note: `action: update` must be set. +attributes/update: + actions: + # The following updates the attribute 'boo' using the value from attribute + # 'foo'. Spans without the attribute 'boo' will not change. + - key: "boo" + from_attribute: "foo" + action: update + # The following updates the attribute to { "db.secret": "redacted"}. + # This demonstrates sanitizing spans of sensitive data. + - key: db.secret + value: redacted + action: update - # The following demonstrates excluding spans from this attributes processor. - # Ex. The following spans match the properties and won't be processed by the - # processor. - # Span1 Name: 'svcB' Attributes: {env: dev, test_request: 123, credit_card: 1234} - # Span2 Name: 'svcA' Attributes: {env: dev, test_request: false} - # The following spans do not match the properties and the processor actions - # are applied to it. - # Span3 Name: 'svcB' Attributes: {env: 1, test_request: dev, credit_card: 1234} - # Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} - attributes/excludemulti: - # Specifies the spans properties that exclude a span from being processed. - exclude: - # match_type defines that "services" is an array of strings that must - # match service name strictly. - match_type: strict - # The Span service name must be equal to "svcA" or "svcB". - services: ["svcA", "svcB"] - attributes: - # This exact attribute ('env', 'dev') must exist in the span for a match. - - {key: env, value: "dev"} - # As long as there is an attribute with key 'test_request' in the span - # there is a match. - - {key: test_request} - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete +# The following demonstrates setting an attribute on both spans where the +# key does exist and the key doesn't exist. +attributes/upsert: + actions: + # The following demonstrates how to set an attribute on all spans. + # Any spans that already had `region` now have value `planet-earth`. + # This can be done to set properties for all traces without + # requiring an instrumentation change. + - key: region + value: "planet-earth" + action: upsert - # The following demonstrates excluding spans from this attributes processor based on a resource. - attributes/excluderesources: - # Specifies the spans properties that exclude a span from being processed. - exclude: - # match_type defines that "resources" is an map where values must match strictly. - match_type: strict - resources: - # This exact resource ('host.type', 'n1-standard-1') must exist in the span for a match. - - {key: host.type, value: "n1-standard-1"} - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete + # The following demonstrates copying a value to a new key. + # Note: If a span doesn't contain `user_key`, no new attribute `new_user_key` + # is created. + - key: new_user_key + from_attribute: user_key + action: upsert - # The following demonstrates excluding spans from this attributes processor based on an instrumenting library. - # If no version is provided, any version will match, even no version. - # If a blank version provided, only no version will match. - attributes/excludelibrary: - # Specifies the spans properties that exclude a span from being processed. - exclude: - # match_type defines that "libraries" is an map where values must match strictly. - match_type: strict - libraries: - # This exact library ('mongo-java-driver', version '3.8.0') must exist in the span for a match. - - {name: "mongo-java-driver", version: "3.8.0"} - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete +# The following demonstrates deleting keys from an attribute. +attributes/delete: + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete - # The following demonstrates including spans for this attributes processor. - # All other spans that do no match the properties are not processed - # by this processor. - # Ex. The following are spans match the properties and the actions are applied. - # Span1 Name: 'svcB' Attributes: {env: dev, test_request: 123, credit_card: 1234} - # Span2 Name: 'svcA' Attributes: {env: dev, test_request: false} - # Span3 Name: 'svcB' Attributes: {env: 1, test_request: dev, credit_card: 1234} - # The following span does not match the include properties and the - # processor actions are not applied. - # Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} - attributes/includeservices: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "services" is an array of regexp-es. - match_type: regexp - # The Span service name must match "auth.*" or "login.*" regexp. - services: ["auth.*", "login.*"] - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete +# The following demonstrates hash existing attribute values. +attributes/hash: + actions: + - key: user.email + action: hash - # The following demonstrates specifying the set of span properties to - # indicate which spans this processor should be applied to. The `include` of - # properties say which ones should be included and the `exclude` properties - # further filter out spans that shouldn't be processed. - # Ex. The following are spans match the properties and the actions are applied. - # Note this span is processed because the value type of redact_trace is a string instead of a boolean. - # Span1 Name: 'svcB' Attributes: {env: production, test_request: 123, credit_card: 1234, redact_trace: "false"} - # Span2 Name: 'svcA' Attributes: {env: staging, test_request: false, redact_trace: true} - # The following span does not match the include properties and the - # processor actions are not applied. - # Span3 Name: 'svcB' Attributes: {env: production, test_request: true, credit_card: 1234, redact_trace: false} - # Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} - attributes/selectiveprocessing: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "services" is an array of strings that must - # match service name strictly. - match_type: strict - # The Span service name must be equal to "svcA" or "svcB". - services: ["svcA", "svcB"] - exclude: - # match_type defines that "attributes" values must match strictly. - match_type: strict - attributes: - - { key: redact_trace, value: false} - actions: - - key: credit_card - action: delete - - key: duplicate_key - action: delete +# The following demonstrates converting the type of existing attribute values. +attributes/convert: + actions: + - key: http.status_code + action: convert + converted_type: int - # The following demonstrates how to backfill spans missing an attribute, - # insert/update that value to a new key and deleting the old key. This guarantees - # an attribute `svc.operation` exists in spans and the attribute `operation` - # doesn't exist. - # Ex: The spans before the processor `attributes/complex`. - # Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} - # Span2 Attributes: {operation: subtract, math_value: 123} - # Span3 Attributes: {timeout: 10, math_value: 4} - # Span4 Attributes: {svc.operation: division, timeout: 3} - attributes/complex: - # Note: There are no include and exclude settings so all spans are processed. - actions: - - key: operation - value: default - action: insert - # The spans after the first action of insert. - # Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} - # Span2 Attributes: {operation: subtract, math_value: 123} - # Span3 Attributes: {timeout: 10, math_value: 4, operation: default} - # Span4 Attributes: {svc.operation: division, timeout: 3, operation:default} - - key: svc.operation - from_attribute: operation - action: upsert - # The spans after the second action of upsert. - # Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} - # Span2 Attributes: {svc.operation: subtract, operation: subtract, math_value: 123} - # Span3 Attributes: {svc.operation: default, timeout: 10, math_value: 4, operation: default} - # Span4 Attributes: {svc.operation: default, timeout: 3, operation:default} +# The following demonstrates excluding spans from this attributes processor. +# Ex. The following spans match the properties and won't be processed by the +# processor. +# Span1 Name: 'svcB' Attributes: {env: dev, test_request: 123, credit_card: 1234} +# Span2 Name: 'svcA' Attributes: {env: dev, test_request: false} +# The following spans do not match the properties and the processor actions +# are applied to it. +# Span3 Name: 'svcB' Attributes: {env: 1, test_request: dev, credit_card: 1234} +# Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} +attributes/excludemulti: + # Specifies the spans properties that exclude a span from being processed. + exclude: + # match_type defines that "services" is an array of strings that must + # match service name strictly. + match_type: strict + # The Span service name must be equal to "svcA" or "svcB". + services: ["svcA", "svcB"] + attributes: + # This exact attribute ('env', 'dev') must exist in the span for a match. + - {key: env, value: "dev"} + # As long as there is an attribute with key 'test_request' in the span + # there is a match. + - {key: test_request} + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete - - key: operation - action: delete - # The spans after the third/final action of delete. - # Span1 Attributes: {timeout: 10, svc.operation: addition} - # Span2 Attributes: {svc.operation: subtract, math_value: 123} - # Span3 Attributes: {svc.operation: default, timeout: 10, math_value: 4} - # Span4 Attributes: {svc.operation: default, timeout: 3} +# The following demonstrates excluding spans from this attributes processor based on a resource. +attributes/excluderesources: + # Specifies the spans properties that exclude a span from being processed. + exclude: + # match_type defines that "resources" is an map where values must match strictly. + match_type: strict + resources: + # This exact resource ('host.type', 'n1-standard-1') must exist in the span for a match. + - {key: host.type, value: "n1-standard-1"} + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete - # The following is an example of various actions. The actions are applied in - # the order specified in the configuration. - attributes/example: - actions: - - key: db.table - action: delete - - key: redacted_span - value: true - action: upsert - - key: copy_key - from_attribute: key_original - action: update - - key: account_id - value: 2245 - action: insert - - key: account_password - action: delete +# The following demonstrates excluding spans from this attributes processor based on an instrumenting library. +# If no version is provided, any version will match, even no version. +# If a blank version provided, only no version will match. +attributes/excludelibrary: + # Specifies the spans properties that exclude a span from being processed. + exclude: + # match_type defines that "libraries" is an map where values must match strictly. + match_type: strict + libraries: + # This exact library ('mongo-java-driver', version '3.8.0') must exist in the span for a match. + - {name: "mongo-java-driver", version: "3.8.0"} + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete - # The following demonstrates how to process spans that have a service name and span - # name that match regexp patterns. This processor will remove "token" attribute - # and will obfuscate "password" attribute in spans where service name matches "auth.*" - # and where span name does not match "login.*". - attributes/regexp: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "services" is an array of regexp-es. - match_type: regexp - # The span service name must match "auth.*" pattern. - services: ["auth.*"] - exclude: - # match_type defines that "span_names" is an array of regexp-es. - match_type: regexp - # The span name must not match "login.*" pattern. - span_names: ["login.*"] - actions: - - key: password - action: update - value: "obfuscated" - - key: token - action: delete +# The following demonstrates including spans for this attributes processor. +# All other spans that do no match the properties are not processed +# by this processor. +# Ex. The following are spans match the properties and the actions are applied. +# Span1 Name: 'svcB' Attributes: {env: dev, test_request: 123, credit_card: 1234} +# Span2 Name: 'svcA' Attributes: {env: dev, test_request: false} +# Span3 Name: 'svcB' Attributes: {env: 1, test_request: dev, credit_card: 1234} +# The following span does not match the include properties and the +# processor actions are not applied. +# Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} +attributes/includeservices: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "services" is an array of regexp-es. + match_type: regexp + # The Span service name must match "auth.*" or "login.*" regexp. + services: ["auth.*", "login.*"] + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete - # The following demonstrates how to process spans that have an attribute that matches a regexp patterns. - # This processor will obfuscate "db.statement" attribute in spans where "db.statement attribute - # matches a regex pattern. - attributes/regexp2: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "attributes" is a map where values are regexp-es. - match_type: regexp - attributes: - # This attribute ('db.statement') must exist in the span and match the regex ('SELECT \* FROM USERS.*') for a match. - - {key: env, value: 'SELECT \* FROM USERS.*'} - actions: - - key: db.statement - action: update - value: "SELECT * FROM USERS [obfuscated]" +# The following demonstrates specifying the set of span properties to +# indicate which spans this processor should be applied to. The `include` of +# properties say which ones should be included and the `exclude` properties +# further filter out spans that shouldn't be processed. +# Ex. The following are spans match the properties and the actions are applied. +# Note this span is processed because the value type of redact_trace is a string instead of a boolean. +# Span1 Name: 'svcB' Attributes: {env: production, test_request: 123, credit_card: 1234, redact_trace: "false"} +# Span2 Name: 'svcA' Attributes: {env: staging, test_request: false, redact_trace: true} +# The following span does not match the include properties and the +# processor actions are not applied. +# Span3 Name: 'svcB' Attributes: {env: production, test_request: true, credit_card: 1234, redact_trace: false} +# Span4 Name: 'svcC' Attributes: {env: dev, test_request: false} +attributes/selectiveprocessing: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "services" is an array of strings that must + # match service name strictly. + match_type: strict + # The Span service name must be equal to "svcA" or "svcB". + services: ["svcA", "svcB"] + exclude: + # match_type defines that "attributes" values must match strictly. + match_type: strict + attributes: + - { key: redact_trace, value: false} + actions: + - key: credit_card + action: delete + - key: duplicate_key + action: delete +# The following demonstrates how to backfill spans missing an attribute, +# insert/update that value to a new key and deleting the old key. This guarantees +# an attribute `svc.operation` exists in spans and the attribute `operation` +# doesn't exist. +# Ex: The spans before the processor `attributes/complex`. +# Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} +# Span2 Attributes: {operation: subtract, math_value: 123} +# Span3 Attributes: {timeout: 10, math_value: 4} +# Span4 Attributes: {svc.operation: division, timeout: 3} +attributes/complex: + # Note: There are no include and exclude settings so all spans are processed. + actions: + - key: operation + value: default + action: insert + # The spans after the first action of insert. + # Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} + # Span2 Attributes: {operation: subtract, math_value: 123} + # Span3 Attributes: {timeout: 10, math_value: 4, operation: default} + # Span4 Attributes: {svc.operation: division, timeout: 3, operation:default} - # The following demonstrates how to process logs that have a body that match regexp - # patterns. This processor will remove "token" attribute and will obfuscate "password" - # attribute in spans where body matches "AUTH.*". - attributes/log_body_regexp: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "services" is an array of regexp-es. - match_type: regexp - # The span service name must match "auth.*" pattern. - log_bodies: ["AUTH.*"] - actions: - - key: password - action: update - value: "obfuscated" - - key: token - action: delete + - key: svc.operation + from_attribute: operation + action: upsert + # The spans after the second action of upsert. + # Span1 Attributes: {timeout: 10, svc.operation: addition, operation: addition} + # Span2 Attributes: {svc.operation: subtract, operation: subtract, math_value: 123} + # Span3 Attributes: {svc.operation: default, timeout: 10, math_value: 4, operation: default} + # Span4 Attributes: {svc.operation: default, timeout: 3, operation:default} - # The following demonstrates how to process logs that have a severity text that match regexp - # patterns. This processor will remove "token" attribute and will obfuscate "password" - # attribute in spans where severity matches "debug". - attributes/log_severity_regexp: - # Specifies the span properties that must exist for the processor to be applied. - include: - # match_type defines that "services" is an array of regexp-es. - match_type: regexp - # The log severity text "debug.*" pattern. - log_severity_texts: [ "debug.*" ] - actions: - - key: password - action: update - value: "obfuscated" - - key: token - action: delete + - key: operation + action: delete + # The spans after the third/final action of delete. + # Span1 Attributes: {timeout: 10, svc.operation: addition} + # Span2 Attributes: {svc.operation: subtract, math_value: 123} + # Span3 Attributes: {svc.operation: default, timeout: 10, math_value: 4} + # Span4 Attributes: {svc.operation: default, timeout: 3} - attributes/from_context: - actions: - - key: origin - from_context: metadata.origin - action: insert - - key: enduser.id - # The following uses `subject` attribute produced - # by the server authenticator from `oidc` extension - # to set the identity of an exporter on spans. - # Refer to the server authenticator's documentation part of your pipeline - # for more information about which attributes are available. - from_context: auth.subject +# The following is an example of various actions. The actions are applied in +# the order specified in the configuration. +attributes/example: + actions: + - key: db.table + action: delete + - key: redacted_span + value: true + action: upsert + - key: copy_key + from_attribute: key_original + action: update + - key: account_id + value: 2245 action: insert + - key: account_password + action: delete + +# The following demonstrates how to process spans that have a service name and span +# name that match regexp patterns. This processor will remove "token" attribute +# and will obfuscate "password" attribute in spans where service name matches "auth.*" +# and where span name does not match "login.*". +attributes/regexp: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "services" is an array of regexp-es. + match_type: regexp + # The span service name must match "auth.*" pattern. + services: ["auth.*"] + exclude: + # match_type defines that "span_names" is an array of regexp-es. + match_type: regexp + # The span name must not match "login.*" pattern. + span_names: ["login.*"] + actions: + - key: password + action: update + value: "obfuscated" + - key: token + action: delete -receivers: - nop: +# The following demonstrates how to process spans that have an attribute that matches a regexp patterns. +# This processor will obfuscate "db.statement" attribute in spans where "db.statement attribute +# matches a regex pattern. +attributes/regexp2: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "attributes" is a map where values are regexp-es. + match_type: regexp + attributes: + # This attribute ('db.statement') must exist in the span and match the regex ('SELECT \* FROM USERS.*') for a match. + - {key: env, value: 'SELECT \* FROM USERS.*'} + actions: + - key: db.statement + action: update + value: "SELECT * FROM USERS [obfuscated]" -exporters: - nop: -service: - pipelines: - traces: - receivers: [nop] - processors: [attributes/insert] - exporters: [nop] +# The following demonstrates how to process logs that have a body that match regexp +# patterns. This processor will remove "token" attribute and will obfuscate "password" +# attribute in spans where body matches "AUTH.*". +attributes/log_body_regexp: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "services" is an array of regexp-es. + match_type: regexp + # The span service name must match "auth.*" pattern. + log_bodies: ["AUTH.*"] + actions: + - key: password + action: update + value: "obfuscated" + - key: token + action: delete +# The following demonstrates how to process logs that have a severity text that match regexp +# patterns. This processor will remove "token" attribute and will obfuscate "password" +# attribute in spans where severity matches "debug". +attributes/log_severity_regexp: + # Specifies the span properties that must exist for the processor to be applied. + include: + # match_type defines that "services" is an array of regexp-es. + match_type: regexp + # The log severity text "debug.*" pattern. + log_severity_texts: [ "debug.*" ] + actions: + - key: password + action: update + value: "obfuscated" + - key: token + action: delete +attributes/from_context: + actions: + - key: origin + from_context: metadata.origin + action: insert + - key: enduser.id + # The following uses `subject` attribute produced + # by the server authenticator from `oidc` extension + # to set the identity of an exporter on spans. + # Refer to the server authenticator's documentation part of your pipeline + # for more information about which attributes are available. + from_context: auth.subject + action: insert diff --git a/processor/cumulativetodeltaprocessor/config_test.go b/processor/cumulativetodeltaprocessor/config_test.go index 972bf1c2a158f..51518f795df6d 100644 --- a/processor/cumulativetodeltaprocessor/config_test.go +++ b/processor/cumulativetodeltaprocessor/config_test.go @@ -15,38 +15,30 @@ package cumulativetodeltaprocessor import ( - "fmt" "path/filepath" "testing" "time" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/service/servicetest" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterset" ) -const configFile = "config.yaml" - -func TestLoadingFullConfig(t *testing.T) { - - factories, err := componenttest.NopFactories() - assert.NoError(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", configFile), factories) - assert.NoError(t, err) - require.NotNil(t, cfg) +func TestLoadConfig(t *testing.T) { + t.Parallel() tests := []struct { - expCfg *Config + id config.ComponentID + expected config.Processor + errorMessage string }{ { - expCfg: &Config{ + id: config.NewComponentIDWithName(typeStr, ""), + expected: &Config{ ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Include: MatchMetrics{ Metrics: []string{ @@ -71,60 +63,63 @@ func TestLoadingFullConfig(t *testing.T) { MaxStaleness: 10 * time.Second, }, }, - } - - for _, test := range tests { - t.Run(test.expCfg.ID().String(), func(t *testing.T) { - cfg := cfg.Processors[test.expCfg.ID()] - assert.Equal(t, test.expCfg, cfg) - }) - } -} - -func TestValidateConfig(t *testing.T) { - tests := []struct { - configName string - succeed bool - errorMessage string - }{ - { - configName: "config.yaml", - succeed: true, - }, { - configName: "config_missing_match_type.yaml", - succeed: false, - errorMessage: "match_type must be set if metrics are supplied", + id: config.NewComponentIDWithName(typeStr, "empty"), + expected: createDefaultConfig(), }, { - configName: "config_missing_name.yaml", - succeed: false, - errorMessage: "metrics must be supplied if match_type is set", + id: config.NewComponentIDWithName(typeStr, "regexp"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + Include: MatchMetrics{ + Metrics: []string{ + "a*", + }, + Config: filterset.Config{ + MatchType: "regexp", + RegexpConfig: nil, + }, + }, + Exclude: MatchMetrics{ + Metrics: []string{ + "b*", + }, + Config: filterset.Config{ + MatchType: "regexp", + RegexpConfig: nil, + }, + }, + MaxStaleness: 10 * time.Second, + }, }, { - configName: "config_empty.yaml", - succeed: true, + id: config.NewComponentIDWithName(typeStr, "missing_match_type"), + errorMessage: "match_type must be set if metrics are supplied", }, { - configName: "config_regexp.yaml", - succeed: true, + id: config.NewComponentIDWithName(typeStr, "missing_name"), + errorMessage: "metrics must be supplied if match_type is set", }, } - for _, test := range tests { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) - factory := NewFactory() - factories.Processors[typeStr] = factory - t.Run(test.configName, func(t *testing.T) { - config, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configName), factories) - if test.succeed { - assert.NotNil(t, config) - assert.NoError(t, err) - } else { - assert.EqualError(t, err, fmt.Sprintf("processor %q has invalid configuration: %s", typeStr, test.errorMessage)) + if tt.expected == nil { + assert.EqualError(t, cfg.Validate(), tt.errorMessage) + return } + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } diff --git a/processor/cumulativetodeltaprocessor/factory_test.go b/processor/cumulativetodeltaprocessor/factory_test.go index 999fb7b54e173..0971821338f21 100644 --- a/processor/cumulativetodeltaprocessor/factory_test.go +++ b/processor/cumulativetodeltaprocessor/factory_test.go @@ -16,16 +16,17 @@ package cumulativetodeltaprocessor import ( "context" - "fmt" "path/filepath" "testing" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configtest" "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/service/servicetest" ) func TestType(t *testing.T) { @@ -44,49 +45,37 @@ func TestCreateDefaultConfig(t *testing.T) { } func TestCreateProcessors(t *testing.T) { - tests := []struct { - configName string - succeed bool - errorMessage string - }{ - { - configName: "config.yaml", - succeed: true, - }, - } + t.Parallel() + + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) - for _, test := range tests { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) + for k := range cm.ToStringMap() { + // Check if all processor variations that are defined in test config can be actually created + t.Run(k, func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() - factory := NewFactory() - factories.Processors[typeStr] = factory - config, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configName), factories) - assert.NoError(t, err) + sub, err := cm.Sub(k) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) - for name, cfg := range config.Processors { - t.Run(fmt.Sprintf("%s/%s", test.configName, name), func(t *testing.T) { - tp, tErr := factory.CreateTracesProcessor( - context.Background(), - componenttest.NewNopProcessorCreateSettings(), - cfg, - consumertest.NewNop()) - // Not implemented error - assert.Error(t, tErr) - assert.Nil(t, tp) + tp, tErr := factory.CreateTracesProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, + consumertest.NewNop()) + // Not implemented error + assert.Error(t, tErr) + assert.Nil(t, tp) - mp, mErr := factory.CreateMetricsProcessor( - context.Background(), - componenttest.NewNopProcessorCreateSettings(), - cfg, - consumertest.NewNop()) - if test.succeed { - assert.NotNil(t, mp) - assert.NoError(t, mErr) - } else { - assert.EqualError(t, mErr, test.errorMessage) - } - }) - } + mp, mErr := factory.CreateMetricsProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, + consumertest.NewNop()) + assert.NotNil(t, mp) + assert.NoError(t, mErr) + }) } } diff --git a/processor/cumulativetodeltaprocessor/testdata/config.yaml b/processor/cumulativetodeltaprocessor/testdata/config.yaml index 9702899cd8ec6..0aee18aa41b36 100644 --- a/processor/cumulativetodeltaprocessor/testdata/config.yaml +++ b/processor/cumulativetodeltaprocessor/testdata/config.yaml @@ -1,30 +1,43 @@ -receivers: - nop: +cumulativetodelta: + include: + match_type: strict + metrics: + - metric1 + - metric2 + exclude: + match_type: strict + metrics: + - metric3 + - metric4 + max_staleness: 10s -processors: - cumulativetodelta: - include: - match_type: strict - metrics: - - metric1 - - metric2 - exclude: - match_type: strict - metrics: - - metric3 - - metric4 - max_staleness: 10s +cumulativetodelta/empty: -exporters: - nop: +cumulativetodelta/missing_match_type: + include: + metrics: + - metric1 + - metric2 + exclude: + metrics: + - metric3 + - metric4 -service: - pipelines: - traces: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] - metrics: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] +cumulativetodelta/missing_name: + include: + match_type: strict + metrics: + exclude: + match_type: strict + metrics: + +cumulativetodelta/regexp: + include: + match_type: regexp + metrics: + - a* + exclude: + match_type: regexp + metrics: + - b* + max_staleness: 10s diff --git a/processor/cumulativetodeltaprocessor/testdata/config_empty.yaml b/processor/cumulativetodeltaprocessor/testdata/config_empty.yaml deleted file mode 100644 index 58677622fc7a5..0000000000000 --- a/processor/cumulativetodeltaprocessor/testdata/config_empty.yaml +++ /dev/null @@ -1,19 +0,0 @@ -receivers: - nop: - -processors: - cumulativetodelta: - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] - metrics: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] diff --git a/processor/cumulativetodeltaprocessor/testdata/config_missing_match_type.yaml b/processor/cumulativetodeltaprocessor/testdata/config_missing_match_type.yaml deleted file mode 100644 index ee26380877a34..0000000000000 --- a/processor/cumulativetodeltaprocessor/testdata/config_missing_match_type.yaml +++ /dev/null @@ -1,27 +0,0 @@ -receivers: - nop: - -processors: - cumulativetodelta: - include: - metrics: - - metric1 - - metric2 - exclude: - metrics: - - metric3 - - metric4 - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] - metrics: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] diff --git a/processor/cumulativetodeltaprocessor/testdata/config_missing_name.yaml b/processor/cumulativetodeltaprocessor/testdata/config_missing_name.yaml deleted file mode 100644 index 9f22aeb04f13a..0000000000000 --- a/processor/cumulativetodeltaprocessor/testdata/config_missing_name.yaml +++ /dev/null @@ -1,25 +0,0 @@ -receivers: - nop: - -processors: - cumulativetodelta: - include: - match_type: strict - metrics: - exclude: - match_type: strict - metrics: - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] - metrics: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] diff --git a/processor/cumulativetodeltaprocessor/testdata/config_regexp.yaml b/processor/cumulativetodeltaprocessor/testdata/config_regexp.yaml deleted file mode 100644 index fefc7f6527094..0000000000000 --- a/processor/cumulativetodeltaprocessor/testdata/config_regexp.yaml +++ /dev/null @@ -1,28 +0,0 @@ -receivers: - nop: - -processors: - cumulativetodelta: - include: - match_type: regexp - metrics: - - a* - exclude: - match_type: regexp - metrics: - - b* - max_staleness: 10s - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] - metrics: - receivers: [nop] - processors: [cumulativetodelta] - exporters: [nop] diff --git a/processor/deltatorateprocessor/config_test.go b/processor/deltatorateprocessor/config_test.go index 81c3e45aa267e..d0c5a7d4ffbfe 100644 --- a/processor/deltatorateprocessor/config_test.go +++ b/processor/deltatorateprocessor/config_test.go @@ -15,25 +15,27 @@ package deltatorateprocessor import ( - "fmt" "path/filepath" "testing" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/service/servicetest" ) -func TestLoadingFullConfig(t *testing.T) { +func TestLoadConfig(t *testing.T) { + t.Parallel() + tests := []struct { - configFile string - expCfg *Config + id config.ComponentID + expected config.Processor + errorMessage string }{ { - configFile: "config_full.yaml", - expCfg: &Config{ + id: config.NewComponentIDWithName(typeStr, ""), + expected: &Config{ ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: []string{ "metric1", @@ -41,57 +43,30 @@ func TestLoadingFullConfig(t *testing.T) { }, }, }, - } - - for _, test := range tests { - t.Run(test.expCfg.ID().String(), func(t *testing.T) { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - config, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configFile), factories) - assert.NoError(t, err) - require.NotNil(t, config) - - cfg := config.Processors[test.expCfg.ID()] - assert.Equal(t, test.expCfg, cfg) - }) - } -} - -func TestValidateConfig(t *testing.T) { - tests := []struct { - configName string - succeed bool - errorMessage string - }{ - { - configName: "config_full.yaml", - succeed: true, - }, { - configName: "config_missing_name.yaml", - succeed: false, + id: config.NewComponentIDWithName(typeStr, "missing_name"), errorMessage: "metric names are missing", }, } - for _, test := range tests { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + + factory := NewFactory() + cfg := factory.CreateDefaultConfig() - factory := NewFactory() - factories.Processors[typeStr] = factory - t.Run(test.configName, func(t *testing.T) { - config, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configName), factories) - if test.succeed { - assert.NotNil(t, config) - assert.NoError(t, err) - } else { - assert.EqualError(t, err, fmt.Sprintf("processor %q has invalid configuration: %s", typeStr, test.errorMessage)) + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + if tt.expected == nil { + assert.EqualError(t, cfg.Validate(), tt.errorMessage) + return } + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) - } } diff --git a/processor/deltatorateprocessor/factory_test.go b/processor/deltatorateprocessor/factory_test.go index d622974fa3578..baa6aeb094a7e 100644 --- a/processor/deltatorateprocessor/factory_test.go +++ b/processor/deltatorateprocessor/factory_test.go @@ -16,16 +16,17 @@ package deltatorateprocessor import ( "context" - "fmt" "path/filepath" "testing" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configtest" "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/service/servicetest" ) func TestType(t *testing.T) { @@ -44,49 +45,37 @@ func TestCreateDefaultConfig(t *testing.T) { } func TestCreateProcessors(t *testing.T) { - tests := []struct { - configName string - succeed bool - errorMessage string - }{ - { - configName: "config_full.yaml", - succeed: true, - }, - } + t.Parallel() + + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) - for _, test := range tests { - factories, err := componenttest.NopFactories() - assert.NoError(t, err) + for k := range cm.ToStringMap() { + // Check if all processor variations that are defined in test config can be actually created + t.Run(k, func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() - factory := NewFactory() - factories.Processors[typeStr] = factory - config, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configName), factories) - assert.NoError(t, err) + sub, err := cm.Sub(k) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) - for name, cfg := range config.Processors { - t.Run(fmt.Sprintf("%s/%s", test.configName, name), func(t *testing.T) { - tp, tErr := factory.CreateTracesProcessor( - context.Background(), - componenttest.NewNopProcessorCreateSettings(), - cfg, - consumertest.NewNop()) - // Not implemented error - assert.Error(t, tErr) - assert.Nil(t, tp) + tp, tErr := factory.CreateTracesProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, + consumertest.NewNop()) + // Not implemented error + assert.Error(t, tErr) + assert.Nil(t, tp) - mp, mErr := factory.CreateMetricsProcessor( - context.Background(), - componenttest.NewNopProcessorCreateSettings(), - cfg, - consumertest.NewNop()) - if test.succeed { - assert.NotNil(t, mp) - assert.NoError(t, mErr) - } else { - assert.EqualError(t, mErr, test.errorMessage) - } - }) - } + mp, mErr := factory.CreateMetricsProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, + consumertest.NewNop()) + assert.NotNil(t, mp) + assert.NoError(t, mErr) + }) } } diff --git a/processor/deltatorateprocessor/testdata/config.yaml b/processor/deltatorateprocessor/testdata/config.yaml new file mode 100644 index 0000000000000..e51bd663e9617 --- /dev/null +++ b/processor/deltatorateprocessor/testdata/config.yaml @@ -0,0 +1,7 @@ +deltatorate: + metrics: + - metric1 + - metric2 + +deltatorate/missing_name: + metrics: diff --git a/processor/deltatorateprocessor/testdata/config_full.yaml b/processor/deltatorateprocessor/testdata/config_full.yaml deleted file mode 100644 index dfe090ea60c33..0000000000000 --- a/processor/deltatorateprocessor/testdata/config_full.yaml +++ /dev/null @@ -1,22 +0,0 @@ -receivers: - nop: - -processors: - deltatorate: - metrics: - - metric1 - - metric2 - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [deltatorate] - exporters: [nop] - metrics: - receivers: [nop] - processors: [deltatorate] - exporters: [nop] diff --git a/processor/deltatorateprocessor/testdata/config_missing_name.yaml b/processor/deltatorateprocessor/testdata/config_missing_name.yaml deleted file mode 100644 index 126f011a49579..0000000000000 --- a/processor/deltatorateprocessor/testdata/config_missing_name.yaml +++ /dev/null @@ -1,20 +0,0 @@ -receivers: - nop: - -processors: - deltatorate: - metrics: - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [deltatorate] - exporters: [nop] - metrics: - receivers: [nop] - processors: [deltatorate] - exporters: [nop] diff --git a/processor/filterprocessor/config_test.go b/processor/filterprocessor/config_test.go index 61747319bb44f..ae5ecfda524f2 100644 --- a/processor/filterprocessor/config_test.go +++ b/processor/filterprocessor/config_test.go @@ -15,16 +15,15 @@ package filterprocessor import ( - "path" "path/filepath" "testing" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/pdata/plog" - "go.opentelemetry.io/collector/service/servicetest" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filterconfig" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/processor/filtermetric" @@ -44,25 +43,17 @@ func TestLoadingConfigStrict(t *testing.T) { MatchType: filtermetric.Strict, MetricNames: testDataFilters, } - - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_strict.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_strict.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "empty"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "empty")), + id: config.NewComponentIDWithName("filter", "empty"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: &filtermetric.MatchProperties{ MatchType: filtermetric.Strict, @@ -70,25 +61,25 @@ func TestLoadingConfigStrict(t *testing.T) { }, }, }, { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: testDataMetricProperties, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Exclude: testDataMetricProperties, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: testDataMetricProperties, Exclude: &filtermetric.MatchProperties{ @@ -100,10 +91,17 @@ func TestLoadingConfigStrict(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -131,24 +129,17 @@ func TestLoadingConfigStrictLogs(t *testing.T) { }, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_strict.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_strict.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "empty"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "empty")), + id: config.NewComponentIDWithName("filter", "empty"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: &LogMatchProperties{ LogMatchType: Strict, @@ -156,25 +147,25 @@ func TestLoadingConfigStrictLogs(t *testing.T) { }, }, }, { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -183,10 +174,17 @@ func TestLoadingConfigStrictLogs(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -204,40 +202,33 @@ func TestLoadingConfigSeverityLogsStrict(t *testing.T) { SeverityTexts: []string{"DEBUG", "DEBUG2", "DEBUG3", "DEBUG4"}, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_severity_strict.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_severity_strict.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -246,10 +237,17 @@ func TestLoadingConfigSeverityLogsStrict(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -266,40 +264,33 @@ func TestLoadingConfigSeverityLogsRegexp(t *testing.T) { SeverityTexts: []string{"DEBUG[2-4]?"}, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_severity_regexp.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_severity_regexp.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -308,10 +299,17 @@ func TestLoadingConfigSeverityLogsRegexp(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -329,40 +327,33 @@ func TestLoadingConfigBodyLogsStrict(t *testing.T) { LogBodies: []string{"This event is not important"}, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_body_strict.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_body_strict.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -371,10 +362,17 @@ func TestLoadingConfigBodyLogsStrict(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -392,40 +390,33 @@ func TestLoadingConfigBodyLogsRegexp(t *testing.T) { LogBodies: []string{"^MINOR:"}, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_body_regexp.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_body_regexp.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -434,10 +425,17 @@ func TestLoadingConfigBodyLogsRegexp(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -457,40 +455,33 @@ func TestLoadingConfigMinSeverityNumberLogs(t *testing.T) { }, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_logs_min_severity.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_logs_min_severity.yaml")) + require.NoError(t, err) tests := []struct { - filterID config.ComponentID - expCfg *Config + id config.ComponentID + expected *Config }{ { - filterID: config.NewComponentIDWithName("filter", "include"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "exclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Exclude: testDataLogPropertiesExclude, }, }, }, { - filterID: config.NewComponentIDWithName("filter", "includeexclude"), - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Logs: LogFilters{ Include: testDataLogPropertiesInclude, Exclude: testDataLogPropertiesExclude, @@ -499,11 +490,17 @@ func TestLoadingConfigMinSeverityNumberLogs(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.filterID.String(), func(t *testing.T) { - cfg := cfg.Processors[test.filterID] - assert.Equal(t, test.expCfg, cfg) - assert.NoError(t, test.expCfg.Validate(), "Failed to validate config") + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } @@ -527,36 +524,33 @@ func TestLoadingConfigRegexp(t *testing.T) { MetricNames: testDataFilters, } - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_regexp.yaml"), factories) - - assert.Nil(t, err) - require.NotNil(t, cfg) + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_regexp.yaml")) + require.NoError(t, err) tests := []struct { - expCfg *Config + id config.ComponentID + expected config.Processor }{ { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: testDataMetricProperties, }, }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Exclude: testDataMetricProperties, }, }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "unlimitedcache")), + id: config.NewComponentIDWithName("filter", "unlimitedcache"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: &filtermetric.MatchProperties{ MatchType: filtermetric.Regexp, @@ -568,8 +562,9 @@ func TestLoadingConfigRegexp(t *testing.T) { }, }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "limitedcache")), + id: config.NewComponentIDWithName("filter", "limitedcache"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Exclude: &filtermetric.MatchProperties{ MatchType: filtermetric.Regexp, @@ -584,29 +579,33 @@ func TestLoadingConfigRegexp(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.expCfg.ID().String(), func(t *testing.T) { - cfg := cfg.Processors[test.expCfg.ID()] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } func TestLoadingSpans(t *testing.T) { - factories, err := componenttest.NopFactories() + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_traces.yaml")) require.NoError(t, err) - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(path.Join(".", "testdata", "config_traces.yaml"), factories) - require.NoError(t, err) - require.NotNil(t, cfg) tests := []struct { - expCfg config.Processor + id config.ComponentID + expected config.Processor }{ { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "spans")), + id: config.NewComponentIDWithName("filter", "spans"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Spans: SpanFilters{ Include: &filterconfig.MatchProperties{ Config: filterset.Config{ @@ -630,29 +629,33 @@ func TestLoadingSpans(t *testing.T) { }, } - for _, test := range tests { - t.Run(test.expCfg.ID().String(), func(t *testing.T) { - cfg := cfg.Processors[test.expCfg.ID()] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } func TestLoadingConfigExpr(t *testing.T) { - factories, err := componenttest.NopFactories() + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config_expr.yaml")) require.NoError(t, err) - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config_expr.yaml"), factories) - require.NoError(t, err) - require.NotNil(t, cfg) tests := []struct { - expCfg config.Processor + id config.ComponentID + expected config.Processor }{ { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "empty")), + id: config.NewComponentIDWithName("filter", "empty"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: &filtermetric.MatchProperties{ MatchType: filtermetric.Expr, @@ -661,8 +664,9 @@ func TestLoadingConfigExpr(t *testing.T) { }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "include")), + id: config.NewComponentIDWithName("filter", "include"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: &filtermetric.MatchProperties{ MatchType: filtermetric.Expr, @@ -675,8 +679,9 @@ func TestLoadingConfigExpr(t *testing.T) { }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "exclude")), + id: config.NewComponentIDWithName("filter", "exclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Exclude: &filtermetric.MatchProperties{ MatchType: filtermetric.Expr, @@ -689,8 +694,9 @@ func TestLoadingConfigExpr(t *testing.T) { }, }, { - expCfg: &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "includeexclude")), + id: config.NewComponentIDWithName("filter", "includeexclude"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), Metrics: MetricFilters{ Include: &filtermetric.MatchProperties{ MatchType: filtermetric.Expr, @@ -708,10 +714,17 @@ func TestLoadingConfigExpr(t *testing.T) { }, }, } - for _, test := range tests { - t.Run(test.expCfg.ID().String(), func(t *testing.T) { - cfg := cfg.Processors[test.expCfg.ID()] - assert.Equal(t, test.expCfg, cfg) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) } } diff --git a/processor/filterprocessor/factory_test.go b/processor/filterprocessor/factory_test.go index 8e678aab61606..bc52725d9ad0d 100644 --- a/processor/filterprocessor/factory_test.go +++ b/processor/filterprocessor/factory_test.go @@ -16,17 +16,18 @@ package filterprocessor import ( "context" - "fmt" "path/filepath" "strings" "testing" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configtest" "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/service/servicetest" ) func TestType(t *testing.T) { @@ -46,6 +47,8 @@ func TestCreateDefaultConfig(t *testing.T) { } func TestCreateProcessors(t *testing.T) { + t.Parallel() + tests := []struct { configName string succeed bool @@ -80,24 +83,34 @@ func TestCreateProcessors(t *testing.T) { }, } - for _, test := range tests { - factories, err := componenttest.NopFactories() - assert.Nil(t, err) - - factory := NewFactory() - factories.Processors[typeStr] = factory - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", test.configName), factories) - assert.Nil(t, err) + for _, tt := range tests { + t.Run(tt.configName, func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", tt.configName)) + require.NoError(t, err) - for name, cfg := range cfg.Processors { - t.Run(fmt.Sprintf("%s/%s", test.configName, name), func(t *testing.T) { + for k := range cm.ToStringMap() { + // Check if all processor variations that are defined in test config can be actually created factory := NewFactory() + cfg := factory.CreateDefaultConfig() - tp, tErr := factory.CreateTracesProcessor(context.Background(), componenttest.NewNopProcessorCreateSettings(), cfg, consumertest.NewNop()) - mp, mErr := factory.CreateMetricsProcessor(context.Background(), componenttest.NewNopProcessorCreateSettings(), cfg, consumertest.NewNop()) - if strings.Contains(test.configName, "traces") { - assert.Equal(t, test.succeed, tp != nil) - assert.Equal(t, test.succeed, tErr == nil) + sub, err := cm.Sub(k) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) + + tp, tErr := factory.CreateTracesProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, consumertest.NewNop(), + ) + mp, mErr := factory.CreateMetricsProcessor( + context.Background(), + componenttest.NewNopProcessorCreateSettings(), + cfg, + consumertest.NewNop(), + ) + if strings.Contains(tt.configName, "traces") { + assert.Equal(t, tt.succeed, tp != nil) + assert.Equal(t, tt.succeed, tErr == nil) assert.NotNil(t, mp) assert.Nil(t, mErr) @@ -106,11 +119,10 @@ func TestCreateProcessors(t *testing.T) { assert.NotNil(t, tp) assert.Nil(t, tErr) - assert.Equal(t, test.succeed, mp != nil) - assert.Equal(t, test.succeed, mErr == nil) + assert.Equal(t, tt.succeed, mp != nil) + assert.Equal(t, tt.succeed, mErr == nil) } - - }) - } + } + }) } } diff --git a/processor/filterprocessor/testdata/config_expr.yaml b/processor/filterprocessor/testdata/config_expr.yaml index 4a36657d645d8..c342f2144c2a0 100644 --- a/processor/filterprocessor/testdata/config_expr.yaml +++ b/processor/filterprocessor/testdata/config_expr.yaml @@ -1,41 +1,28 @@ -receivers: - nop: - -processors: - filter/empty: - metrics: - include: - match_type: expr - filter/include: - metrics: - include: - match_type: expr - expressions: - - Label("foo") == "bar" - - HasLabel("baz") - filter/exclude: - metrics: - exclude: - match_type: expr - expressions: - - Label("foo") == "bar" - - HasLabel("baz") - filter/includeexclude: - metrics: - include: - match_type: expr - expressions: - - HasLabel("foo") - exclude: - match_type: expr - expressions: - - HasLabel("bar") -exporters: - nop: - -service: - pipelines: - metrics: - receivers: [nop] - processors: [filter/empty] - exporters: [nop] +filter/empty: + metrics: + include: + match_type: expr +filter/include: + metrics: + include: + match_type: expr + expressions: + - Label("foo") == "bar" + - HasLabel("baz") +filter/exclude: + metrics: + exclude: + match_type: expr + expressions: + - Label("foo") == "bar" + - HasLabel("baz") +filter/includeexclude: + metrics: + include: + match_type: expr + expressions: + - HasLabel("foo") + exclude: + match_type: expr + expressions: + - HasLabel("bar") diff --git a/processor/filterprocessor/testdata/config_invalid.yaml b/processor/filterprocessor/testdata/config_invalid.yaml index 0c4b087bd3009..b67b85e2a60d9 100644 --- a/processor/filterprocessor/testdata/config_invalid.yaml +++ b/processor/filterprocessor/testdata/config_invalid.yaml @@ -1,26 +1,9 @@ -receivers: - nop: +filter/include: + # any names NOT matching filters are excluded from remainder of pipeline + metrics: + include: + match_type: regexp + metric_names: + # re2 regexp patterns + - (\W|^)stock\stips(\W|$ -processors: - filter/include: - # any names NOT matching filters are excluded from remainder of pipeline - metrics: - include: - match_type: regexp - metric_names: - # re2 regexp patterns - - (\W|^)stock\stips(\W|$ - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/include] - exporters: [nop] - metrics: - receivers: [nop] - processors: [filter/include] - exporters: [nop] diff --git a/processor/filterprocessor/testdata/config_logs_body_regexp.yaml b/processor/filterprocessor/testdata/config_logs_body_regexp.yaml index a6b6c15f63932..5cfe244b2eb3b 100644 --- a/processor/filterprocessor/testdata/config_logs_body_regexp.yaml +++ b/processor/filterprocessor/testdata/config_logs_body_regexp.yaml @@ -1,42 +1,29 @@ -receivers: - nop: +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: regexp + bodies: + - "^IMPORTANT:" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: regexp + bodies: + - "^MINOR:" -processors: - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: regexp - bodies: - - "^IMPORTANT:" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: regexp - bodies: - - "^MINOR:" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with bodies starting with "IMPORTANT:" + include: + match_type: regexp + bodies: + - "^IMPORTANT:" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with bodies starting with "IMPORTANT:" - include: - match_type: regexp - bodies: - - "^IMPORTANT:" + exclude: + match_type: regexp + bodies: + - "^MINOR:" - exclude: - match_type: regexp - bodies: - - "^MINOR:" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] diff --git a/processor/filterprocessor/testdata/config_logs_body_strict.yaml b/processor/filterprocessor/testdata/config_logs_body_strict.yaml index b3339e3595a4e..62f1921f39fa9 100644 --- a/processor/filterprocessor/testdata/config_logs_body_strict.yaml +++ b/processor/filterprocessor/testdata/config_logs_body_strict.yaml @@ -1,42 +1,28 @@ -receivers: - nop: +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: strict + bodies: + - "This is an important event" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: strict + bodies: + - "This event is not important" -processors: - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: strict - bodies: - - "This is an important event" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: strict - bodies: - - "This event is not important" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with bodies that exactly match "This is an important event" + include: + match_type: strict + bodies: + - "This is an important event" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with bodies that exactly match "This is an important event" - include: - match_type: strict - bodies: - - "This is an important event" - - exclude: - match_type: strict - bodies: - - "This event is not important" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] + exclude: + match_type: strict + bodies: + - "This event is not important" diff --git a/processor/filterprocessor/testdata/config_logs_min_severity.yaml b/processor/filterprocessor/testdata/config_logs_min_severity.yaml index f7ae58e36e001..af79b869db11f 100644 --- a/processor/filterprocessor/testdata/config_logs_min_severity.yaml +++ b/processor/filterprocessor/testdata/config_logs_min_severity.yaml @@ -1,44 +1,30 @@ -receivers: - nop: +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + # This filters out all logs below "INFO" level (the whole DEBUG and TRACE ranges) + # Logs with no defined severity will also be matched. + include: + severity_number: + min: "INFO" + match_undefined: true +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + # This will filter out the "ERROR" and "FATAL" ranges + exclude: + severity_number: + min: "ERROR" -processors: - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - # This filters out all logs below "INFO" level (the whole DEBUG and TRACE ranges) - # Logs with no defined severity will also be matched. - include: - severity_number: - min: "INFO" - match_undefined: true - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - # This will filter out the "ERROR" and "FATAL" ranges - exclude: - severity_number: - min: "ERROR" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following will only allow records with severity in the "INFO" and "WARN" ranges to pass, + # as well as logs with undefined severity + include: + severity_number: + min: "INFO" + match_undefined: true - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following will only allow records with severity in the "INFO" and "WARN" ranges to pass, - # as well as logs with undefined severity - include: - severity_number: - min: "INFO" - match_undefined: true - - exclude: - severity_number: - min: "ERROR" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] + exclude: + severity_number: + min: "ERROR" diff --git a/processor/filterprocessor/testdata/config_logs_record_attributes_regexp.yaml b/processor/filterprocessor/testdata/config_logs_record_attributes_regexp.yaml index a64ea2974ad2d..f341da990422e 100644 --- a/processor/filterprocessor/testdata/config_logs_record_attributes_regexp.yaml +++ b/processor/filterprocessor/testdata/config_logs_record_attributes_regexp.yaml @@ -1,49 +1,36 @@ -receivers: - nop: +filter/empty: + logs: + include: + match_type: regexp +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: regexp + record_attributes: + - key: host.name + value: "(host1|mycustomhost2)" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: regexp + record_attributes: + - key: host.name + value: banned_host_.* +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with resource attributes + # "should_include" to pass through + include: + match_type: regexp + record_attributes: + - key: should_include + value: "(true|probably_true)" + exclude: + match_type: regexp + record_attributes: + - key: should_exclude + value: "(probably_false|false)" -processors: - filter/empty: - logs: - include: - match_type: regexp - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: regexp - record_attributes: - - key: host.name - value: "(host1|mycustomhost2)" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: regexp - record_attributes: - - key: host.name - value: banned_host_.* - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with resource attributes - # "should_include" to pass through - include: - match_type: regexp - record_attributes: - - key: should_include - value: "(true|probably_true)" - exclude: - match_type: regexp - record_attributes: - - key: should_exclude - value: "(probably_false|false)" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/empty, filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] diff --git a/processor/filterprocessor/testdata/config_logs_record_attributes_strict.yaml b/processor/filterprocessor/testdata/config_logs_record_attributes_strict.yaml index 10a3869143dc0..4e818ad2f2231 100644 --- a/processor/filterprocessor/testdata/config_logs_record_attributes_strict.yaml +++ b/processor/filterprocessor/testdata/config_logs_record_attributes_strict.yaml @@ -1,53 +1,35 @@ -receivers: - nop: - -processors: - filter/empty: - logs: - include: - match_type: strict - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: strict - record_attributes: - - key: should_include - value: "true" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: strict - record_attributes: - - key: should_exclude - value: "true" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with record attributes - # "should_include" to pass through - include: - match_type: strict - record_attributes: - - key: should_include - value: "true" - exclude: - match_type: strict - record_attributes: - - key: should_exclude - value: "true" - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/empty] - exporters: [nop] - logs: - receivers: [nop] - processors: [filter/empty, filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] +filter/empty: + logs: + include: + match_type: strict +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: strict + record_attributes: + - key: should_include + value: "true" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: strict + record_attributes: + - key: should_exclude + value: "true" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with record attributes + # "should_include" to pass through + include: + match_type: strict + record_attributes: + - key: should_include + value: "true" + exclude: + match_type: strict + record_attributes: + - key: should_exclude + value: "true" diff --git a/processor/filterprocessor/testdata/config_logs_regexp.yaml b/processor/filterprocessor/testdata/config_logs_regexp.yaml index ee303cfcc0ee3..60673afce55cb 100644 --- a/processor/filterprocessor/testdata/config_logs_regexp.yaml +++ b/processor/filterprocessor/testdata/config_logs_regexp.yaml @@ -1,49 +1,35 @@ -receivers: - nop: - -processors: - filter/empty: - logs: - include: - match_type: regexp - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: regexp - resource_attributes: - - key: host.name - value: "(host1|mycustomhost2)" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: regexp - resource_attributes: - - key: host.name - value: banned_host_.* - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with resource attributes - # "should_include" to pass through - include: - match_type: regexp - resource_attributes: - - key: should_include - value: "(true|probably_true)" - exclude: - match_type: regexp - resource_attributes: - - key: should_exclude - value: "(probably_false|false)" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/empty, filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] +filter/empty: + logs: + include: + match_type: regexp +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: regexp + resource_attributes: + - key: host.name + value: "(host1|mycustomhost2)" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: regexp + resource_attributes: + - key: host.name + value: banned_host_.* +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with resource attributes + # "should_include" to pass through + include: + match_type: regexp + resource_attributes: + - key: should_include + value: "(true|probably_true)" + exclude: + match_type: regexp + resource_attributes: + - key: should_exclude + value: "(probably_false|false)" diff --git a/processor/filterprocessor/testdata/config_logs_severity_regexp.yaml b/processor/filterprocessor/testdata/config_logs_severity_regexp.yaml index d18785d3a8bf9..bfcf261645fd3 100644 --- a/processor/filterprocessor/testdata/config_logs_severity_regexp.yaml +++ b/processor/filterprocessor/testdata/config_logs_severity_regexp.yaml @@ -1,42 +1,28 @@ -receivers: - nop: +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: regexp + severity_texts: + - "INFO[2-4]?" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: regexp + severity_texts: + - "DEBUG[2-4]?" -processors: - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: regexp - severity_texts: - - "INFO[2-4]?" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: regexp - severity_texts: - - "DEBUG[2-4]?" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with severity INFO, INFO2, INFO3, or INFO4 + include: + match_type: regexp + severity_texts: + - "INFO[2-4]?" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with severity INFO, INFO2, INFO3, or INFO4 - include: - match_type: regexp - severity_texts: - - "INFO[2-4]?" - - exclude: - match_type: regexp - severity_texts: - - "DEBUG[2-4]?" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] + exclude: + match_type: regexp + severity_texts: + - "DEBUG[2-4]?" diff --git a/processor/filterprocessor/testdata/config_logs_severity_strict.yaml b/processor/filterprocessor/testdata/config_logs_severity_strict.yaml index 7e4ed0adc9d1a..803be48a1fe16 100644 --- a/processor/filterprocessor/testdata/config_logs_severity_strict.yaml +++ b/processor/filterprocessor/testdata/config_logs_severity_strict.yaml @@ -1,48 +1,34 @@ -receivers: - nop: +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: strict + severity_texts: + - "INFO" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: strict + severity_texts: + - "DEBUG" + - "DEBUG2" + - "DEBUG3" + - "DEBUG4" -processors: - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: strict - severity_texts: - - "INFO" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: strict - severity_texts: - - "DEBUG" - - "DEBUG2" - - "DEBUG3" - - "DEBUG4" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with severity "INFO" + include: + match_type: strict + severity_texts: + - "INFO" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with severity "INFO" - include: - match_type: strict - severity_texts: - - "INFO" - - exclude: - match_type: strict - severity_texts: - - "DEBUG" - - "DEBUG2" - - "DEBUG3" - - "DEBUG4" - -exporters: - nop: - -service: - pipelines: - logs: - receivers: [nop] - processors: [filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] + exclude: + match_type: strict + severity_texts: + - "DEBUG" + - "DEBUG2" + - "DEBUG3" + - "DEBUG4" diff --git a/processor/filterprocessor/testdata/config_logs_strict.yaml b/processor/filterprocessor/testdata/config_logs_strict.yaml index 2b2df7d8931d3..69de9707648ab 100644 --- a/processor/filterprocessor/testdata/config_logs_strict.yaml +++ b/processor/filterprocessor/testdata/config_logs_strict.yaml @@ -1,53 +1,35 @@ -receivers: - nop: - -processors: - filter/empty: - logs: - include: - match_type: strict - filter/include: - logs: - # any logs NOT matching filters are excluded from remainder of pipeline - include: - match_type: strict - resource_attributes: - - key: should_include - value: "true" - filter/exclude: - logs: - # any logs matching filters are excluded from remainder of pipeline - exclude: - match_type: strict - resource_attributes: - - key: should_exclude - value: "true" - filter/includeexclude: - logs: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with resource attributes - # "should_include" to pass through - include: - match_type: strict - resource_attributes: - - key: should_include - value: "true" - exclude: - match_type: strict - resource_attributes: - - key: should_exclude - value: "true" - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/empty] - exporters: [nop] - logs: - receivers: [nop] - processors: [filter/empty, filter/include, filter/exclude, filter/includeexclude] - exporters: [nop] +filter/empty: + logs: + include: + match_type: strict +filter/include: + logs: + # any logs NOT matching filters are excluded from remainder of pipeline + include: + match_type: strict + resource_attributes: + - key: should_include + value: "true" +filter/exclude: + logs: + # any logs matching filters are excluded from remainder of pipeline + exclude: + match_type: strict + resource_attributes: + - key: should_exclude + value: "true" +filter/includeexclude: + logs: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with resource attributes + # "should_include" to pass through + include: + match_type: strict + resource_attributes: + - key: should_include + value: "true" + exclude: + match_type: strict + resource_attributes: + - key: should_exclude + value: "true" diff --git a/processor/filterprocessor/testdata/config_regexp.yaml b/processor/filterprocessor/testdata/config_regexp.yaml index 9b398e7166084..dea42d2d12d03 100644 --- a/processor/filterprocessor/testdata/config_regexp.yaml +++ b/processor/filterprocessor/testdata/config_regexp.yaml @@ -1,79 +1,61 @@ -receivers: - nop: - -processors: - filter: - filter/include: - # any names NOT matching filters are excluded from remainder of pipeline - metrics: - include: - match_type: regexp - metric_names: - # re2 regexp patterns - - prefix/.* - - prefix_.* - - .*/suffix - - .*_suffix - - .*/contains/.* - - .*_contains_.* - - full/name/match - - full_name_match - filter/exclude: - # any names matching filters are excluded from remainder of pipeline - metrics: - exclude: - match_type: regexp - metric_names: - - prefix/.* - - prefix_.* - - .*/suffix - - .*_suffix - - .*/contains/.* - - .*_contains_.* - - full/name/match - - full_name_match - filter/unlimitedcache: - metrics: - include: - match_type: regexp - regexp: - cacheenabled: true - metric_names: - - prefix/.* - - prefix_.* - - .*/suffix - - .*_suffix - - .*/contains/.* - - .*_contains_.* - - full/name/match - - full_name_match - filter/limitedcache: - metrics: - exclude: - match_type: regexp - metric_names: - - prefix/.* - - prefix_.* - - .*/suffix - - .*_suffix - - .*/contains/.* - - .*_contains_.* - - full/name/match - - full_name_match - regexp: - cacheenabled: true - cachemaxnumentries: 10 - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter] - exporters: [nop] - metrics: - receivers: [nop] - processors: [filter] - exporters: [nop] +filter: +filter/include: + # any names NOT matching filters are excluded from remainder of pipeline + metrics: + include: + match_type: regexp + metric_names: + # re2 regexp patterns + - prefix/.* + - prefix_.* + - .*/suffix + - .*_suffix + - .*/contains/.* + - .*_contains_.* + - full/name/match + - full_name_match +filter/exclude: + # any names matching filters are excluded from remainder of pipeline + metrics: + exclude: + match_type: regexp + metric_names: + - prefix/.* + - prefix_.* + - .*/suffix + - .*_suffix + - .*/contains/.* + - .*_contains_.* + - full/name/match + - full_name_match +filter/unlimitedcache: + metrics: + include: + match_type: regexp + regexp: + cacheenabled: true + metric_names: + - prefix/.* + - prefix_.* + - .*/suffix + - .*_suffix + - .*/contains/.* + - .*_contains_.* + - full/name/match + - full_name_match +filter/limitedcache: + metrics: + exclude: + match_type: regexp + metric_names: + - prefix/.* + - prefix_.* + - .*/suffix + - .*_suffix + - .*/contains/.* + - .*_contains_.* + - full/name/match + - full_name_match + regexp: + cacheenabled: true + cachemaxnumentries: 10 diff --git a/processor/filterprocessor/testdata/config_strict.yaml b/processor/filterprocessor/testdata/config_strict.yaml index 3e1ef5729edd8..659592a0d95f8 100644 --- a/processor/filterprocessor/testdata/config_strict.yaml +++ b/processor/filterprocessor/testdata/config_strict.yaml @@ -1,51 +1,33 @@ -receivers: - nop: - -processors: - filter/empty: - metrics: - include: - match_type: strict - filter/include: - metrics: - # any names NOT matching filters are excluded from remainder of pipeline - include: - match_type: strict - metric_names: - - hello_world - - hello/world - filter/exclude: - metrics: - # any names matching filters are excluded from remainder of pipeline - exclude: - match_type: strict - metric_names: - - hello_world - - hello/world - filter/includeexclude: - metrics: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow metrics named "hello/world" to pass through - include: - match_type: strict - metric_names: - - hello_world - - hello/world - exclude: - match_type: strict - metric_names: - - hello_world - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/empty] - exporters: [nop] - metrics: - receivers: [nop] - processors: [filter/empty] - exporters: [nop] +filter/empty: + metrics: + include: + match_type: strict +filter/include: + metrics: + # any names NOT matching filters are excluded from remainder of pipeline + include: + match_type: strict + metric_names: + - hello_world + - hello/world +filter/exclude: + metrics: + # any names matching filters are excluded from remainder of pipeline + exclude: + match_type: strict + metric_names: + - hello_world + - hello/world +filter/includeexclude: + metrics: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow metrics named "hello/world" to pass through + include: + match_type: strict + metric_names: + - hello_world + - hello/world + exclude: + match_type: strict + metric_names: + - hello_world diff --git a/processor/filterprocessor/testdata/config_traces.yaml b/processor/filterprocessor/testdata/config_traces.yaml index cdeaebed4daa3..3def22ea49b21 100644 --- a/processor/filterprocessor/testdata/config_traces.yaml +++ b/processor/filterprocessor/testdata/config_traces.yaml @@ -1,32 +1,18 @@ -receivers: - nop: - -processors: - filter/spans: - spans: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with resource attributes - # "should_include" to pass through - include: - match_type: strict - services: - - test - - test2 - attributes: - - key: should_include - value: "(true|probably_true)" - exclude: - match_type: regexp - attributes: - - key: should_exclude - value: "(probably_false|false)" - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/spans] - exporters: [nop] +filter/spans: + spans: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with resource attributes + # "should_include" to pass through + include: + match_type: strict + services: + - test + - test2 + attributes: + - key: should_include + value: "(true|probably_true)" + exclude: + match_type: regexp + attributes: + - key: should_exclude + value: "(probably_false|false)" diff --git a/processor/filterprocessor/testdata/config_traces_invalid.yaml b/processor/filterprocessor/testdata/config_traces_invalid.yaml index acd497c975f31..5eb9d226c3f09 100644 --- a/processor/filterprocessor/testdata/config_traces_invalid.yaml +++ b/processor/filterprocessor/testdata/config_traces_invalid.yaml @@ -1,29 +1,15 @@ -receivers: - nop: - -processors: - filter/spans: - spans: - # if both include and exclude are specified, include filters are applied first - # the following configuration would only allow logs with resource attributes - # "should_include" to pass through - include: - match_type: regexp - services: - - test - attributes: - - key: should_include - value: "(true|probably_true)" - # should error since nothing is set to match on - exclude: - match_type: regexp - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [filter/spans] - exporters: [nop] +filter/spans: + spans: + # if both include and exclude are specified, include filters are applied first + # the following configuration would only allow logs with resource attributes + # "should_include" to pass through + include: + match_type: regexp + services: + - test + attributes: + - key: should_include + value: "(true|probably_true)" + # should error since nothing is set to match on + exclude: + match_type: regexp diff --git a/processor/groupbyattrsprocessor/config_test.go b/processor/groupbyattrsprocessor/config_test.go index 38043018accea..a1dc94aa644ad 100644 --- a/processor/groupbyattrsprocessor/config_test.go +++ b/processor/groupbyattrsprocessor/config_test.go @@ -18,47 +18,50 @@ import ( "path/filepath" "testing" + "go.opentelemetry.io/collector/confmap/confmaptest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" - "go.opentelemetry.io/collector/processor/batchprocessor" - "go.opentelemetry.io/collector/service/servicetest" - - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbytraceprocessor" ) -func TestLoadConfig(t *testing.T) { - factories, err := componenttest.NopFactories() - require.NoError(t, err) - factory := NewFactory() - factories.Processors[typeStr] = factory - - factories.Processors["batch"] = batchprocessor.NewFactory() - factories.Processors["groupbytrace"] = groupbytraceprocessor.NewFactory() +func TestLoadingConfig(t *testing.T) { + t.Parallel() - require.NoError(t, err) + tests := []struct { + id config.ComponentID + expected config.Processor + }{ + { + id: config.NewComponentIDWithName(typeStr, "grouping"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + GroupByKeys: []string{"key1", "key2"}, + }, + }, + { + id: config.NewComponentIDWithName(typeStr, "compaction"), + expected: &Config{ + ProcessorSettings: config.NewProcessorSettings(config.NewComponentID(typeStr)), + GroupByKeys: []string{}, + }, + }, + } - err = configtest.CheckConfigStruct(factory.CreateDefaultConfig()) - require.NoError(t, err) + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) - cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config.yaml"), factories) + factory := NewFactory() + cfg := factory.CreateDefaultConfig() - require.Nil(t, err) - require.NotNil(t, cfg) - - groupingConf := cfg.Processors[config.NewComponentIDWithName(typeStr, "grouping")] - assert.Equal(t, groupingConf, - &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "grouping")), - GroupByKeys: []string{"key1", "key2"}, - }) + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, config.UnmarshalProcessor(sub, cfg)) - compactionConf := cfg.Processors[config.NewComponentIDWithName(typeStr, "compaction")] - assert.Equal(t, compactionConf, - &Config{ - ProcessorSettings: config.NewProcessorSettings(config.NewComponentIDWithName(typeStr, "compaction")), - GroupByKeys: []string{}, + assert.NoError(t, cfg.Validate()) + assert.Equal(t, tt.expected, cfg) }) + } } diff --git a/processor/groupbyattrsprocessor/go.mod b/processor/groupbyattrsprocessor/go.mod index f5a7d4ded54c9..26150435052e7 100644 --- a/processor/groupbyattrsprocessor/go.mod +++ b/processor/groupbyattrsprocessor/go.mod @@ -3,7 +3,6 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/processor/group go 1.18 require ( - github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbytraceprocessor v0.58.0 github.com/stretchr/testify v1.8.0 go.opencensus.io v0.23.0 go.opentelemetry.io/collector v0.58.0 @@ -13,19 +12,20 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf v1.4.2 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.58.0 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.6.1 // indirect go.opentelemetry.io/otel v1.9.0 // indirect go.opentelemetry.io/otel/metric v0.31.0 // indirect go.opentelemetry.io/otel/trace v1.9.0 // indirect @@ -37,6 +37,7 @@ require ( google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect google.golang.org/grpc v1.48.0 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/processor/groupbyattrsprocessor/go.sum b/processor/groupbyattrsprocessor/go.sum index c88063f91f8c9..cfcd1f5535fec 100644 --- a/processor/groupbyattrsprocessor/go.sum +++ b/processor/groupbyattrsprocessor/go.sum @@ -43,6 +43,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -116,7 +117,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/knadh/koanf v1.4.2 h1:2itp+cdC6miId4pO4Jw7c/3eiYD26Z/Sz3ATJMwHxIs= github.com/knadh/koanf v1.4.2/go.mod h1:4NCo0q4pmU398vF9vq2jStF9MWQZ8JEDcDMHlDCr4h0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -148,8 +151,10 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -243,6 +248,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -304,6 +310,7 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/processor/groupbyattrsprocessor/testdata/config.yaml b/processor/groupbyattrsprocessor/testdata/config.yaml index a1e3188767acc..14578e14231b8 100644 --- a/processor/groupbyattrsprocessor/testdata/config.yaml +++ b/processor/groupbyattrsprocessor/testdata/config.yaml @@ -1,25 +1,6 @@ -receivers: - nop: - -processors: - batch: - groupbyattrs/grouping: - keys: - - key1 - - key2 - groupbyattrs/compaction: - groupbytrace: - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [groupbyattrs/grouping] - exporters: [nop] - traces/compaction: - receivers: [nop] - processors: [groupbytrace, batch, groupbyattrs/compaction] - exporters: [nop] +groupbyattrs/grouping: + keys: + - key1 + - key2 +groupbyattrs/compaction: +groupbytrace: diff --git a/processor/groupbytraceprocessor/testdata/config.yaml b/processor/groupbytraceprocessor/testdata/config.yaml index 885617677abff..446af05e9c832 100644 --- a/processor/groupbytraceprocessor/testdata/config.yaml +++ b/processor/groupbytraceprocessor/testdata/config.yaml @@ -1,17 +1,3 @@ -receivers: - nop: - -processors: - groupbytrace/custom: - wait_duration: 10s - num_traces: 1000 - -exporters: - nop: - -service: - pipelines: - traces: - receivers: [nop] - processors: [groupbytrace/custom] - exporters: [nop] +groupbytrace/custom: + wait_duration: 10s + num_traces: 1000