diff --git a/docs/sources/reference/components/otelcol/otelcol.processor.tail_sampling.md b/docs/sources/reference/components/otelcol/otelcol.processor.tail_sampling.md index 2955a4ec1f0..3b1b5322c8d 100644 --- a/docs/sources/reference/components/otelcol/otelcol.processor.tail_sampling.md +++ b/docs/sources/reference/components/otelcol/otelcol.processor.tail_sampling.md @@ -49,6 +49,8 @@ You can use the following arguments with `otelcol.processor.tail_sampling`: | `num_traces` | `int` | Number of traces kept in memory. | `50000` | no | | `block_on_overflow` | `boolean` | If `true`, wait for space when the `num_traces` limit is reached. If `false`, old traces will be evicted to make space. | `false` | no | | `expected_new_traces_per_sec` | `int` | Expected number of new traces (helps in allocating data structures). | `0` | no | +| `sample_on_first_match` | `boolean` | Make a sampling decision as soon as any policy matches. | `false` | no | +| `drop_pending_traces_on_shutdown` | `boolean` | Drop pending traces on shutdown instead of deciding with partial data. | `false` | no | | `decision_cache` | `object` | Configures caches for sampling decisions. | `{}` | no | `decision_wait` determines the number of batches to maintain on a channel. @@ -60,6 +62,10 @@ Increasing the number will increase the memory usage of the component while decr `expected_new_traces_per_sec` determines the initial slice sizing of the current batch. A larger number will use more memory but be more efficient when adding traces to the batch. +If `sample_on_first_match` is `true`, the component makes a decision as soon as one policy matches. + +If `drop_pending_traces_on_shutdown` is `true`, the component drops traces that are still waiting for `decision_wait` when shutdown starts. + `decision_cache` can contain two keys: * `sampled_cache_size`: Configures the number of trace IDs to be kept in an LRU cache, persisting the "keep" decisions for traces that may have already been released from memory. @@ -85,6 +91,7 @@ You can use the following blocks with `otelcol.processor.tail_sampling`: | `policy` > [`ottl_condition`][ottl_condition] | The policy samples based on a given boolean OTTL condition (span and span event). | no | | `policy` > [`probabilistic`][probabilistic] | The policy samples a percentage of traces. | no | | `policy` > [`rate_limiting`][rate_limiting] | The policy samples based on rate. | no | +| `policy` > [`bytes_limiting`][bytes_limiting] | The policy samples based on the rate of bytes per second. | no | | `policy` > [`span_count`][span_count] | The policy samples based on the minimum number of spans within a batch. | no | | `policy` > [`status_code`][status_code] | The policy samples based upon the status code. | no | | `policy` > [`string_attribute`][string_attribute] | The policy samples based on string attributes (resource and record) value matches. | no | @@ -97,10 +104,24 @@ You can use the following blocks with `otelcol.processor.tail_sampling`: | `policy` > `and` > `and_sub_policy` > [`ottl_condition`][ottl_condition] | The policy samples based on a given boolean OTTL condition (span and span event). | no | | `policy` > `and` > `and_sub_policy` > [`probabilistic`][probabilistic] | The policy samples a percentage of traces. | no | | `policy` > `and` > `and_sub_policy` > [`rate_limiting`][rate_limiting] | The policy samples based on rate. | no | +| `policy` > `and` > `and_sub_policy` > [`bytes_limiting`][bytes_limiting] | The policy samples based on the rate of bytes per second. | no | | `policy` > `and` > `and_sub_policy` > [`span_count`][span_count] | The policy samples based on the minimum number of spans within a batch. | no | | `policy` > `and` > `and_sub_policy` > [`status_code`][status_code] | The policy samples based upon the status code. | no | | `policy` > `and` > `and_sub_policy` > [`string_attribute`][string_attribute] | The policy samples based on string attributes (resource and record) value matches. | no | | `policy` > `and` > `and_sub_policy` > [`trace_state`][trace_state] | The policy samples based on TraceState value matches. | no | +| `policy` > [`drop`][drop] | The policy drops traces based on multiple sub-policies. | no | +| `policy` > `drop` > [`drop_sub_policy`][drop_sub_policy] | A set of policies underneath a `drop` policy type. | no | +| `policy` > `drop` > `drop_sub_policy` > [`boolean_attribute`][boolean_attribute] | The policy samples based on a boolean attribute (resource and record). | no | +| `policy` > `drop` > `drop_sub_policy` > [`latency`][latency] | The policy samples based on the duration of the trace. | no | +| `policy` > `drop` > `drop_sub_policy` > [`numeric_attribute`][numeric_attribute] | The policy samples based on number attributes (resource and record). | no | +| `policy` > `drop` > `drop_sub_policy` > [`ottl_condition`][ottl_condition] | The policy samples based on a given boolean OTTL condition (span and span event). | no | +| `policy` > `drop` > `drop_sub_policy` > [`probabilistic`][probabilistic] | The policy samples a percentage of traces. | no | +| `policy` > `drop` > `drop_sub_policy` > [`rate_limiting`][rate_limiting] | The policy samples based on rate. | no | +| `policy` > `drop` > `drop_sub_policy` > [`bytes_limiting`][bytes_limiting] | The policy samples based on the rate of bytes per second. | no | +| `policy` > `drop` > `drop_sub_policy` > [`span_count`][span_count] | The policy samples based on the minimum number of spans within a batch. | no | +| `policy` > `drop` > `drop_sub_policy` > [`status_code`][status_code] | The policy samples based upon the status code. | no | +| `policy` > `drop` > `drop_sub_policy` > [`string_attribute`][string_attribute] | The policy samples based on string attributes (resource and record) value matches. | no | +| `policy` > `drop` > `drop_sub_policy` > [`trace_state`][trace_state] | The policy samples based on TraceState value matches. | no | | `policy` > [`composite`][composite] | The policy samples based on a combination of above samplers, with ordering and rate allocation per sampler. | no | | `policy` > `composite` > [`composite_sub_policy`][composite_sub_policy] | A set of policies underneath a `composite` policy type. | no | | `policy` > `composite` > `composite_sub_policy` > [`boolean_attribute`][boolean_attribute] | The policy samples based on a boolean attribute (resource and record). | no | @@ -109,6 +130,7 @@ You can use the following blocks with `otelcol.processor.tail_sampling`: | `policy` > `composite` > `composite_sub_policy` > [`ottl_condition`][ottl_condition] | The policy samples based on a given boolean OTTL condition (span and span event). | no | | `policy` > `composite` > `composite_sub_policy` > [`probabilistic`][probabilistic] | The policy samples a percentage of traces. | no | | `policy` > `composite` > `composite_sub_policy` > [`rate_limiting`][rate_limiting] | The policy samples based on rate. | no | +| `policy` > `composite` > `composite_sub_policy` > [`bytes_limiting`][bytes_limiting] | The policy samples based on the rate of bytes per second. | no | | `policy` > `composite` > `composite_sub_policy` > [`span_count`][span_count] | The policy samples based on the minimum number of spans within a batch. | no | | `policy` > `composite` > `composite_sub_policy` > [`status_code`][status_code] | The policy samples based upon the status code. | no | | `policy` > `composite` > `composite_sub_policy` > [`string_attribute`][string_attribute] | The policy samples based on string attributes (resource and record) value matches. | no | @@ -122,12 +144,15 @@ You can use the following blocks with `otelcol.processor.tail_sampling`: [status_code]: #status_code [string_attribute]: #string_attribute [rate_limiting]: #rate_limiting +[bytes_limiting]: #bytes_limiting [span_count]: #span_count [boolean_attribute]: #boolean_attribute [ottl_condition]: #ottl_condition [trace_state]: #trace_state [and]: #and [and_sub_policy]: #and_sub_policy +[drop]: #drop +[drop_sub_policy]: #drop_sub_policy [composite]: #composite [composite_sub_policy]: #composite_sub_policy [output]: #output @@ -155,6 +180,7 @@ The following arguments are supported: Each policy results in a decision, and the processor evaluates them to make a final decision: +* When there's a "drop" decision, the trace isn't sampled. * When there's an "inverted not sample" decision, the trace isn't sampled. ***Deprecated*** * When there's a "sample" decision, the trace is sampled. * When there's an "inverted sample" decision and no "not sample" decisions, the trace is sampled. ***Deprecated*** @@ -257,6 +283,18 @@ The following arguments are supported: |--------------------|----------|---------------------------------------------------------------------|---------|----------| | `spans_per_second` | `number` | Sets the maximum number of spans that can be processed each second. | | yes | +### `bytes_limiting` + +The `bytes_limiting` block configures a policy of type `bytes_limiting`. +The policy samples based on the rate of bytes per second using a token bucket algorithm. + +The following arguments are supported: + +| Name | Type | Description | Default | Required | +|--------------------|----------|-------------------------------------------------------------------------------------------------------------------|---------|----------| +| `bytes_per_second` | `number` | Sets the sustained byte throughput limit. | | yes | +| `burst_capacity` | `number` | Sets the maximum burst size in bytes. If omitted, it defaults to `2 * bytes_per_second` in the upstream policy. | `0` | no | + ### `span_count` The `span_count` block configures a policy of type `span_count`. @@ -330,6 +368,23 @@ The following arguments are supported: | `name` | `string` | The custom name given to the policy. | | yes | | `type` | `string` | The valid policy type for this policy. | | yes | +### `drop` + +The `drop` block configures a policy of type `drop`. +This policy drops traces when all `drop_sub_policy` blocks match. + +### `drop_sub_policy` + +The `drop_sub_policy` block configures a sampling policy used by the `drop` block. +At least one `drop_sub_policy` block is required inside a `drop` block. + +The following arguments are supported: + +| Name | Type | Description | Default | Required | +|--------|----------|----------------------------------------|---------|----------| +| `name` | `string` | The custom name given to the policy. | | yes | +| `type` | `string` | The valid policy type for this policy. | | yes | + ### `composite` The `composite` block configures a policy of type `composite`. @@ -393,6 +448,8 @@ otelcol.processor.tail_sampling "default" { decision_wait = "10s" num_traces = 100 expected_new_traces_per_sec = 10 + sample_on_first_match = true + drop_pending_traces_on_shutdown = true policy { name = "test-policy-1" @@ -470,6 +527,16 @@ otelcol.processor.tail_sampling "default" { policy { name = "test-policy-9" + type = "bytes_limiting" + + bytes_limiting { + bytes_per_second = 2048 + burst_capacity = 4096 + } + } + + policy { + name = "test-policy-10" type = "string_attribute" string_attribute { @@ -481,7 +548,7 @@ otelcol.processor.tail_sampling "default" { } policy { - name = "test-policy-10" + name = "test-policy-11" type = "span_count" span_count { @@ -490,7 +557,7 @@ otelcol.processor.tail_sampling "default" { } policy { - name = "test-policy-11" + name = "test-policy-12" type = "trace_state" trace_state { @@ -500,7 +567,7 @@ otelcol.processor.tail_sampling "default" { } policy { - name = "test-policy-12" + name = "test-policy-13" type = "ottl_condition" ottl_condition { error_mode = "ignore" @@ -515,6 +582,24 @@ otelcol.processor.tail_sampling "default" { } } + policy { + name = "drop-policy-1" + type = "drop" + + drop { + drop_sub_policy { + name = "test-drop-policy-1" + type = "string_attribute" + + string_attribute { + key = "url.path" + values = ["/health", "/metrics"] + enabled_regex_matching = true + } + } + } + } + policy { name = "and-policy-1" type = "and" diff --git a/internal/component/otelcol/processor/tail_sampling/tail_sampling.go b/internal/component/otelcol/processor/tail_sampling/tail_sampling.go index d31ac062e58..fe3af7c1058 100644 --- a/internal/component/otelcol/processor/tail_sampling/tail_sampling.go +++ b/internal/component/otelcol/processor/tail_sampling/tail_sampling.go @@ -31,12 +31,14 @@ func init() { // Arguments configures the otelcol.processor.tail_sampling component. type Arguments struct { - PolicyCfgs []PolicyConfig `alloy:"policy,block"` - DecisionWait time.Duration `alloy:"decision_wait,attr,optional"` - NumTraces uint64 `alloy:"num_traces,attr,optional"` - BlockOnOverflow bool `alloy:"block_on_overflow,attr,optional"` - ExpectedNewTracesPerSec uint64 `alloy:"expected_new_traces_per_sec,attr,optional"` - DecisionCache DecisionCacheConfig `alloy:"decision_cache,attr,optional"` + PolicyCfgs []PolicyConfig `alloy:"policy,block"` + DecisionWait time.Duration `alloy:"decision_wait,attr,optional"` + NumTraces uint64 `alloy:"num_traces,attr,optional"` + BlockOnOverflow bool `alloy:"block_on_overflow,attr,optional"` + ExpectedNewTracesPerSec uint64 `alloy:"expected_new_traces_per_sec,attr,optional"` + SampleOnFirstMatch bool `alloy:"sample_on_first_match,attr,optional"` + DropPendingTracesOnShutdown bool `alloy:"drop_pending_traces_on_shutdown,attr,optional"` + DecisionCache DecisionCacheConfig `alloy:"decision_cache,attr,optional"` // Output configures where to send processed data. Required. Output *otelcol.ConsumerArguments `alloy:"output,block"` // DebugMetrics configures component internal metrics. Optional. @@ -81,12 +83,14 @@ func (args Arguments) Convert() (otelcomponent.Config, error) { } return &tsp.Config{ - DecisionWait: args.DecisionWait, - NumTraces: args.NumTraces, - BlockOnOverflow: args.BlockOnOverflow, - ExpectedNewTracesPerSec: args.ExpectedNewTracesPerSec, - PolicyCfgs: otelPolicyCfgs, - DecisionCache: args.DecisionCache.Convert(), + DecisionWait: args.DecisionWait, + NumTraces: args.NumTraces, + BlockOnOverflow: args.BlockOnOverflow, + ExpectedNewTracesPerSec: args.ExpectedNewTracesPerSec, + SampleOnFirstMatch: args.SampleOnFirstMatch, + DropPendingTracesOnShutdown: args.DropPendingTracesOnShutdown, + PolicyCfgs: otelPolicyCfgs, + DecisionCache: args.DecisionCache.Convert(), }, nil } diff --git a/internal/component/otelcol/processor/tail_sampling/tail_sampling_test.go b/internal/component/otelcol/processor/tail_sampling/tail_sampling_test.go index 77fdf141102..e50e7abd8cd 100644 --- a/internal/component/otelcol/processor/tail_sampling/tail_sampling_test.go +++ b/internal/component/otelcol/processor/tail_sampling/tail_sampling_test.go @@ -110,6 +110,8 @@ func TestBigConfig(t *testing.T) { decision_wait = "10s" num_traces = 100 expected_new_traces_per_sec = 10 + sample_on_first_match = true + drop_pending_traces_on_shutdown = true policy { name = "test-policy-1" type = "always_sample" @@ -169,6 +171,14 @@ func TestBigConfig(t *testing.T) { spans_per_second = 35 } } + policy { + name = "test-policy-bytes-limiting" + type = "bytes_limiting" + bytes_limiting { + bytes_per_second = 2048 + burst_capacity = 4096 + } + } policy { name = "test-policy-9" type = "string_attribute" @@ -284,6 +294,29 @@ func TestBigConfig(t *testing.T) { ] } } + and_sub_policy { + name = "test-and-policy-5" + type = "bytes_limiting" + bytes_limiting { + bytes_per_second = 1024 + burst_capacity = 2048 + } + } + } + } + policy { + name = "drop-policy-1" + type = "drop" + drop { + drop_sub_policy { + name = "test-drop-policy-1" + type = "string_attribute" + string_attribute { + key = "http.route" + values = ["/health", "/metrics"] + enabled_regex_matching = true + } + } } } policy{ @@ -336,6 +369,14 @@ func TestBigConfig(t *testing.T) { ] } } + composite_sub_policy { + name = "test-composite-policy-6" + type = "bytes_limiting" + bytes_limiting { + bytes_per_second = 512 + burst_capacity = 1024 + } + } rate_allocation { policy = "test-composite-policy-1" percent = 50 diff --git a/internal/component/otelcol/processor/tail_sampling/types.go b/internal/component/otelcol/processor/tail_sampling/types.go index 2626e6fd951..99041651529 100644 --- a/internal/component/otelcol/processor/tail_sampling/types.go +++ b/internal/component/otelcol/processor/tail_sampling/types.go @@ -19,6 +19,9 @@ type PolicyConfig struct { // Configs for defining and policy AndConfig AndConfig `alloy:"and,block,optional"` + + // Configs for defining drop policy + DropConfig DropConfig `alloy:"drop,block,optional"` } func (policyConfig PolicyConfig) Convert() tsp.PolicyCfg { @@ -33,12 +36,14 @@ func (policyConfig PolicyConfig) Convert() tsp.PolicyCfg { "status_code": policyConfig.SharedPolicyConfig.StatusCodeConfig.Convert(), "string_attribute": policyConfig.SharedPolicyConfig.StringAttributeConfig.Convert(), "rate_limiting": policyConfig.SharedPolicyConfig.RateLimitingConfig.Convert(), + "bytes_limiting": policyConfig.SharedPolicyConfig.BytesLimitingConfig.Convert(), "span_count": policyConfig.SharedPolicyConfig.SpanCountConfig.Convert(), "boolean_attribute": policyConfig.SharedPolicyConfig.BooleanAttributeConfig.Convert(), "ottl_condition": policyConfig.SharedPolicyConfig.OttlConditionConfig.Convert(), "trace_state": policyConfig.SharedPolicyConfig.TraceStateConfig.Convert(), "composite": policyConfig.CompositeConfig.Convert(), "and": policyConfig.AndConfig.Convert(), + "drop": policyConfig.DropConfig.Convert(), }, &otelConfig) return otelConfig @@ -54,6 +59,7 @@ type SharedPolicyConfig struct { StatusCodeConfig StatusCodeConfig `alloy:"status_code,block,optional"` StringAttributeConfig StringAttributeConfig `alloy:"string_attribute,block,optional"` RateLimitingConfig RateLimitingConfig `alloy:"rate_limiting,block,optional"` + BytesLimitingConfig BytesLimitingConfig `alloy:"bytes_limiting,block,optional"` SpanCountConfig SpanCountConfig `alloy:"span_count,block,optional"` BooleanAttributeConfig BooleanAttributeConfig `alloy:"boolean_attribute,block,optional"` OttlConditionConfig OttlConditionConfig `alloy:"ottl_condition,block,optional"` @@ -174,6 +180,22 @@ func (rateLimitingConfig RateLimitingConfig) Convert() tsp.RateLimitingCfg { } } +// BytesLimitingConfig holds the configurable settings to create a bytes limiting +// sampling policy evaluator using a token bucket algorithm. +type BytesLimitingConfig struct { + // BytesPerSecond sets the limit on the maximum number of bytes that can be processed each second. + BytesPerSecond int64 `alloy:"bytes_per_second,attr"` + // BurstCapacity sets the maximum burst capacity in bytes. + BurstCapacity int64 `alloy:"burst_capacity,attr,optional"` +} + +func (bytesLimitingConfig BytesLimitingConfig) Convert() tsp.BytesLimitingCfg { + return tsp.BytesLimitingCfg{ + BytesPerSecond: bytesLimitingConfig.BytesPerSecond, + BurstCapacity: bytesLimitingConfig.BurstCapacity, + } +} + // SpanCountConfig holds the configurable settings to create a Span Count filter sampling policy // sampling policy evaluator type SpanCountConfig struct { @@ -348,6 +370,7 @@ func (compositeSubPolicyConfig CompositeSubPolicyConfig) Convert() tsp.Composite "status_code": compositeSubPolicyConfig.SharedPolicyConfig.StatusCodeConfig.Convert(), "string_attribute": compositeSubPolicyConfig.SharedPolicyConfig.StringAttributeConfig.Convert(), "rate_limiting": compositeSubPolicyConfig.SharedPolicyConfig.RateLimitingConfig.Convert(), + "bytes_limiting": compositeSubPolicyConfig.SharedPolicyConfig.BytesLimitingConfig.Convert(), "span_count": compositeSubPolicyConfig.SharedPolicyConfig.SpanCountConfig.Convert(), "boolean_attribute": compositeSubPolicyConfig.SharedPolicyConfig.BooleanAttributeConfig.Convert(), "ottl_condition": compositeSubPolicyConfig.SharedPolicyConfig.OttlConditionConfig.Convert(), @@ -386,6 +409,21 @@ func (andConfig AndConfig) Convert() tsp.AndCfg { } } +type DropConfig struct { + SubPolicyConfig []AndSubPolicyConfig `alloy:"drop_sub_policy,block"` +} + +func (dropConfig DropConfig) Convert() tsp.DropCfg { + var otelPolicyCfgs []tsp.AndSubPolicyCfg + for _, subPolicyCfg := range dropConfig.SubPolicyConfig { + otelPolicyCfgs = append(otelPolicyCfgs, subPolicyCfg.Convert()) + } + + return tsp.DropCfg{ + SubPolicyCfg: otelPolicyCfgs, + } +} + // AndSubPolicyConfig holds the common configuration to all policies under and policy. type AndSubPolicyConfig struct { SharedPolicyConfig SharedPolicyConfig `alloy:",squash"` @@ -403,6 +441,7 @@ func (andSubPolicyConfig AndSubPolicyConfig) Convert() tsp.AndSubPolicyCfg { "status_code": andSubPolicyConfig.SharedPolicyConfig.StatusCodeConfig.Convert(), "string_attribute": andSubPolicyConfig.SharedPolicyConfig.StringAttributeConfig.Convert(), "rate_limiting": andSubPolicyConfig.SharedPolicyConfig.RateLimitingConfig.Convert(), + "bytes_limiting": andSubPolicyConfig.SharedPolicyConfig.BytesLimitingConfig.Convert(), "span_count": andSubPolicyConfig.SharedPolicyConfig.SpanCountConfig.Convert(), "boolean_attribute": andSubPolicyConfig.SharedPolicyConfig.BooleanAttributeConfig.Convert(), "ottl_condition": andSubPolicyConfig.SharedPolicyConfig.OttlConditionConfig.Convert(), diff --git a/internal/converter/internal/otelcolconvert/converter_tailsamplingprocessor.go b/internal/converter/internal/otelcolconvert/converter_tailsamplingprocessor.go index 6c5f2036474..55b1db71511 100644 --- a/internal/converter/internal/otelcolconvert/converter_tailsamplingprocessor.go +++ b/internal/converter/internal/otelcolconvert/converter_tailsamplingprocessor.go @@ -50,11 +50,13 @@ func toTailSamplingProcessor(state *State, id componentstatus.InstanceID, cfg *t ) return &tail_sampling.Arguments{ - PolicyCfgs: toPolicyCfgs(cfg.PolicyCfgs), - DecisionWait: cfg.DecisionWait, - NumTraces: cfg.NumTraces, - BlockOnOverflow: cfg.BlockOnOverflow, - ExpectedNewTracesPerSec: cfg.ExpectedNewTracesPerSec, + PolicyCfgs: toPolicyCfgs(cfg.PolicyCfgs), + DecisionWait: cfg.DecisionWait, + NumTraces: cfg.NumTraces, + BlockOnOverflow: cfg.BlockOnOverflow, + ExpectedNewTracesPerSec: cfg.ExpectedNewTracesPerSec, + SampleOnFirstMatch: cfg.SampleOnFirstMatch, + DropPendingTracesOnShutdown: cfg.DropPendingTracesOnShutdown, Output: &otelcol.ConsumerArguments{ Traces: ToTokenizedConsumers(nextTraces), }, @@ -69,6 +71,7 @@ func toPolicyCfgs(cfgs []tailsamplingprocessor.PolicyCfg) []tail_sampling.Policy SharedPolicyConfig: toSharedPolicyConfig(cfg), CompositeConfig: toCompositeConfig(cfg.CompositeCfg), AndConfig: toAndConfig(cfg.AndCfg), + DropConfig: toDropConfig(cfg.DropCfg), }) } return out @@ -84,6 +87,7 @@ func toSharedPolicyConfig(cfg tailsamplingprocessor.PolicyCfg) tail_sampling.Sha StatusCodeConfig: toStatusCodeConfig(cfg.StatusCodeCfg), StringAttributeConfig: toStringAttributeConfig(cfg.StringAttributeCfg), RateLimitingConfig: toRateLimitingConfig(cfg.RateLimitingCfg), + BytesLimitingConfig: toBytesLimitingConfig(cfg.BytesLimitingCfg), SpanCountConfig: toSpanCountConfig(cfg.SpanCountCfg), BooleanAttributeConfig: toBooleanAttributeConfig(cfg.BooleanAttributeCfg), OttlConditionConfig: toOttlConditionConfig(cfg.OTTLConditionCfg), @@ -114,6 +118,7 @@ func toSubPolicyConfig(cfgs []tailsamplingprocessor.CompositeSubPolicyCfg) []tai StatusCodeConfig: toStatusCodeConfig(cfg.StatusCodeCfg), StringAttributeConfig: toStringAttributeConfig(cfg.StringAttributeCfg), RateLimitingConfig: toRateLimitingConfig(cfg.RateLimitingCfg), + BytesLimitingConfig: toBytesLimitingConfig(cfg.BytesLimitingCfg), SpanCountConfig: toSpanCountConfig(cfg.SpanCountCfg), BooleanAttributeConfig: toBooleanAttributeConfig(cfg.BooleanAttributeCfg), OttlConditionConfig: toOttlConditionConfig(cfg.OTTLConditionCfg), @@ -141,6 +146,12 @@ func toAndConfig(cfg tailsamplingprocessor.AndCfg) tail_sampling.AndConfig { } } +func toDropConfig(cfg tailsamplingprocessor.DropCfg) tail_sampling.DropConfig { + return tail_sampling.DropConfig{ + SubPolicyConfig: toAndSubPolicyCfg(cfg.SubPolicyCfg), + } +} + func toAndSubPolicyCfg(cfgs []tailsamplingprocessor.AndSubPolicyCfg) []tail_sampling.AndSubPolicyConfig { var out []tail_sampling.AndSubPolicyConfig for _, cfg := range cfgs { @@ -154,6 +165,7 @@ func toAndSubPolicyCfg(cfgs []tailsamplingprocessor.AndSubPolicyCfg) []tail_samp StatusCodeConfig: toStatusCodeConfig(cfg.StatusCodeCfg), StringAttributeConfig: toStringAttributeConfig(cfg.StringAttributeCfg), RateLimitingConfig: toRateLimitingConfig(cfg.RateLimitingCfg), + BytesLimitingConfig: toBytesLimitingConfig(cfg.BytesLimitingCfg), SpanCountConfig: toSpanCountConfig(cfg.SpanCountCfg), BooleanAttributeConfig: toBooleanAttributeConfig(cfg.BooleanAttributeCfg), OttlConditionConfig: toOttlConditionConfig(cfg.OTTLConditionCfg), @@ -209,6 +221,13 @@ func toRateLimitingConfig(cfg tailsamplingprocessor.RateLimitingCfg) tail_sampli } } +func toBytesLimitingConfig(cfg tailsamplingprocessor.BytesLimitingCfg) tail_sampling.BytesLimitingConfig { + return tail_sampling.BytesLimitingConfig{ + BytesPerSecond: cfg.BytesPerSecond, + BurstCapacity: cfg.BurstCapacity, + } +} + func toSpanCountConfig(cfg tailsamplingprocessor.SpanCountCfg) tail_sampling.SpanCountConfig { return tail_sampling.SpanCountConfig{ MinSpans: cfg.MinSpans, diff --git a/internal/converter/internal/otelcolconvert/testdata/tail_sampling.alloy b/internal/converter/internal/otelcolconvert/testdata/tail_sampling.alloy index 864f6993746..297c1070019 100644 --- a/internal/converter/internal/otelcolconvert/testdata/tail_sampling.alloy +++ b/internal/converter/internal/otelcolconvert/testdata/tail_sampling.alloy @@ -89,6 +89,16 @@ otelcol.processor.tail_sampling "default" { } } + policy { + name = "test-policy-8b" + type = "bytes_limiting" + + bytes_limiting { + bytes_per_second = 2048 + burst_capacity = 4096 + } + } + policy { name = "test-policy-9" type = "string_attribute" @@ -168,6 +178,34 @@ otelcol.processor.tail_sampling "default" { values = ["value1", "value2"] } } + + and_sub_policy { + name = "test-and-policy-3" + type = "bytes_limiting" + + bytes_limiting { + bytes_per_second = 1024 + burst_capacity = 2048 + } + } + } + } + + policy { + name = "drop-policy-1" + type = "drop" + + drop { + drop_sub_policy { + name = "test-drop-policy-1" + type = "string_attribute" + + string_attribute { + key = "url.path" + values = ["\\/health", "\\/metrics"] + enabled_regex_matching = true + } + } } } @@ -205,6 +243,16 @@ otelcol.processor.tail_sampling "default" { type = "always_sample" } + composite_sub_policy { + name = "test-composite-policy-4" + type = "bytes_limiting" + + bytes_limiting { + bytes_per_second = 512 + burst_capacity = 1024 + } + } + rate_allocation { policy = "test-composite-policy-1" percent = 50 @@ -216,9 +264,11 @@ otelcol.processor.tail_sampling "default" { } } } - decision_wait = "10s" - num_traces = 100 - expected_new_traces_per_sec = 10 + decision_wait = "10s" + num_traces = 100 + expected_new_traces_per_sec = 10 + sample_on_first_match = true + drop_pending_traces_on_shutdown = true output { traces = [otelcol.exporter.otlp.default.input] diff --git a/internal/converter/internal/otelcolconvert/testdata/tail_sampling.yaml b/internal/converter/internal/otelcolconvert/testdata/tail_sampling.yaml index 4efcc8b7fd7..d3f1635df53 100644 --- a/internal/converter/internal/otelcolconvert/testdata/tail_sampling.yaml +++ b/internal/converter/internal/otelcolconvert/testdata/tail_sampling.yaml @@ -13,6 +13,8 @@ processors: decision_wait: 10s num_traces: 100 expected_new_traces_per_sec: 10 + sample_on_first_match: true + drop_pending_traces_on_shutdown: true policies: [ { @@ -54,6 +56,11 @@ processors: type: rate_limiting, rate_limiting: {spans_per_second: 35} }, + { + name: test-policy-8b, + type: bytes_limiting, + bytes_limiting: {bytes_per_second: 2048, burst_capacity: 4096} + }, { name: test-policy-9, type: string_attribute, @@ -105,9 +112,29 @@ processors: type: string_attribute, string_attribute: { key: key2, values: [ value1, value2 ] } }, + { + name: test-and-policy-3, + type: bytes_limiting, + bytes_limiting: {bytes_per_second: 1024, burst_capacity: 2048} + }, ] } }, + { + name: drop-policy-1, + type: drop, + drop: + { + drop_sub_policy: + [ + { + name: test-drop-policy-1, + type: string_attribute, + string_attribute: {key: url.path, values: [\/health, \/metrics], enabled_regex_matching: true} + } + ] + } + }, { name: composite-policy-1, type: composite, @@ -130,6 +157,11 @@ processors: { name: test-composite-policy-3, type: always_sample + }, + { + name: test-composite-policy-4, + type: bytes_limiting, + bytes_limiting: {bytes_per_second: 512, burst_capacity: 1024} } ], rate_allocation: