From 510a56bb96fac0972aa578f5db0bfe5feee45c0d Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 9 Oct 2024 14:07:30 -0600 Subject: [PATCH] Remove ccs_telemetry feature flag (#113825) This removes `ccs_telemetry` feature flag, and instead introduces an undocumented, true by default setting: - `search.ccs.collect_telemetry` - enables CCS search telemetry collection and `_cluster/stats?include_remote=true`. Can be disabled if this is causing any problems. --- docs/build.gradle | 1 - docs/changelog/113825.yaml | 12 ++++++++++++ .../cluster/stats/ClusterStatsRemoteIT.java | 8 -------- .../search/ccs/CCSUsageTelemetryIT.java | 8 -------- .../cluster/stats/ClusterStatsResponse.java | 14 +++++--------- .../stats/TransportClusterStatsAction.java | 5 +++-- .../action/search/TransportSearchAction.java | 16 ++++++++-------- .../common/settings/ClusterSettings.java | 1 + .../admin/cluster/RestClusterStatsAction.java | 9 +++------ .../org/elasticsearch/search/SearchService.java | 7 +++++++ .../search/CCSUsageTelemetryAsyncSearchIT.java | 8 -------- .../cluster/ClusterStatsMonitoringDocTests.java | 6 +----- 12 files changed, 40 insertions(+), 55 deletions(-) create mode 100644 docs/changelog/113825.yaml diff --git a/docs/build.gradle b/docs/build.gradle index 8a8d9cde4d1a5..e495ecacce27b 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -123,7 +123,6 @@ testClusters.matching { it.name == "yamlRestTest"}.configureEach { requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0") requiresFeature 'es.failure_store_feature_flag_enabled', Version.fromString("8.12.0") - requiresFeature 'es.ccs_telemetry_feature_flag_enabled', Version.fromString("8.16.0") // TODO Rene: clean up this kind of cross project file references extraConfigFile 'op-jwks.json', project(':x-pack:test:idp-fixture').file("src/main/resources/oidc/op-jwks.json") diff --git a/docs/changelog/113825.yaml b/docs/changelog/113825.yaml new file mode 100644 index 0000000000000..6d4090fda7ed2 --- /dev/null +++ b/docs/changelog/113825.yaml @@ -0,0 +1,12 @@ +pr: 113825 +summary: Cross-cluster search telemetry +area: Search +type: feature +issues: [] +highlight: + title: Cross-cluster search telemetry + body: |- + The cross-cluster search telemetry is collected when cross-cluster searches + are performed, and is returned as "ccs" field in `_cluster/stats` output. + It also add a new parameter `include_remotes=true` to the `_cluster/stats` API + which will collect data from connected remote clusters. diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRemoteIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRemoteIT.java index 81180e291e52a..6cc9824245247 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRemoteIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsRemoteIT.java @@ -14,7 +14,6 @@ import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.FeatureFlag; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; @@ -23,7 +22,6 @@ import org.elasticsearch.test.ESIntegTestCase.Scope; import org.elasticsearch.test.InternalTestCluster; import org.junit.Assert; -import org.junit.BeforeClass; import java.util.Collection; import java.util.List; @@ -46,7 +44,6 @@ public class ClusterStatsRemoteIT extends AbstractMultiClustersTestCase { private static final String REMOTE2 = "cluster-b"; private static final String INDEX_NAME = "demo"; - private static final FeatureFlag CCS_TELEMETRY_FEATURE_FLAG = new FeatureFlag("ccs_telemetry"); @Override protected boolean reuseClusters() { @@ -63,11 +60,6 @@ protected Map skipUnavailableForRemoteClusters() { return Map.of(REMOTE1, false, REMOTE2, true); } - @BeforeClass - protected static void skipIfTelemetryDisabled() { - assumeTrue("Skipping test as CCS_TELEMETRY_FEATURE_FLAG is disabled", CCS_TELEMETRY_FEATURE_FLAG.isEnabled()); - } - public void testRemoteClusterStats() throws ExecutionException, InterruptedException { setupClusters(); final Client client = client(LOCAL_CLUSTER); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CCSUsageTelemetryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CCSUsageTelemetryIT.java index 3f738d08ab93a..c9d34dbf14015 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CCSUsageTelemetryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CCSUsageTelemetryIT.java @@ -25,7 +25,6 @@ import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; -import org.elasticsearch.common.util.FeatureFlag; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.plugins.Plugin; @@ -40,7 +39,6 @@ import org.elasticsearch.test.InternalTestCluster; import org.elasticsearch.usage.UsageService; import org.junit.Assert; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.rules.TestRule; import org.junit.runner.Description; @@ -73,7 +71,6 @@ public class CCSUsageTelemetryIT extends AbstractMultiClustersTestCase { private static final Logger LOGGER = LogManager.getLogger(CCSUsageTelemetryIT.class); private static final String REMOTE1 = "cluster-a"; private static final String REMOTE2 = "cluster-b"; - private static final FeatureFlag CCS_TELEMETRY_FEATURE_FLAG = new FeatureFlag("ccs_telemetry"); @Override protected boolean reuseClusters() { @@ -88,11 +85,6 @@ protected Collection remoteClusterAlias() { @Rule public SkipUnavailableRule skipOverride = new SkipUnavailableRule(REMOTE1, REMOTE2); - @BeforeClass - protected static void skipIfTelemetryDisabled() { - assumeTrue("Skipping test as CCS_TELEMETRY_FEATURE_FLAG is disabled", CCS_TELEMETRY_FEATURE_FLAG.isEnabled()); - } - @Override protected Map skipUnavailableForRemoteClusters() { var map = skipOverride.getMap(); diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java index 1a77a3d4d5399..5f7c45c5807a5 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsResponse.java @@ -28,8 +28,6 @@ import java.util.Map; import java.util.Set; -import static org.elasticsearch.action.search.TransportSearchAction.CCS_TELEMETRY_FEATURE_FLAG; - public class ClusterStatsResponse extends BaseNodesResponse implements ToXContentFragment { final ClusterStatsNodes nodesStats; @@ -145,14 +143,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field("repositories"); repositoryUsageStats.toXContent(builder, params); - if (CCS_TELEMETRY_FEATURE_FLAG.isEnabled()) { - builder.startObject("ccs"); - if (remoteClustersStats != null) { - builder.field("clusters", remoteClustersStats); - } - ccsMetrics.toXContent(builder, params); - builder.endObject(); + builder.startObject("ccs"); + if (remoteClustersStats != null) { + builder.field("clusters", remoteClustersStats); } + ccsMetrics.toXContent(builder, params); + builder.endObject(); return builder; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java index ac875cb7adc51..b132a1177d98a 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java @@ -49,6 +49,7 @@ import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.node.NodeService; import org.elasticsearch.repositories.RepositoriesService; +import org.elasticsearch.search.SearchService; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskId; @@ -431,8 +432,8 @@ public Map getRemoteStats() { } } - private static boolean doRemotes(ClusterStatsRequest request) { - return request.doRemotes(); + private boolean doRemotes(ClusterStatsRequest request) { + return SearchService.CCS_COLLECT_TELEMETRY.get(settings) && request.doRemotes(); } private class RemoteStatsFanout extends CancellableFanOut> { diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java index 553ee1d05a052..1645a378446a4 100644 --- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java +++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java @@ -52,9 +52,9 @@ import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.ArrayUtils; import org.elasticsearch.common.util.CollectionUtils; -import org.elasticsearch.common.util.FeatureFlag; import org.elasticsearch.common.util.Maps; import org.elasticsearch.common.util.concurrent.CountDown; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -128,8 +128,6 @@ public class TransportSearchAction extends HandledTransportAction SHARD_COUNT_LIMIT_SETTING = Setting.longSetting( "action.search.shard_count.limit", @@ -162,6 +160,7 @@ public class TransportSearchAction extends HandledTransportAction 0; + return SearchService.CCS_COLLECT_TELEMETRY.get(settings) && usageBuilder.getRemotesCount() > 0; } public void setRemotes(int count) { diff --git a/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index 69be30b0b5111..8cbacccb915ac 100644 --- a/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -467,6 +467,7 @@ public void apply(Settings value, Settings current, Settings previous) { SearchService.MAX_KEEPALIVE_SETTING, SearchService.ALLOW_EXPENSIVE_QUERIES, SearchService.CCS_VERSION_CHECK_SETTING, + SearchService.CCS_COLLECT_TELEMETRY, MultiBucketConsumerService.MAX_BUCKET_SETTING, SearchService.LOW_LEVEL_CANCELLATION_SETTING, SearchService.MAX_OPEN_SCROLL_CONTEXT, diff --git a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterStatsAction.java b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterStatsAction.java index 6379f6594e7c5..236c3a1be0c32 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterStatsAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestClusterStatsAction.java @@ -11,8 +11,6 @@ import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequest; import org.elasticsearch.client.internal.node.NodeClient; -import org.elasticsearch.common.util.FeatureFlag; -import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.Scope; @@ -33,10 +31,9 @@ public class RestClusterStatsAction extends BaseRestHandler { private static final Set SUPPORTED_CAPABILITIES = Set.of( "human-readable-total-docs-size", - "verbose-dense-vector-mapping-stats" + "verbose-dense-vector-mapping-stats", + "ccs-stats" ); - private static final Set SUPPORTED_CAPABILITIES_CCS_STATS = Set.copyOf(Sets.union(SUPPORTED_CAPABILITIES, Set.of("ccs-stats"))); - public static final FeatureFlag CCS_TELEMETRY_FEATURE_FLAG = new FeatureFlag("ccs_telemetry"); private static final Set SUPPORTED_QUERY_PARAMETERS = Set.of("include_remotes", "nodeId", REST_TIMEOUT_PARAM); @Override @@ -73,6 +70,6 @@ public boolean canTripCircuitBreaker() { @Override public Set supportedCapabilities() { - return CCS_TELEMETRY_FEATURE_FLAG.isEnabled() ? SUPPORTED_CAPABILITIES_CCS_STATS : SUPPORTED_CAPABILITIES; + return SUPPORTED_CAPABILITIES; } } diff --git a/server/src/main/java/org/elasticsearch/search/SearchService.java b/server/src/main/java/org/elasticsearch/search/SearchService.java index 70101bbc7fc54..6fff4318e5b35 100644 --- a/server/src/main/java/org/elasticsearch/search/SearchService.java +++ b/server/src/main/java/org/elasticsearch/search/SearchService.java @@ -260,6 +260,13 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv Property.NodeScope ); + public static final Setting CCS_COLLECT_TELEMETRY = Setting.boolSetting( + "search.ccs.collect_telemetry", + true, + Property.Dynamic, + Property.NodeScope + ); + public static final int DEFAULT_SIZE = 10; public static final int DEFAULT_FROM = 0; diff --git a/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/CCSUsageTelemetryAsyncSearchIT.java b/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/CCSUsageTelemetryAsyncSearchIT.java index 9e17aa25154bb..65f9f13846126 100644 --- a/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/CCSUsageTelemetryAsyncSearchIT.java +++ b/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/CCSUsageTelemetryAsyncSearchIT.java @@ -14,7 +14,6 @@ import org.elasticsearch.action.search.TransportSearchAction; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.FeatureFlag; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.plugins.Plugin; @@ -34,7 +33,6 @@ import org.elasticsearch.xpack.core.search.action.SubmitAsyncSearchRequest; import org.hamcrest.Matchers; import org.junit.Before; -import org.junit.BeforeClass; import java.util.Arrays; import java.util.Collection; @@ -55,12 +53,6 @@ public class CCSUsageTelemetryAsyncSearchIT extends AbstractMultiClustersTestCase { private static final String REMOTE1 = "cluster-a"; private static final String REMOTE2 = "cluster-b"; - private static final FeatureFlag CCS_TELEMETRY_FEATURE_FLAG = new FeatureFlag("ccs_telemetry"); - - @BeforeClass - protected static void skipIfTelemetryDisabled() { - assumeTrue("Skipping test as CCS_TELEMETRY_FEATURE_FLAG is disabled", CCS_TELEMETRY_FEATURE_FLAG.isEnabled()); - } @Override protected boolean reuseClusters() { diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java index 73ceafc0a24b9..c3d502e561bd7 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java @@ -78,7 +78,6 @@ import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; -import static org.elasticsearch.action.search.TransportSearchAction.CCS_TELEMETRY_FEATURE_FLAG; import static org.elasticsearch.common.xcontent.XContentHelper.stripWhitespace; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -847,10 +846,7 @@ public void testToXContent() throws IOException { } } }"""; - assertEquals( - stripWhitespace(Strings.format(expectedJson + (CCS_TELEMETRY_FEATURE_FLAG.isEnabled() ? ccsOutput : "") + suffixJson, args)), - xContent.utf8ToString() - ); + assertEquals(stripWhitespace(Strings.format(expectedJson + ccsOutput + suffixJson, args)), xContent.utf8ToString()); } private DiscoveryNode masterNode() {