From e33e96cd9123a0892b2a89faebf5e30b0f2a6664 Mon Sep 17 00:00:00 2001 From: Andrew Wilkins Date: Mon, 15 Feb 2021 11:43:08 +0800 Subject: [PATCH] sampling: require a default policy --- x-pack/apm-server/sampling/config.go | 10 ++++++++++ x-pack/apm-server/sampling/config_test.go | 6 +++++- x-pack/apm-server/sampling/processor_test.go | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/x-pack/apm-server/sampling/config.go b/x-pack/apm-server/sampling/config.go index ce713d93ee0..9ba7794f2f9 100644 --- a/x-pack/apm-server/sampling/config.go +++ b/x-pack/apm-server/sampling/config.go @@ -46,6 +46,9 @@ type LocalSamplingConfig struct { // Policies holds local tail-sampling policies. Policies are matched in the // order provided. Policies should therefore be ordered from most to least // specific. + // + // Policies must include at least one policy that matches all traces, to ensure + // that dropping non-matching traces is intentional. Policies []Policy // IngestRateDecayFactor holds the ingest rate decay factor, used for calculating @@ -173,10 +176,17 @@ func (config LocalSamplingConfig) validate() error { if len(config.Policies) == 0 { return errors.New("Policies unspecified") } + var anyDefaultPolicy bool for i, policy := range config.Policies { if err := policy.validate(); err != nil { return errors.Wrapf(err, "Policy %d invalid", i) } + if policy.PolicyCriteria == (PolicyCriteria{}) { + anyDefaultPolicy = true + } + } + if !anyDefaultPolicy { + return errors.New("Policies does not contain a default (empty criteria) policy") } if config.IngestRateDecayFactor <= 0 || config.IngestRateDecayFactor > 1 { return errors.New("IngestRateDecayFactor unspecified or out of range (0,1]") diff --git a/x-pack/apm-server/sampling/config_test.go b/x-pack/apm-server/sampling/config_test.go index 7519dbd06b2..9db7225416f 100644 --- a/x-pack/apm-server/sampling/config_test.go +++ b/x-pack/apm-server/sampling/config_test.go @@ -38,7 +38,11 @@ func TestNewProcessorConfigInvalid(t *testing.T) { config.MaxDynamicServices = 1 assertInvalidConfigError("invalid local sampling config: Policies unspecified") - config.Policies = []sampling.Policy{{}} + config.Policies = []sampling.Policy{{ + PolicyCriteria: sampling.PolicyCriteria{ServiceName: "foo"}, + }} + assertInvalidConfigError("invalid local sampling config: Policies does not contain a default (empty criteria) policy") + config.Policies[0].PolicyCriteria = sampling.PolicyCriteria{} for _, invalid := range []float64{-1, 1.0, 2.0} { config.Policies[0].SampleRate = invalid assertInvalidConfigError("invalid local sampling config: Policy 0 invalid: SampleRate unspecified or out of range [0,1)") diff --git a/x-pack/apm-server/sampling/processor_test.go b/x-pack/apm-server/sampling/processor_test.go index ba412ba8ad3..71422558c05 100644 --- a/x-pack/apm-server/sampling/processor_test.go +++ b/x-pack/apm-server/sampling/processor_test.go @@ -292,6 +292,9 @@ func TestProcessLocalTailSamplingPolicyOrder(t *testing.T) { }, { PolicyCriteria: sampling.PolicyCriteria{ServiceName: "service_name"}, SampleRate: 0.1, + }, { + PolicyCriteria: sampling.PolicyCriteria{}, + SampleRate: 0, }} config.FlushInterval = 10 * time.Millisecond published := make(chan string)