diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index e1b960c78b8a0..7f7a869e2f472 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -1209,6 +1209,10 @@ public enum Cap { * Views with branching (requires subqueries/FORK). */ VIEWS_WITH_BRANCHING(VIEWS_WITH_NO_BRANCHING.isEnabled() && SUBQUERY_IN_FROM_COMMAND.isEnabled()), + /** + * Added telemetry for views + */ + VIEWS_TELEMETRY, /** * Support for the {@code leading_zeros} named parameter. diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java index 8783c6f2075b2..1b91feb12d893 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java @@ -98,6 +98,7 @@ import org.elasticsearch.xpack.esql.planner.premapper.PreMapper; import org.elasticsearch.xpack.esql.plugin.ComputeService; import org.elasticsearch.xpack.esql.plugin.TransportActionServices; +import org.elasticsearch.xpack.esql.telemetry.FeatureMetric; import org.elasticsearch.xpack.esql.telemetry.Metrics; import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; import org.elasticsearch.xpack.esql.view.ViewResolver; @@ -276,7 +277,13 @@ private void analyseAndExecute( ActionListener> listener ) { assert ThreadPool.assertCurrentThreadPool(ThreadPool.Names.SEARCH); + + // this is stack telemetry + gatherViewMetrics(viewResolution); + + // this is APM gatherPlanTelemetry(viewResolution.plan(), statement.settings()); + PlanTimeProfile planTimeProfile = request.profile() ? new PlanTimeProfile() : null; ZoneId timeZone = request.timeZone() == null @@ -761,6 +768,13 @@ private void gatherSettingsMetrics(EsqlStatement statement) { statement.settings().stream().map(QuerySetting::name).distinct().forEach(metrics::incSetting); } + private void gatherViewMetrics(ViewResolver.ViewResolutionResult viewResolution) { + if (metrics == null || viewResolution.viewQueries().isEmpty()) { + return; + } + metrics.inc(FeatureMetric.VIEW); + } + /** * Associates errors that occurred during field-caps with the cluster info in the execution info. * - Skips clusters that are no longer running, as they have already been marked as successful, skipped, or failed. diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java index adaab55378fc2..9f8e1fdda20de 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java @@ -104,6 +104,7 @@ public enum FeatureMetric { COMPLETION(Completion.class::isInstance), SAMPLE(Sample.class::isInstance), SUBQUERY(Subquery.class::isInstance), + VIEW(plan -> false), // Views are counted in EsqlSession.gatherViewMetrics, not via plan traversal MMR(MMR.class::isInstance), PROMQL(PromqlCommand.class::isInstance), URI_PARTS(UriParts.class::isInstance), diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml index 0a77d1691d91d..01cbdda490857 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml @@ -97,6 +97,7 @@ setup: - set: { esql.features.completion: completion_counter } - set: { esql.features.sample: sample_counter } - set: { esql.features.subquery: subquery_counter } + - set: { esql.features.view: view_counter } - set: { esql.features.uri_parts: uri_parts_counter } - set: { esql.features.registered_domain: registered_domain_counter } - set: { esql.features.mmr: mmr_counter } @@ -407,3 +408,40 @@ took: - exists: esql.took.lt_10h - exists: esql.took.lt_1d - exists: esql.took.gt_1d + +--- +"Views telemetry (snapshot only)": + - requires: + test_runner_features: [ capabilities ] + capabilities: + - method: POST + path: /_query + parameters: [ ] + capabilities: [ views_telemetry ] + - method: GET + path: /_query/view + capabilities: [ view_index_abstraction ] + reason: "Views telemetry test requires snapshot build with views enabled" + + - do: { xpack.usage: { } } + - set: { esql.features.view: view_counter } + - set: { esql.features.subquery: subquery_counter } + + - do: + esql.put_view: + name: test_view_for_telemetry + body: + query: 'FROM test | WHERE data > 0' + + - do: + esql.query: + body: + query: 'FROM test_view_for_telemetry | LIMIT 10' + + - do: { xpack.usage: { } } + - gt: { esql.features.view: $view_counter } + - match: { esql.features.subquery: $subquery_counter } + + - do: + esql.delete_view: + name: test_view_for_telemetry