diff --git a/processor/tailsamplingprocessor/README.md b/processor/tailsamplingprocessor/README.md index 24dd8bad697d4..80ff435b53695 100644 --- a/processor/tailsamplingprocessor/README.md +++ b/processor/tailsamplingprocessor/README.md @@ -37,11 +37,12 @@ Multiple policies exist today and it is straight forward to add more. These incl - `bytes_limiting`: Sample based on the rate of bytes per second using a token bucket algorithm implemented by golang.org/x/time/rate. This allows for burst traffic up to a configurable capacity while maintaining the average rate over time. The bucket is refilled continuously at the specified rate and has a maximum capacity for burst handling. - `span_count`: Sample based on the minimum and/or maximum number of spans, inclusive. If the sum of all spans in the trace is outside the range threshold, the trace will not be sampled. - `boolean_attribute`: Sample based on boolean attribute (resource and record). -- `ottl_condition`: Sample based on given boolean OTTL condition (span and span event). Conditions may use OTTL path-based context names (e.g. `span.attributes["http.status_code"]`, `resource.attributes["service.name"]`, `spanevent.name`, `scope.name`). It is highly recommended to use this new syntax to avoid breaking changes in the future. +- `ottl_condition`: Sample based on given boolean OTTL condition (span and span event). Conditions may use OTTL path-based context names (e.g. `span.attributes["http.status_code"]`, `resource.attributes["service.name"]`, `spanevent.name`, `scope.name`). It is highly recommended to use this new syntax to avoid breaking changes in the future. The `error_mode` defaults to `propagate`; this default will change to `ignore` when the `processor.tailsamplingprocessor.defaultErrorModeIgnore` feature gate is stable. - `and`: Sample based on multiple policies, creates an AND policy - `not`: Sample based on the opposite result a single policy, creates a NOT policy - `drop`: Drop (not sample) based on multiple policies, creates a DROP policy - `composite`: Sample based on a combination of above samplers, with ordering and rate allocation per sampler. Rate allocation allocates certain percentages of spans per policy order. + For example if we have set max_total_spans_per_second as 100 then we can set rate_allocation as follows 1. test-composite-policy-1 = 50 % of max_total_spans_per_second = 50 spans_per_second 2. test-composite-policy-2 = 25 % of max_total_spans_per_second = 25 spans_per_second diff --git a/processor/tailsamplingprocessor/config.go b/processor/tailsamplingprocessor/config.go index 26e18f39808e4..b720427dac1e9 100644 --- a/processor/tailsamplingprocessor/config.go +++ b/processor/tailsamplingprocessor/config.go @@ -296,6 +296,9 @@ type BooleanAttributeCfg struct { // OTTLConditionCfg holds the configurable setting to create a OTTL condition filter // sampling policy evaluator. type OTTLConditionCfg struct { + // ErrorMode determines how the processor reacts to errors that occur while processing an OTTL + // condition. The current default value is `propagate`, which will change to `ignore` when the + // `processor.tailsamplingprocessor.defaultErrorModeIgnore` feature gate is stable. ErrorMode ottl.ErrorMode `mapstructure:"error_mode"` SpanConditions []string `mapstructure:"span"` SpanEventConditions []string `mapstructure:"spanevent"` diff --git a/processor/tailsamplingprocessor/config.schema.yaml b/processor/tailsamplingprocessor/config.schema.yaml index b9f3dc1ddd1c6..7a5df8e3044d8 100644 --- a/processor/tailsamplingprocessor/config.schema.yaml +++ b/processor/tailsamplingprocessor/config.schema.yaml @@ -262,6 +262,7 @@ $defs: type: object properties: error_mode: + description: ErrorMode determines how the processor reacts to errors that occur while processing an OTTL condition. The current default value is `propagate`, which will change to `ignore` when the `processor.tailsamplingprocessor.defaultErrorModeIgnore` feature gate is stable. $ref: /pkg/ottl.error_mode span: type: array diff --git a/processor/tailsamplingprocessor/factory_test.go b/processor/tailsamplingprocessor/factory_test.go index 4e2450fd0966e..2109885691252 100644 --- a/processor/tailsamplingprocessor/factory_test.go +++ b/processor/tailsamplingprocessor/factory_test.go @@ -13,8 +13,10 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/processor/processortest" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/metadata" ) @@ -24,6 +26,18 @@ func TestCreateDefaultConfig(t *testing.T) { assert.NoError(t, componenttest.CheckConfigStruct(cfg)) } +func TestDefaultOTTLConditionErrorMode(t *testing.T) { + t.Cleanup(func() { + _ = featuregate.GlobalRegistry().Set(metadata.ProcessorTailsamplingprocessorDefaultErrorModeIgnoreFeatureGate.ID(), false) + }) + + assert.Equal(t, ottl.PropagateError, defaultOTTLConditionErrorMode()) + + require.NoError(t, featuregate.GlobalRegistry().Set(metadata.ProcessorTailsamplingprocessorDefaultErrorModeIgnoreFeatureGate.ID(), true)) + + assert.Equal(t, ottl.IgnoreError, defaultOTTLConditionErrorMode()) +} + func TestCreateProcessor(t *testing.T) { cm, err := confmaptest.LoadConf(filepath.Join("testdata", "tail_sampling_config.yaml")) require.NoError(t, err) diff --git a/processor/tailsamplingprocessor/internal/metadata/generated_feature_gates.go b/processor/tailsamplingprocessor/internal/metadata/generated_feature_gates.go index 300119c6b3a4a..c86fc0942cfbc 100644 --- a/processor/tailsamplingprocessor/internal/metadata/generated_feature_gates.go +++ b/processor/tailsamplingprocessor/internal/metadata/generated_feature_gates.go @@ -38,3 +38,11 @@ var ProcessorTailsamplingprocessorTailstorageextensionFeatureGate = featuregate. featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/47331"), featuregate.WithRegisterFromVersion("v0.150.0"), ) + +var ProcessorTailsamplingprocessorDefaultErrorModeIgnoreFeatureGate = featuregate.GlobalRegistry().MustRegister( + "processor.tailsamplingprocessor.defaultErrorModeIgnore", + featuregate.StageAlpha, + featuregate.WithRegisterDescription("Changes the default error_mode of the tail sampling processor ottl_condition policy from propagate to ignore"), + featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/48420"), + featuregate.WithRegisterFromVersion("v0.153.0"), +) diff --git a/processor/tailsamplingprocessor/metadata.yaml b/processor/tailsamplingprocessor/metadata.yaml index 77afd7f8cde3a..2dd0ea2ccf27f 100644 --- a/processor/tailsamplingprocessor/metadata.yaml +++ b/processor/tailsamplingprocessor/metadata.yaml @@ -37,6 +37,12 @@ feature_gates: from_version: v0.150.0 reference_url: https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/47331 + - id: "processor.tailsamplingprocessor.defaultErrorModeIgnore" + description: Changes the default error_mode of the tail sampling processor ottl_condition policy from propagate to ignore + stage: alpha + from_version: v0.153.0 + reference_url: https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/48420 + tests: config: diff --git a/processor/tailsamplingprocessor/processor.go b/processor/tailsamplingprocessor/processor.go index b4ccede5d61b7..2ed692a66f9fe 100644 --- a/processor/tailsamplingprocessor/processor.go +++ b/processor/tailsamplingprocessor/processor.go @@ -24,6 +24,7 @@ import ( "go.opentelemetry.io/otel/trace" "go.uber.org/zap" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/cache" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/idbatcher" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/metadata" @@ -450,6 +451,9 @@ func getSharedPolicyEvaluator(settings component.TelemetrySettings, cfg *sharedP return sampling.NewBooleanAttributeFilter(settings, bafCfg.Key, bafCfg.Value, bafCfg.InvertMatch), nil case OTTLCondition: ottlfCfg := cfg.OTTLConditionCfg + if ottlfCfg.ErrorMode == "" { + ottlfCfg.ErrorMode = defaultOTTLConditionErrorMode() + } return sampling.NewOTTLConditionFilter(settings, ottlfCfg.SpanConditions, ottlfCfg.SpanEventConditions, ottlfCfg.ErrorMode) case TraceFlags: return sampling.NewTraceFlags(settings), nil @@ -468,6 +472,13 @@ func getSharedPolicyEvaluator(settings component.TelemetrySettings, cfg *sharedP } } +func defaultOTTLConditionErrorMode() ottl.ErrorMode { + if metadata.ProcessorTailsamplingprocessorDefaultErrorModeIgnoreFeatureGate.IsEnabled() { + return ottl.IgnoreError + } + return ottl.PropagateError +} + type policyDecisionMetrics struct { tracesSampled int spansSampled int64