From f5e545a8aa9f7828142332b4d224d981786a6e8c Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Sat, 4 Jan 2025 12:25:46 +0100 Subject: [PATCH 1/5] router: make shadow requests inherit parent sampling decision by default Signed-off-by: Rohit Agrawal --- .../config/route/v3/route_components.proto | 5 ++- changelogs/current.yaml | 5 +++ envoy/router/router.h | 5 +++ source/common/router/config_impl.cc | 1 + source/common/router/config_impl.h | 2 + source/common/router/router.cc | 13 ++++-- test/common/router/config_impl_test.cc | 44 +++++++++++++++++++ 7 files changed, 71 insertions(+), 4 deletions(-) diff --git a/api/envoy/config/route/v3/route_components.proto b/api/envoy/config/route/v3/route_components.proto index a3d4d009f0eb..c3cf19e150aa 100644 --- a/api/envoy/config/route/v3/route_components.proto +++ b/api/envoy/config/route/v3/route_components.proto @@ -815,7 +815,10 @@ message RouteAction { // value, the request will be mirrored. core.v3.RuntimeFractionalPercent runtime_fraction = 3; - // Determines if the trace span should be sampled. Defaults to true. + // Specifies whether the trace span for the shadow request should be sampled. If this field is not explicitly set, + // the shadow request will inherit the sampling decision of its parent span. This ensures consistency with the trace + // sampling policy of the original request and prevents oversampling, especially in scenarios where runtime sampling + // is disabled. google.protobuf.BoolValue trace_sampled = 4; // Disables appending the ``-shadow`` suffix to the shadowed ``Host`` header. Defaults to ``false``. diff --git a/changelogs/current.yaml b/changelogs/current.yaml index 909c0053f23d..b6031865d82d 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -117,6 +117,11 @@ minor_behavior_changes: config because existing provider already has up to date routes config. This behavioral change can be temporarily reverted by setting runtime guard ``envoy.reloadable_features.normalize_rds_provider_config`` to false. +- area: router + change: | + Changed the behavior of shadow request sampling so that if trace sampling is not explicitly configured in the shadow + policy, the shadow request will inherit the parent's sampling decision. This means sampling will follow the trace + sampling policy of the original request, which prevents oversampling when runtime sampling is disabled. bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* diff --git a/envoy/router/router.h b/envoy/router/router.h index 2efc01474346..39b92b28037e 100644 --- a/envoy/router/router.h +++ b/envoy/router/router.h @@ -540,6 +540,11 @@ class ShadowPolicy { */ virtual bool traceSampled() const PURE; + /** + * @return true if the config has `trace_sampled` set. + */ + virtual bool hasTraceSampledConf() const PURE; + /** * @return true if host name should be suffixed with "-shadow". */ diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index f158bca8b07c..0b8502db9374 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -490,6 +490,7 @@ ShadowPolicyImpl::ShadowPolicyImpl(const RequestMirrorPolicy& config, absl::Stat default_value_.set_denominator(envoy::type::v3::FractionalPercent::HUNDRED); } trace_sampled_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, trace_sampled, true); + has_trace_sampled_ = config.has_trace_sampled(); } DecoratorImpl::DecoratorImpl(const envoy::config::route::v3::Decorator& decorator) diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index 344a31326ad5..bd44200b7b1c 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -510,6 +510,7 @@ class ShadowPolicyImpl : public ShadowPolicy { const std::string& runtimeKey() const override { return runtime_key_; } const envoy::type::v3::FractionalPercent& defaultValue() const override { return default_value_; } bool traceSampled() const override { return trace_sampled_; } + bool hasTraceSampledConf() const override { return has_trace_sampled_; } bool disableShadowHostSuffixAppend() const override { return disable_shadow_host_suffix_append_; } private: @@ -520,6 +521,7 @@ class ShadowPolicyImpl : public ShadowPolicy { std::string runtime_key_; envoy::type::v3::FractionalPercent default_value_; bool trace_sampled_; + bool has_trace_sampled_; const bool disable_shadow_host_suffix_append_; }; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index 7be5ba569780..bf881769658c 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -444,6 +444,14 @@ void Filter::chargeUpstreamCode(Http::Code code, chargeUpstreamCode(response_status_code, *fake_response_headers, upstream_host, dropped); } +absl::optional getSampleValueFromShadowPolicy(const ShadowPolicy& shadow_policy) { + // If trace sampling is not explicitly configured in shadow_policy, we pass null optional to + // inherit the parent's sampling decision. This prevents oversampling when runtime sampling is + // disabled. + return shadow_policy.hasTraceSampledConf() ? absl::make_optional(shadow_policy.traceSampled()) + : absl::nullopt; +} + Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { downstream_headers_ = &headers; @@ -802,7 +810,7 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, .setTimeout(timeout_.global_timeout_) .setParentSpan(callbacks_->activeSpan()) .setChildSpanName("mirror") - .setSampled(shadow_policy.traceSampled()) + .setSampled(getSampleValueFromShadowPolicy(shadow_policy)) .setIsShadow(true) .setIsShadowSuffixDisabled(shadow_policy.disableShadowHostSuffixAppend()) .setBufferAccount(callbacks_->account()) @@ -1066,12 +1074,11 @@ void Filter::maybeDoShadowing() { if (shadow_trailers_) { request->trailers(Http::createHeaderMap(*shadow_trailers_)); } - auto options = Http::AsyncClient::RequestOptions() .setTimeout(timeout_.global_timeout_) .setParentSpan(callbacks_->activeSpan()) .setChildSpanName("mirror") - .setSampled(shadow_policy.traceSampled()) + .setSampled(getSampleValueFromShadowPolicy(shadow_policy)) .setIsShadow(true) .setIsShadowSuffixDisabled(shadow_policy.disableShadowHostSuffixAppend()); options.setFilterConfig(config_); diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 8a25c063734f..744080a2b2ff 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -11542,6 +11542,50 @@ TEST_F(CommonConfigImplTest, TestCommonConfig) { shared_config.ignorePathParametersInPathMatching()); } +TEST_F(RouteMatcherTest, RequestMirrorPoliciesWithTraceSampled) { + const std::string yaml = R"EOF( +virtual_hosts: +- name: www2 + domains: ["*"] + routes: + - match: + prefix: "/foo" + route: + request_mirror_policies: + # Policy with explicit trace_sampled set to false + - cluster: some_cluster + trace_sampled: false + # Policy with explicit trace_sampled set to true + - cluster: some_cluster2 + trace_sampled: true + # Policy with no trace_sampled specified (should default to true) + - cluster: some_cluster3 + cluster: www2 + )EOF"; + + factory_context_.cluster_manager_.initializeClusters( + {"www2", "some_cluster", "some_cluster2", "some_cluster3"}, {}); + TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); + + { + Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/foo", "GET"); + const auto& shadow_policies = config.route(headers, 0)->routeEntry()->shadowPolicies(); + + // First policy should have trace sampled = false + EXPECT_TRUE(shadow_policies[0]->hasTraceSampledConf()); + EXPECT_FALSE(shadow_policies[0]->traceSampled()); + + // Second policy should have trace sampled = true + EXPECT_TRUE(shadow_policies[1]->hasTraceSampledConf()); + EXPECT_TRUE(shadow_policies[1]->traceSampled()); + + // Since the config is unspecified for the third policy, trace sampled should default to true + EXPECT_FALSE(shadow_policies[2]->hasTraceSampledConf()); + EXPECT_TRUE(shadow_policies[2]->traceSampled()); + } +} + } // namespace } // namespace Router } // namespace Envoy From 4cb8cfc82599e613a2ead2d6f043f5937f55f10e Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Mon, 6 Jan 2025 12:32:00 +0100 Subject: [PATCH 2/5] addressed comments from @wbpcode Signed-off-by: Rohit Agrawal --- changelogs/current.yaml | 4 +- ci/do_ci.sh | 2 +- envoy/router/router.h | 7 +--- source/common/router/config_impl.cc | 16 ++++++-- source/common/router/config_impl.h | 6 +-- source/common/router/router.cc | 6 +-- test/common/router/config_impl_test.cc | 52 ++++++++++++++++++++------ 7 files changed, 62 insertions(+), 31 deletions(-) diff --git a/changelogs/current.yaml b/changelogs/current.yaml index b6031865d82d..1f9ef7f9d7df 100644 --- a/changelogs/current.yaml +++ b/changelogs/current.yaml @@ -121,7 +121,9 @@ minor_behavior_changes: change: | Changed the behavior of shadow request sampling so that if trace sampling is not explicitly configured in the shadow policy, the shadow request will inherit the parent's sampling decision. This means sampling will follow the trace - sampling policy of the original request, which prevents oversampling when runtime sampling is disabled. + sampling policy of the original request, which prevents oversampling when runtime sampling is disabled. This + behavior can be temporarily reverted by setting the runtime guard + ``envoy.reloadable_features.shadow_policy_inherit_trace_sampling`` to ``false``. bug_fixes: # *Changes expected to improve the state of the world and are unlikely to have negative effects* diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 8cb7a1337599..0f26de00adf6 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -434,7 +434,7 @@ case $CI_TARGET in # Make sure that there are no regressions to building Envoy with autolink disabled. EXTRA_OPTIONS=( "--define" "library_autolink=disabled") - bazel test "${BAZEL_BUILD_OPTIONS[@]}" \ + bazel run "${BAZEL_BUILD_OPTIONS[@]}" \ "${EXTRA_OPTIONS[@]}" \ -c dbg \ "${TEST_TARGETS[@]}" diff --git a/envoy/router/router.h b/envoy/router/router.h index 39b92b28037e..af94e4dbd5d7 100644 --- a/envoy/router/router.h +++ b/envoy/router/router.h @@ -538,12 +538,7 @@ class ShadowPolicy { /** * @return true if the trace span should be sampled. */ - virtual bool traceSampled() const PURE; - - /** - * @return true if the config has `trace_sampled` set. - */ - virtual bool hasTraceSampledConf() const PURE; + virtual absl::optional traceSampled() const PURE; /** * @return true if host name should be suffixed with "-shadow". diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 0b8502db9374..f9e537e8bce4 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -489,8 +489,18 @@ ShadowPolicyImpl::ShadowPolicyImpl(const RequestMirrorPolicy& config, absl::Stat default_value_.set_numerator(100); default_value_.set_denominator(envoy::type::v3::FractionalPercent::HUNDRED); } - trace_sampled_ = PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, trace_sampled, true); - has_trace_sampled_ = config.has_trace_sampled(); + // If trace sampling is not explicitly configured in shadow_policy, we pass null optional to + // inherit the parent's sampling decision. This prevents oversampling when runtime sampling is + // disabled. + if (config.has_trace_sampled()) { + trace_sampled_ = absl::optional(config.trace_sampled().value()); + } else { + // If the shadow policy does not specify trace_sampled, we will inherit the parent's sampling + // decision. + const bool user_parent_sampling_decision = Runtime::runtimeFeatureEnabled( + "envoy.reloadable_features.shadow_policy_inherit_trace_sampling"); + trace_sampled_ = user_parent_sampling_decision ? absl::nullopt : absl::make_optional(true); + } } DecoratorImpl::DecoratorImpl(const envoy::config::route::v3::Decorator& decorator) @@ -1632,7 +1642,7 @@ UriTemplateMatcherRouteEntryImpl::UriTemplateMatcherRouteEntryImpl( Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator, absl::Status& creation_status) : RouteEntryImplBase(vhost, route, factory_context, validator, creation_status), - uri_template_(path_matcher_->uriTemplate()){}; + uri_template_(path_matcher_->uriTemplate()) {}; void UriTemplateMatcherRouteEntryImpl::rewritePathHeader(Http::RequestHeaderMap& headers, bool insert_envoy_original_path) const { diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h index bd44200b7b1c..4fded280a1c8 100644 --- a/source/common/router/config_impl.h +++ b/source/common/router/config_impl.h @@ -509,8 +509,7 @@ class ShadowPolicyImpl : public ShadowPolicy { const Http::LowerCaseString& clusterHeader() const override { return cluster_header_; } const std::string& runtimeKey() const override { return runtime_key_; } const envoy::type::v3::FractionalPercent& defaultValue() const override { return default_value_; } - bool traceSampled() const override { return trace_sampled_; } - bool hasTraceSampledConf() const override { return has_trace_sampled_; } + absl::optional traceSampled() const override { return trace_sampled_; } bool disableShadowHostSuffixAppend() const override { return disable_shadow_host_suffix_append_; } private: @@ -520,8 +519,7 @@ class ShadowPolicyImpl : public ShadowPolicy { const Http::LowerCaseString cluster_header_; std::string runtime_key_; envoy::type::v3::FractionalPercent default_value_; - bool trace_sampled_; - bool has_trace_sampled_; + absl::optional trace_sampled_; const bool disable_shadow_host_suffix_append_; }; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index bf881769658c..0a42e803fef4 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -445,11 +445,7 @@ void Filter::chargeUpstreamCode(Http::Code code, } absl::optional getSampleValueFromShadowPolicy(const ShadowPolicy& shadow_policy) { - // If trace sampling is not explicitly configured in shadow_policy, we pass null optional to - // inherit the parent's sampling decision. This prevents oversampling when runtime sampling is - // disabled. - return shadow_policy.hasTraceSampledConf() ? absl::make_optional(shadow_policy.traceSampled()) - : absl::nullopt; + return shadow_policy.traceSampled(); } Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 744080a2b2ff..8d3ba44ee7cf 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -11558,31 +11558,61 @@ TEST_F(RouteMatcherTest, RequestMirrorPoliciesWithTraceSampled) { # Policy with explicit trace_sampled set to true - cluster: some_cluster2 trace_sampled: true - # Policy with no trace_sampled specified (should default to true) + # Policy with no trace_sampled specified - cluster: some_cluster3 cluster: www2 )EOF"; factory_context_.cluster_manager_.initializeClusters( {"www2", "some_cluster", "some_cluster2", "some_cluster3"}, {}); - TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, - creation_status_); + // Test with runtime flag disabled (old behavior) { - Http::TestRequestHeaderMapImpl headers = genHeaders("www.lyft.com", "/foo", "GET"); + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.shadow_policy_inherit_trace_sampling", "false"}}); + + TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); + + Http::TestRequestHeaderMapImpl headers = genHeaders("www.databricks.com", "/foo", "GET"); + const auto& shadow_policies = config.route(headers, 0)->routeEntry()->shadowPolicies(); + + // First policy should have trace sampled = false + EXPECT_TRUE(shadow_policies[0]->traceSampled().has_value()); + EXPECT_FALSE(shadow_policies[0]->traceSampled().value()); + + // Second policy should have trace sampled = true + EXPECT_TRUE(shadow_policies[1]->traceSampled().has_value()); + EXPECT_TRUE(shadow_policies[1]->traceSampled().value()); + + // With flag disabled, unspecified should default to true + EXPECT_TRUE(shadow_policies[2]->traceSampled().has_value()); + EXPECT_TRUE(shadow_policies[2]->traceSampled().value()); + } + + // Test with runtime flag enabled (new behavior) + { + TestScopedRuntime scoped_runtime; + scoped_runtime.mergeValues( + {{"envoy.reloadable_features.shadow_policy_inherit_trace_sampling", "true"}}); + + TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true, + creation_status_); + + Http::TestRequestHeaderMapImpl headers = genHeaders("www.databricks.com", "/foo", "GET"); const auto& shadow_policies = config.route(headers, 0)->routeEntry()->shadowPolicies(); // First policy should have trace sampled = false - EXPECT_TRUE(shadow_policies[0]->hasTraceSampledConf()); - EXPECT_FALSE(shadow_policies[0]->traceSampled()); + EXPECT_TRUE(shadow_policies[0]->traceSampled().has_value()); + EXPECT_FALSE(shadow_policies[0]->traceSampled().value()); // Second policy should have trace sampled = true - EXPECT_TRUE(shadow_policies[1]->hasTraceSampledConf()); - EXPECT_TRUE(shadow_policies[1]->traceSampled()); + EXPECT_TRUE(shadow_policies[1]->traceSampled().has_value()); + EXPECT_TRUE(shadow_policies[1]->traceSampled().value()); - // Since the config is unspecified for the third policy, trace sampled should default to true - EXPECT_FALSE(shadow_policies[2]->hasTraceSampledConf()); - EXPECT_TRUE(shadow_policies[2]->traceSampled()); + // With flag enabled, unspecified should be nullopt + EXPECT_FALSE(shadow_policies[2]->traceSampled().has_value()); } } From 87bed35843f5501696664a89ff73c49af164bfd8 Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Mon, 6 Jan 2025 12:58:13 +0100 Subject: [PATCH 3/5] fixes Signed-off-by: Rohit Agrawal --- ci/do_ci.sh | 2 +- source/common/router/config_impl.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 0f26de00adf6..8cb7a1337599 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -434,7 +434,7 @@ case $CI_TARGET in # Make sure that there are no regressions to building Envoy with autolink disabled. EXTRA_OPTIONS=( "--define" "library_autolink=disabled") - bazel run "${BAZEL_BUILD_OPTIONS[@]}" \ + bazel test "${BAZEL_BUILD_OPTIONS[@]}" \ "${EXTRA_OPTIONS[@]}" \ -c dbg \ "${TEST_TARGETS[@]}" diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index f9e537e8bce4..5f662f06a2f2 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -1642,7 +1642,7 @@ UriTemplateMatcherRouteEntryImpl::UriTemplateMatcherRouteEntryImpl( Server::Configuration::ServerFactoryContext& factory_context, ProtobufMessage::ValidationVisitor& validator, absl::Status& creation_status) : RouteEntryImplBase(vhost, route, factory_context, validator, creation_status), - uri_template_(path_matcher_->uriTemplate()) {}; + uri_template_(path_matcher_->uriTemplate()){}; void UriTemplateMatcherRouteEntryImpl::rewritePathHeader(Http::RequestHeaderMap& headers, bool insert_envoy_original_path) const { From ce1480ce909a5e2da98941c3881c50cecda27508 Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Mon, 6 Jan 2025 14:14:07 +0100 Subject: [PATCH 4/5] more fixes Signed-off-by: Rohit Agrawal --- source/common/runtime/runtime_features.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc index c1d277f38000..1c61f2fc22de 100644 --- a/source/common/runtime/runtime_features.cc +++ b/source/common/runtime/runtime_features.cc @@ -87,6 +87,7 @@ RUNTIME_GUARD(envoy_reloadable_features_reject_invalid_yaml); RUNTIME_GUARD(envoy_reloadable_features_report_stream_reset_error_code); RUNTIME_GUARD(envoy_reloadable_features_sanitize_http2_headers_without_nghttp2); RUNTIME_GUARD(envoy_reloadable_features_sanitize_sni_in_access_log); +RUNTIME_GUARD(envoy_reloadable_features_shadow_policy_inherit_trace_sampling); RUNTIME_GUARD(envoy_reloadable_features_skip_dns_lookup_for_proxied_requests); RUNTIME_GUARD(envoy_reloadable_features_streaming_shadow); RUNTIME_GUARD(envoy_reloadable_features_strict_duration_validation); From bacb67b41086a1e3b5bb21440edf0ca48252c564 Mon Sep 17 00:00:00 2001 From: Rohit Agrawal Date: Wed, 8 Jan 2025 13:48:24 +0100 Subject: [PATCH 5/5] addressed comments from @wbpcode Signed-off-by: Rohit Agrawal --- source/common/router/config_impl.cc | 2 +- source/common/router/router.cc | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc index 5f662f06a2f2..af14c75da675 100644 --- a/source/common/router/config_impl.cc +++ b/source/common/router/config_impl.cc @@ -493,7 +493,7 @@ ShadowPolicyImpl::ShadowPolicyImpl(const RequestMirrorPolicy& config, absl::Stat // inherit the parent's sampling decision. This prevents oversampling when runtime sampling is // disabled. if (config.has_trace_sampled()) { - trace_sampled_ = absl::optional(config.trace_sampled().value()); + trace_sampled_ = config.trace_sampled().value(); } else { // If the shadow policy does not specify trace_sampled, we will inherit the parent's sampling // decision. diff --git a/source/common/router/router.cc b/source/common/router/router.cc index dac64d5cad4a..b37eb8b3159b 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -442,10 +442,6 @@ void Filter::chargeUpstreamCode(Http::Code code, Upstream::HostDescriptionOptCon chargeUpstreamCode(response_status_code, *fake_response_headers, upstream_host, dropped); } -absl::optional getSampleValueFromShadowPolicy(const ShadowPolicy& shadow_policy) { - return shadow_policy.traceSampled(); -} - Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, bool end_stream) { downstream_headers_ = &headers; @@ -804,7 +800,7 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers, .setTimeout(timeout_.global_timeout_) .setParentSpan(callbacks_->activeSpan()) .setChildSpanName("mirror") - .setSampled(getSampleValueFromShadowPolicy(shadow_policy)) + .setSampled(shadow_policy.traceSampled()) .setIsShadow(true) .setIsShadowSuffixDisabled(shadow_policy.disableShadowHostSuffixAppend()) .setBufferAccount(callbacks_->account()) @@ -1072,7 +1068,7 @@ void Filter::maybeDoShadowing() { .setTimeout(timeout_.global_timeout_) .setParentSpan(callbacks_->activeSpan()) .setChildSpanName("mirror") - .setSampled(getSampleValueFromShadowPolicy(shadow_policy)) + .setSampled(shadow_policy.traceSampled()) .setIsShadow(true) .setIsShadowSuffixDisabled(shadow_policy.disableShadowHostSuffixAppend()); options.setFilterConfig(config_);