From a0b18d8d02b59770ea71e02423a170e19d3c4ad7 Mon Sep 17 00:00:00 2001 From: Alexander Spies Date: Tue, 28 Jan 2025 14:47:49 +0100 Subject: [PATCH] Revert "ESQL: Implement a MetricsAware interface (#120527)" This reverts commit a4482d4c4c2d24418553510afa6a11a5f316983a. --- docs/changelog/120527.yaml | 6 -- .../xpack/esql/EsqlTestUtils.java | 2 +- .../xpack/esql/action/TelemetryIT.java | 35 ++++------ .../xpack/esql/analysis/Analyzer.java | 8 +-- .../xpack/esql/analysis/Verifier.java | 4 +- .../esql/capabilities/TelemetryAware.java | 23 ------- .../xpack/esql/execution/PlanExecutor.java | 20 +++--- .../function/EsqlFunctionRegistry.java | 15 ---- .../xpack/esql/parser/AstBuilder.java | 4 +- .../xpack/esql/parser/EsqlParser.java | 13 +--- .../xpack/esql/parser/ExpressionBuilder.java | 39 ++++------- .../xpack/esql/parser/LogicalPlanBuilder.java | 16 ++--- .../xpack/esql/plan/logical/Aggregate.java | 5 +- .../xpack/esql/plan/logical/Dissect.java | 8 ++- .../xpack/esql/plan/logical/Drop.java | 7 +- .../xpack/esql/plan/logical/Enrich.java | 7 +- .../xpack/esql/plan/logical/EsRelation.java | 5 ++ .../xpack/esql/plan/logical/Eval.java | 8 ++- .../xpack/esql/plan/logical/Explain.java | 8 ++- .../xpack/esql/plan/logical/Filter.java | 5 +- .../xpack/esql/plan/logical/Grok.java | 8 ++- .../xpack/esql/plan/logical/InlineStats.java | 8 ++- .../xpack/esql/plan/logical/Keep.java | 8 ++- .../xpack/esql/plan/logical/Limit.java | 8 ++- .../xpack/esql/plan/logical/LogicalPlan.java | 2 + .../xpack/esql/plan/logical/Lookup.java | 8 ++- .../xpack/esql/plan/logical/MvExpand.java | 5 +- .../xpack/esql/plan/logical/OrderBy.java | 5 +- .../xpack/esql/plan/logical/Project.java | 8 +++ .../xpack/esql/plan/logical/Rename.java | 8 ++- .../xpack/esql/plan/logical/Row.java | 8 ++- .../xpack/esql/plan/logical/TopN.java | 7 ++ .../esql/plan/logical/UnresolvedRelation.java | 19 +----- .../xpack/esql/plan/logical/join/Join.java | 5 ++ .../esql/plan/logical/join/LookupJoin.java | 8 +-- .../esql/plan/logical/join/StubRelation.java | 5 ++ .../plan/logical/local/LocalRelation.java | 8 +++ .../esql/plan/logical/show/ShowInfo.java | 5 +- .../xpack/esql/session/EsqlSession.java | 11 +-- .../{telemetry => stats}/FeatureMetric.java | 2 +- .../esql/{telemetry => stats}/Metrics.java | 2 +- .../xpack/esql/stats/PlanningMetrics.java | 41 +++++++++++ .../PlanningMetricsManager.java} | 12 ++-- .../{telemetry => stats}/QueryMetric.java | 2 +- .../xpack/esql/telemetry/PlanTelemetry.java | 68 ------------------- .../elasticsearch/xpack/esql/CsvTests.java | 4 +- .../function/CheckLicenseTests.java | 2 +- .../LocalLogicalPlanOptimizerTests.java | 5 ++ .../LocalPhysicalPlanOptimizerTests.java | 2 +- .../esql/planner/QueryTranslatorTests.java | 2 +- .../PlanExecutorMetricsTests.java | 2 +- .../VerifierMetricsTests.java | 36 +++++----- 52 files changed, 265 insertions(+), 297 deletions(-) delete mode 100644 docs/changelog/120527.yaml delete mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/TelemetryAware.java rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/{telemetry => stats}/FeatureMetric.java (98%) rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/{telemetry => stats}/Metrics.java (99%) create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/{telemetry/PlanTelemetryManager.java => stats/PlanningMetricsManager.java} (89%) rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/{telemetry => stats}/QueryMetric.java (93%) delete mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java rename x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/{telemetry => stats}/PlanExecutorMetricsTests.java (99%) rename x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/{telemetry => stats}/VerifierMetricsTests.java (93%) diff --git a/docs/changelog/120527.yaml b/docs/changelog/120527.yaml deleted file mode 100644 index a8e8088ea2aba..0000000000000 --- a/docs/changelog/120527.yaml +++ /dev/null @@ -1,6 +0,0 @@ -pr: 120527 -summary: Implement a `MetricsAware` interface -area: ES|QL -type: enhancement -issues: - - 115992 diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java index 01195e0040a75..f3b2ea0d864ff 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java @@ -73,8 +73,8 @@ import org.elasticsearch.xpack.esql.plugin.QueryPragmas; import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; +import org.elasticsearch.xpack.esql.stats.Metrics; import org.elasticsearch.xpack.esql.stats.SearchStats; -import org.elasticsearch.xpack.esql.telemetry.Metrics; import org.elasticsearch.xpack.versionfield.Version; import org.junit.Assert; diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/TelemetryIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/TelemetryIT.java index a27b64044ca9c..25603acece3cb 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/TelemetryIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/TelemetryIT.java @@ -20,7 +20,7 @@ import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.telemetry.Measurement; import org.elasticsearch.telemetry.TestTelemetryPlugin; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetryManager; +import org.elasticsearch.xpack.esql.stats.PlanningMetricsManager; import org.junit.Before; import java.util.Collection; @@ -113,17 +113,6 @@ public static Iterable parameters() { Map.ofEntries(Map.entry("TO_IP", 1), Map.entry("TO_STRING", 2)), true ) }, - new Object[] { - new Test( - // Using the `::` cast operator and a function alias - """ - FROM idx - | EVAL ip = host::ip::string, y = to_str(host) - """, - Map.ofEntries(Map.entry("FROM", 1), Map.entry("EVAL", 1)), - Map.ofEntries(Map.entry("TO_IP", 1), Map.entry("TO_STRING", 2)), - true - ) }, new Object[] { new Test( "METRICS idx | LIMIT 10", @@ -134,7 +123,9 @@ public static Iterable parameters() { new Object[] { new Test( "METRICS idx max(id) BY host | LIMIT 10", - Build.current().isSnapshot() ? Map.ofEntries(Map.entry("METRICS", 1), Map.entry("LIMIT", 1)) : Collections.emptyMap(), + Build.current().isSnapshot() + ? Map.ofEntries(Map.entry("METRICS", 1), Map.entry("LIMIT", 1), Map.entry("FROM TS", 1)) + : Collections.emptyMap(), Build.current().isSnapshot() ? Map.ofEntries(Map.entry("MAX", 1)) : Collections.emptyMap(), Build.current().isSnapshot() ) } @@ -147,7 +138,7 @@ public static Iterable parameters() { // | EVAL ip = to_ip(host), x = to_string(host), y = to_string(host) // | INLINESTATS max(id) // """, - // Build.current().isSnapshot() ? Map.of("FROM", 1, "EVAL", 1, "INLINESTATS", 1) : Collections.emptyMap(), + // Build.current().isSnapshot() ? Map.of("FROM", 1, "EVAL", 1, "INLINESTATS", 1, "STATS", 1) : Collections.emptyMap(), // Build.current().isSnapshot() // ? Map.ofEntries(Map.entry("MAX", 1), Map.entry("TO_IP", 1), Map.entry("TO_STRING", 2)) // : Collections.emptyMap(), @@ -195,19 +186,19 @@ private static void testQuery( client(dataNode.getName()).execute(EsqlQueryAction.INSTANCE, request, ActionListener.running(() -> { try { // test total commands used - final List commandMeasurementsAll = measurements(plugin, PlanTelemetryManager.FEATURE_METRICS_ALL); + final List commandMeasurementsAll = measurements(plugin, PlanningMetricsManager.FEATURE_METRICS_ALL); assertAllUsages(expectedCommands, commandMeasurementsAll, iteration, success); // test num of queries using a command - final List commandMeasurements = measurements(plugin, PlanTelemetryManager.FEATURE_METRICS); + final List commandMeasurements = measurements(plugin, PlanningMetricsManager.FEATURE_METRICS); assertUsageInQuery(expectedCommands, commandMeasurements, iteration, success); // test total functions used - final List functionMeasurementsAll = measurements(plugin, PlanTelemetryManager.FUNCTION_METRICS_ALL); + final List functionMeasurementsAll = measurements(plugin, PlanningMetricsManager.FUNCTION_METRICS_ALL); assertAllUsages(expectedFunctions, functionMeasurementsAll, iteration, success); // test number of queries using a function - final List functionMeasurements = measurements(plugin, PlanTelemetryManager.FUNCTION_METRICS); + final List functionMeasurements = measurements(plugin, PlanningMetricsManager.FUNCTION_METRICS); assertUsageInQuery(expectedFunctions, functionMeasurements, iteration, success); } finally { latch.countDown(); @@ -225,8 +216,8 @@ private static void assertAllUsages(Map expected, List found = featureNames(metrics); assertThat(found, is(expected.keySet())); for (Measurement metric : metrics) { - assertThat(metric.attributes().get(PlanTelemetryManager.SUCCESS), is(success)); - String featureName = (String) metric.attributes().get(PlanTelemetryManager.FEATURE_NAME); + assertThat(metric.attributes().get(PlanningMetricsManager.SUCCESS), is(success)); + String featureName = (String) metric.attributes().get(PlanningMetricsManager.FEATURE_NAME); assertThat(metric.getLong(), is(iteration * expected.get(featureName))); } } @@ -236,7 +227,7 @@ private static void assertUsageInQuery(Map expected, List measurements(TestTelemetryPlugin plugin, String private static Set featureNames(List functionMeasurements) { return functionMeasurements.stream() - .map(x -> x.attributes().get(PlanTelemetryManager.FEATURE_NAME)) + .map(x -> x.attributes().get(PlanningMetricsManager.FEATURE_NAME)) .map(String.class::cast) .collect(Collectors.toSet()); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java index 812080085b5a7..4f5ff35b84054 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java @@ -92,7 +92,7 @@ import org.elasticsearch.xpack.esql.rule.Rule; import org.elasticsearch.xpack.esql.rule.RuleExecutor; import org.elasticsearch.xpack.esql.session.Configuration; -import org.elasticsearch.xpack.esql.telemetry.FeatureMetric; +import org.elasticsearch.xpack.esql.stats.FeatureMetric; import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import java.time.Duration; @@ -133,7 +133,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.TIME_DURATION; import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION; import static org.elasticsearch.xpack.esql.core.type.DataType.isTemporalAmount; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.LIMIT; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.LIMIT; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.maybeParseTemporalAmount; /** @@ -220,7 +220,7 @@ private LogicalPlan resolveIndex(UnresolvedRelation plan, IndexResolution indexR plan.metadataFields(), plan.indexMode(), indexResolutionMessage, - plan.telemetryLabel() + plan.commandName() ); } IndexPattern table = plan.indexPattern(); @@ -233,7 +233,7 @@ private LogicalPlan resolveIndex(UnresolvedRelation plan, IndexResolution indexR plan.metadataFields(), plan.indexMode(), "invalid [" + table + "] resolution to [" + indexResolution + "]", - plan.telemetryLabel() + plan.commandName() ); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java index c2663650685eb..b59a112b1adb6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java @@ -32,8 +32,8 @@ import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; import org.elasticsearch.xpack.esql.plan.logical.Lookup; import org.elasticsearch.xpack.esql.plan.logical.Project; -import org.elasticsearch.xpack.esql.telemetry.FeatureMetric; -import org.elasticsearch.xpack.esql.telemetry.Metrics; +import org.elasticsearch.xpack.esql.stats.FeatureMetric; +import org.elasticsearch.xpack.esql.stats.Metrics; import java.util.ArrayList; import java.util.BitSet; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/TelemetryAware.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/TelemetryAware.java deleted file mode 100644 index 9116c18b7a9bc..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/capabilities/TelemetryAware.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.capabilities; - -import java.util.Locale; - -/** - * Interface for plan nodes that need to be accounted in the statistics - */ -public interface TelemetryAware { - - /** - * @return the label reported in the telemetry data. Only needs to be overwritten if the label doesn't match the class name. - */ - default String telemetryLabel() { - return getClass().getSimpleName().toUpperCase(Locale.ROOT); - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java index 81f63fd9d37a6..94913581f696d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java @@ -26,10 +26,10 @@ import org.elasticsearch.xpack.esql.session.IndexResolver; import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; import org.elasticsearch.xpack.esql.session.Result; -import org.elasticsearch.xpack.esql.telemetry.Metrics; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetryManager; -import org.elasticsearch.xpack.esql.telemetry.QueryMetric; +import org.elasticsearch.xpack.esql.stats.Metrics; +import org.elasticsearch.xpack.esql.stats.PlanningMetrics; +import org.elasticsearch.xpack.esql.stats.PlanningMetricsManager; +import org.elasticsearch.xpack.esql.stats.QueryMetric; import static org.elasticsearch.action.ActionListener.wrap; @@ -41,7 +41,7 @@ public class PlanExecutor { private final Mapper mapper; private final Metrics metrics; private final Verifier verifier; - private final PlanTelemetryManager planTelemetryManager; + private final PlanningMetricsManager planningMetricsManager; public PlanExecutor(IndexResolver indexResolver, MeterRegistry meterRegistry, XPackLicenseState licenseState) { this.indexResolver = indexResolver; @@ -50,7 +50,7 @@ public PlanExecutor(IndexResolver indexResolver, MeterRegistry meterRegistry, XP this.mapper = new Mapper(); this.metrics = new Metrics(functionRegistry); this.verifier = new Verifier(metrics, licenseState); - this.planTelemetryManager = new PlanTelemetryManager(meterRegistry); + this.planningMetricsManager = new PlanningMetricsManager(meterRegistry); } public void esql( @@ -65,7 +65,7 @@ public void esql( QueryBuilderResolver queryBuilderResolver, ActionListener listener ) { - final PlanTelemetry planTelemetry = new PlanTelemetry(functionRegistry); + final PlanningMetrics planningMetrics = new PlanningMetrics(); final var session = new EsqlSession( sessionId, cfg, @@ -76,7 +76,7 @@ public void esql( new LogicalPlanOptimizer(new LogicalOptimizerContext(cfg, foldContext)), mapper, verifier, - planTelemetry, + planningMetrics, indicesExpressionGrouper, queryBuilderResolver ); @@ -84,12 +84,12 @@ public void esql( metrics.total(clientId); ActionListener executeListener = wrap(x -> { - planTelemetryManager.publish(planTelemetry, true); + planningMetricsManager.publish(planningMetrics, true); listener.onResponse(x); }, ex -> { // TODO when we decide if we will differentiate Kibana from REST, this String value will likely come from the request metrics.failed(clientId); - planTelemetryManager.publish(planTelemetry, false); + planningMetricsManager.publish(planningMetrics, false); listener.onFailure(ex); }); // Wrap it in a listener so that if we have any exceptions during execution, the listener picks it up diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index a614a473ebe41..d1622daaa5e33 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -224,7 +224,6 @@ public class EsqlFunctionRegistry { // it has with the alias name associated to the FunctionDefinition instance private final Map defs = new LinkedHashMap<>(); private final Map aliases = new HashMap<>(); - private final Map, String> names = new HashMap<>(); private SnapshotFunctionRegistry snapshotRegistry = null; @@ -259,12 +258,6 @@ public boolean functionExists(String functionName) { return defs.containsKey(functionName); } - public String functionName(Class clazz) { - String name = names.get(clazz); - Check.notNull(name, "Cannot find function by class {}", clazz); - return name; - } - public Collection listFunctions() { // It is worth double checking if we need this copy. These are immutable anyway. return defs.values(); @@ -765,14 +758,6 @@ void register(FunctionDefinition... functions) { } aliases.put(alias, f.name()); } - Check.isTrue( - names.containsKey(f.clazz()) == false, - "function type [{}} is registered twice with names [{}] and [{}]", - f.clazz(), - names.get(f.clazz()), - f.name() - ); - names.put(f.clazz(), f.name()); } // sort the temporary map by key name and add it to the global map of functions defs.putAll( diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java index ec23783fe1a2c..3b39e6a9d1fdb 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/AstBuilder.java @@ -8,7 +8,7 @@ package org.elasticsearch.xpack.esql.parser; public class AstBuilder extends LogicalPlanBuilder { - public AstBuilder(ParsingContext context) { - super(context); + public AstBuilder(QueryParams params) { + super(params); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java index 5912f1fe58bcd..9538e3ba495db 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java @@ -18,9 +18,7 @@ import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; import org.elasticsearch.xpack.esql.core.util.StringUtils; -import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; import java.util.BitSet; import java.util.function.BiFunction; @@ -54,27 +52,20 @@ public void setEsqlConfig(EsqlConfig config) { this.config = config; } - // testing utility public LogicalPlan createStatement(String query) { return createStatement(query, new QueryParams()); } - // testing utility public LogicalPlan createStatement(String query, QueryParams params) { - return createStatement(query, params, new PlanTelemetry(new EsqlFunctionRegistry())); - } - - public LogicalPlan createStatement(String query, QueryParams params, PlanTelemetry metrics) { if (log.isDebugEnabled()) { log.debug("Parsing as statement: {}", query); } - return invokeParser(query, params, metrics, EsqlBaseParser::singleStatement, AstBuilder::plan); + return invokeParser(query, params, EsqlBaseParser::singleStatement, AstBuilder::plan); } private T invokeParser( String query, QueryParams params, - PlanTelemetry metrics, Function parseFunction, BiFunction result ) { @@ -108,7 +99,7 @@ private T invokeParser( log.trace("Parse tree: {}", tree.toStringTree()); } - return result.apply(new AstBuilder(new ExpressionBuilder.ParsingContext(params, metrics)), tree); + return result.apply(new AstBuilder(params), tree); } catch (StackOverflowError e) { throw new ParsingException("ESQL statement is too large, causing stack overflow when generating the parsing tree: [{}]", query); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java index 78c3044257f9f..114fcda1e634a 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java @@ -62,7 +62,6 @@ import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.InsensitiveEquals; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThan; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.LessThanOrEqual; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import java.math.BigInteger; @@ -116,12 +115,10 @@ public abstract class ExpressionBuilder extends IdentifierBuilder { */ public static final int MAX_EXPRESSION_DEPTH = 400; - protected final ParsingContext context; + protected final QueryParams params; - public record ParsingContext(QueryParams params, PlanTelemetry telemetry) {} - - ExpressionBuilder(ParsingContext context) { - this.context = context; + ExpressionBuilder(QueryParams params) { + this.params = params; } protected Expression expression(ParseTree ctx) { @@ -624,9 +621,7 @@ public Expression visitFunctionExpression(EsqlBaseParser.FunctionExpressionConte @Override public String visitFunctionName(EsqlBaseParser.FunctionNameContext ctx) { - var name = visitIdentifierOrParameter(ctx.identifierOrParameter()); - context.telemetry().function(name); - return name; + return visitIdentifierOrParameter(ctx.identifierOrParameter()); } @Override @@ -688,9 +683,7 @@ private Expression castToType(Source source, ParseTree parseTree, EsqlBaseParser throw new ParsingException(source, "Unsupported conversion to type [{}]", dataType); } Expression expr = expression(parseTree); - var convertFunction = converterToFactory.apply(source, expr); - context.telemetry().function(convertFunction.getClass()); - return convertFunction; + return converterToFactory.apply(source, expr); } @Override @@ -922,10 +915,10 @@ QueryParam paramByToken(TerminalNode node) { return null; } Token token = node.getSymbol(); - if (context.params().contains(token) == false) { + if (params.contains(token) == false) { throw new ParsingException(source(node), "Unexpected parameter"); } - return context.params().get(token); + return params.get(token); } QueryParam paramByNameOrPosition(TerminalNode node) { @@ -936,28 +929,26 @@ QueryParam paramByNameOrPosition(TerminalNode node) { String nameOrPosition = token.getText().substring(1); if (isInteger(nameOrPosition)) { int index = Integer.parseInt(nameOrPosition); - if (context.params().get(index) == null) { + if (params.get(index) == null) { String message = ""; - int np = context.params().size(); + int np = params.size(); if (np > 0) { message = ", did you mean " + (np == 1 ? "position 1?" : "any position between 1 and " + np + "?"); } - context.params() - .addParsingError(new ParsingException(source(node), "No parameter is defined for position " + index + message)); + params.addParsingError(new ParsingException(source(node), "No parameter is defined for position " + index + message)); } - return context.params().get(index); + return params.get(index); } else { - if (context.params().contains(nameOrPosition) == false) { + if (params.contains(nameOrPosition) == false) { String message = ""; - List potentialMatches = StringUtils.findSimilar(nameOrPosition, context.params().namedParams().keySet()); + List potentialMatches = StringUtils.findSimilar(nameOrPosition, params.namedParams().keySet()); if (potentialMatches.size() > 0) { message = ", did you mean " + (potentialMatches.size() == 1 ? "[" + potentialMatches.get(0) + "]?" : "any of " + potentialMatches + "?"); } - context.params() - .addParsingError(new ParsingException(source(node), "Unknown query parameter [" + nameOrPosition + "]" + message)); + params.addParsingError(new ParsingException(source(node), "Unknown query parameter [" + nameOrPosition + "]" + message)); } - return context.params().get(nameOrPosition); + return params.get(nameOrPosition); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index 82f3e18912325..7ddd3dafd2784 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -18,7 +18,6 @@ import org.elasticsearch.index.IndexMode; import org.elasticsearch.transport.RemoteClusterAware; import org.elasticsearch.xpack.esql.VerificationException; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failure; import org.elasticsearch.xpack.esql.core.expression.Alias; import org.elasticsearch.xpack.esql.core.expression.Attribute; @@ -95,18 +94,15 @@ interface PlanFactory extends Function {} */ public static final int MAX_QUERY_DEPTH = 500; - public LogicalPlanBuilder(ParsingContext context) { - super(context); + public LogicalPlanBuilder(QueryParams params) { + super(params); } private int queryDepth = 0; protected LogicalPlan plan(ParseTree ctx) { LogicalPlan p = ParserUtils.typedParsing(this, ctx, LogicalPlan.class); - if (p instanceof TelemetryAware ma) { - this.context.telemetry().command(ma); - } - var errors = this.context.params().parsingErrors(); + var errors = this.params.parsingErrors(); if (errors.hasNext() == false) { return p; } else { @@ -486,7 +482,8 @@ public LogicalPlan visitMetricsCommand(EsqlBaseParser.MetricsCommandContext ctx) false, List.of(new MetadataAttribute(source, MetadataAttribute.TSID_FIELD, DataType.KEYWORD, false)), IndexMode.TIME_SERIES, - null + null, + "FROM TS" ); return new Aggregate(source, relation, Aggregate.AggregateType.METRICS, stats.groupings, stats.aggregates); } @@ -546,7 +543,8 @@ public PlanFactory visitJoinCommand(EsqlBaseParser.JoinCommandContext ctx) { false, emptyList(), IndexMode.LOOKUP, - null + null, + "???" ); var condition = ctx.joinCondition(); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Aggregate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Aggregate.java index 5c40bfce32064..0111d23fac281 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Aggregate.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Aggregate.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -40,7 +39,7 @@ import static org.elasticsearch.xpack.esql.expression.NamedExpressions.mergeOutputAttributes; import static org.elasticsearch.xpack.esql.plan.logical.Filter.checkFilterConditionDataType; -public class Aggregate extends UnaryPlan implements PostAnalysisVerificationAware, TelemetryAware { +public class Aggregate extends UnaryPlan implements PostAnalysisVerificationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( LogicalPlan.class, "Aggregate", @@ -143,7 +142,7 @@ public List aggregates() { } @Override - public String telemetryLabel() { + public String commandName() { return switch (aggregateType) { case STANDARD -> "STATS"; case METRICS -> "METRICS"; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Dissect.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Dissect.java index 9200850b2f9db..a83e102e51005 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Dissect.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Dissect.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.dissect.DissectParser; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; @@ -26,7 +25,7 @@ import java.util.List; import java.util.Objects; -public class Dissect extends RegexExtract implements TelemetryAware { +public class Dissect extends RegexExtract { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Dissect", Dissect::new); private final Parser parser; @@ -124,6 +123,11 @@ public boolean equals(Object o) { return Objects.equals(parser, dissect.parser); } + @Override + public String commandName() { + return "DISSECT"; + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), parser); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Drop.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Drop.java index 483c3508013ab..add5a2d576c00 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Drop.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Drop.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.plan.logical; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.NamedExpression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -17,7 +16,7 @@ import java.util.List; import java.util.Objects; -public class Drop extends UnaryPlan implements TelemetryAware { +public class Drop extends UnaryPlan { private final List removals; public Drop(Source source, LogicalPlan child, List removals) { @@ -39,6 +38,10 @@ public List removals() { return removals; } + public String commandName() { + return "DROP"; + } + @Override public boolean expressionsResolved() { return Resolvables.resolved(removals); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Enrich.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Enrich.java index 4e9fc87318029..9b81060349815 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Enrich.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Enrich.java @@ -18,7 +18,6 @@ import org.elasticsearch.transport.RemoteClusterAware; import org.elasticsearch.xpack.core.enrich.EnrichPolicy; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisPlanVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -49,7 +48,7 @@ import static org.elasticsearch.xpack.esql.core.expression.Expressions.asAttributes; import static org.elasticsearch.xpack.esql.expression.NamedExpressions.mergeOutputAttributes; -public class Enrich extends UnaryPlan implements GeneratingPlan, PostAnalysisPlanVerificationAware, TelemetryAware { +public class Enrich extends UnaryPlan implements GeneratingPlan, PostAnalysisPlanVerificationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( LogicalPlan.class, "Enrich", @@ -203,6 +202,10 @@ protected AttributeSet computeReferences() { return matchField.references(); } + public String commandName() { + return "ENRICH"; + } + @Override public boolean expressionsResolved() { return policyName.resolved() diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsRelation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsRelation.java index 448085df1e831..90b3aa8625087 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsRelation.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/EsRelation.java @@ -172,6 +172,11 @@ public Set concreteIndices() { return indexNameWithModes.keySet(); } + @Override + public String commandName() { + return "FROM"; + } + @Override public boolean expressionsResolved() { // For unresolved expressions to exist in EsRelation is fine, as long as they are not used in later operations diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Eval.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Eval.java index 7c437dac03409..cbd79011032df 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Eval.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Eval.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -38,7 +37,7 @@ import static org.elasticsearch.xpack.esql.core.expression.Expressions.asAttributes; import static org.elasticsearch.xpack.esql.expression.NamedExpressions.mergeOutputAttributes; -public class Eval extends UnaryPlan implements GeneratingPlan, PostAnalysisVerificationAware, TelemetryAware { +public class Eval extends UnaryPlan implements GeneratingPlan, PostAnalysisVerificationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Eval", Eval::new); private final List fields; @@ -132,6 +131,11 @@ private List renameAliases(List originalAttributes, List n return newFieldsWithUpdatedRefs; } + @Override + public String commandName() { + return "EVAL"; + } + @Override public boolean expressionsResolved() { return Resolvables.resolved(fields); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Explain.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Explain.java index bd49ed04881cc..38e7c19522df6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Explain.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Explain.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.esql.plan.logical; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -18,7 +17,7 @@ import java.util.List; import java.util.Objects; -public class Explain extends LeafPlan implements TelemetryAware { +public class Explain extends LeafPlan { public enum Type { PARSED, @@ -70,6 +69,11 @@ public List output() { ); } + @Override + public String commandName() { + return "EXPLAIN"; + } + @Override public boolean expressionsResolved() { return true; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Filter.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Filter.java index 6931c320007fe..0fae5e5831fc7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Filter.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Filter.java @@ -10,7 +10,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -29,7 +28,7 @@ * {@code SELECT x FROM y WHERE z ..} the "WHERE" clause is a Filter. A * {@code Filter} has a "condition" Expression that does the filtering. */ -public class Filter extends UnaryPlan implements PostAnalysisVerificationAware, TelemetryAware { +public class Filter extends UnaryPlan implements PostAnalysisVerificationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Filter", Filter::new); private final Expression condition; @@ -70,7 +69,7 @@ public Expression condition() { } @Override - public String telemetryLabel() { + public String commandName() { return "WHERE"; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Grok.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Grok.java index 1fab2cbecd034..fcfd1ac0f04da 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Grok.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Grok.java @@ -15,7 +15,6 @@ import org.elasticsearch.grok.GrokCaptureType; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; @@ -32,7 +31,7 @@ import java.util.Objects; import java.util.stream.Collectors; -public class Grok extends RegexExtract implements TelemetryAware { +public class Grok extends RegexExtract { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Grok", Grok::readFrom); public record Parser(String pattern, org.elasticsearch.grok.Grok grok) { @@ -149,6 +148,11 @@ public boolean equals(Object o) { return Objects.equals(parser, grok.parser); } + @Override + public String commandName() { + return "GROK"; + } + @Override public int hashCode() { return Objects.hash(super.hashCode(), parser); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/InlineStats.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/InlineStats.java index 527ba28d377f1..4211f8a0d45b6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/InlineStats.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/InlineStats.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.Expressions; @@ -37,7 +36,7 @@ * underlying aggregate. *

*/ -public class InlineStats extends UnaryPlan implements NamedWriteable, SurrogateLogicalPlan, TelemetryAware { +public class InlineStats extends UnaryPlan implements NamedWriteable, SurrogateLogicalPlan { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( LogicalPlan.class, "InlineStats", @@ -81,6 +80,11 @@ public Aggregate aggregate() { return aggregate; } + @Override + public String commandName() { + return "INLINESTATS"; + } + @Override public boolean expressionsResolved() { return aggregate.expressionsResolved(); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Keep.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Keep.java index 67108afb94668..4c03d68e6e6f7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Keep.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Keep.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.esql.plan.logical; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.NamedExpression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -15,7 +14,7 @@ import java.util.List; import java.util.Objects; -public class Keep extends Project implements TelemetryAware { +public class Keep extends Project { public Keep(Source source, LogicalPlan child, List projections) { super(source, child, projections); @@ -45,4 +44,9 @@ public int hashCode() { public boolean equals(Object obj) { return super.equals(obj); } + + @Override + public String commandName() { + return "KEEP"; + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Limit.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Limit.java index 1bb89acf1942d..ea64b7687f4c0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Limit.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Limit.java @@ -9,7 +9,6 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -18,7 +17,7 @@ import java.io.IOException; import java.util.Objects; -public class Limit extends UnaryPlan implements TelemetryAware { +public class Limit extends UnaryPlan { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Limit", Limit::new); private final Expression limit; @@ -58,6 +57,11 @@ public Expression limit() { return limit; } + @Override + public String commandName() { + return "LIMIT"; + } + @Override public boolean expressionsResolved() { return limit.resolved(); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/LogicalPlan.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/LogicalPlan.java index ac4baea8bc853..e845c25bd3b32 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/LogicalPlan.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/LogicalPlan.java @@ -75,6 +75,8 @@ public boolean resolved() { return lazyResolved; } + public abstract String commandName(); + public abstract boolean expressionsResolved(); @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Lookup.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Lookup.java index 1c05ceb124529..6e7f421003292 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Lookup.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Lookup.java @@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.core.Nullable; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -32,7 +31,7 @@ * Looks up values from the associated {@code tables}. * The class is supposed to be substituted by a {@link Join}. */ -public class Lookup extends UnaryPlan implements SurrogateLogicalPlan, TelemetryAware { +public class Lookup extends UnaryPlan implements SurrogateLogicalPlan { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Lookup", Lookup::new); private final Expression tableName; @@ -118,6 +117,11 @@ public JoinConfig joinConfig() { return new JoinConfig(JoinTypes.LEFT, matchFields, leftFields, rightFields); } + @Override + public String commandName() { + return "LOOKUP"; + } + @Override public boolean expressionsResolved() { return tableName.resolved() && Resolvables.resolved(matchFields) && localRelation != null; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/MvExpand.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/MvExpand.java index f5a3c8230b124..949e4906e5033 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/MvExpand.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/MvExpand.java @@ -10,7 +10,6 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.AttributeSet; import org.elasticsearch.xpack.esql.core.expression.NamedExpression; @@ -23,7 +22,7 @@ import java.util.List; import java.util.Objects; -public class MvExpand extends UnaryPlan implements TelemetryAware { +public class MvExpand extends UnaryPlan { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "MvExpand", MvExpand::new); private final NamedExpression target; @@ -96,7 +95,7 @@ protected AttributeSet computeReferences() { return target.references(); } - public String telemetryLabel() { + public String commandName() { return "MV_EXPAND"; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/OrderBy.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/OrderBy.java index 051e2c7769bde..d927d78701c65 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/OrderBy.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/OrderBy.java @@ -10,7 +10,6 @@ import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -25,7 +24,7 @@ import static org.elasticsearch.xpack.esql.common.Failure.fail; -public class OrderBy extends UnaryPlan implements PostAnalysisVerificationAware, TelemetryAware { +public class OrderBy extends UnaryPlan implements PostAnalysisVerificationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "OrderBy", OrderBy::new); private final List order; @@ -70,7 +69,7 @@ public List order() { } @Override - public String telemetryLabel() { + public String commandName() { return "SORT"; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java index e12a8cb557fde..841e7fbe81896 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java @@ -78,6 +78,14 @@ public boolean resolved() { return super.resolved() && Expressions.anyMatch(projections, Functions::isAggregate) == false; } + @Override + public String commandName() { + // this could represent multiple commands (KEEP, DROP, RENAME) + // and should not be present in a pre-analyzed plan. + // maybe it should throw exception? + return ""; + } + @Override public boolean expressionsResolved() { return Resolvables.resolved(projections); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Rename.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Rename.java index 7887d8ed66b99..773d3fd015e5f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Rename.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Rename.java @@ -9,7 +9,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.analysis.Analyzer.ResolveRefs; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Alias; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expressions; @@ -21,7 +20,7 @@ import java.util.List; import java.util.Objects; -public class Rename extends UnaryPlan implements TelemetryAware { +public class Rename extends UnaryPlan { private final List renamings; @@ -52,6 +51,11 @@ public List output() { return Expressions.asAttributes(projectionsAfterResolution); } + @Override + public String commandName() { + return "RENAME"; + } + @Override public boolean expressionsResolved() { for (var alias : renamings) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Row.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Row.java index 005ca45d19131..65d1adf5e2799 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Row.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Row.java @@ -9,7 +9,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.capabilities.Resolvables; import org.elasticsearch.xpack.esql.core.expression.Alias; @@ -24,7 +23,7 @@ import static org.elasticsearch.xpack.esql.common.Failure.fail; -public class Row extends LeafPlan implements PostAnalysisVerificationAware, TelemetryAware { +public class Row extends LeafPlan implements PostAnalysisVerificationAware { private final List fields; @@ -52,6 +51,11 @@ public List output() { return Expressions.asAttributes(fields); } + @Override + public String commandName() { + return "ROW"; + } + @Override public boolean expressionsResolved() { return Resolvables.resolved(fields); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/TopN.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/TopN.java index a9a5dbddc544f..d6e0e4334bd47 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/TopN.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/TopN.java @@ -55,6 +55,13 @@ public String getWriteableName() { return ENTRY.name; } + @Override + public String commandName() { + // this is the result of optimizations, it will never appear in a pre-analyzed plan + // maybe we should throw exception? + return ""; + } + @Override public boolean expressionsResolved() { return limit.resolved() && Resolvables.resolved(order); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/UnresolvedRelation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/UnresolvedRelation.java index 5d22a86b2cdf7..0a20e1dd9080d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/UnresolvedRelation.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/UnresolvedRelation.java @@ -8,13 +8,11 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.index.IndexMode; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.capabilities.Unresolvable; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.plan.IndexPattern; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; import java.util.Collections; import java.util.List; @@ -22,7 +20,7 @@ import static java.util.Collections.singletonList; -public class UnresolvedRelation extends LeafPlan implements Unresolvable, TelemetryAware { +public class UnresolvedRelation extends LeafPlan implements Unresolvable { private final IndexPattern indexPattern; private final boolean frozen; @@ -58,17 +56,6 @@ public UnresolvedRelation( this.commandName = commandName; } - public UnresolvedRelation( - Source source, - IndexPattern table, - boolean frozen, - List metadataFields, - IndexMode indexMode, - String unresolvedMessage - ) { - this(source, table, frozen, metadataFields, indexMode, unresolvedMessage, null); - } - @Override public void writeTo(StreamOutput out) { throw new UnsupportedOperationException("not serialized"); @@ -99,7 +86,7 @@ public boolean resolved() { /** * - * This is used by {@link PlanTelemetry} to collect query statistics + * This is used by {@link org.elasticsearch.xpack.esql.stats.PlanningMetrics} to collect query statistics * It can return *
    *
  • "FROM" if this a |FROM idx command
  • @@ -108,7 +95,7 @@ public boolean resolved() { *
*/ @Override - public String telemetryLabel() { + public String commandName() { return commandName; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/Join.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/Join.java index 997bff70663bd..a541142f952e0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/Join.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/Join.java @@ -189,6 +189,11 @@ public Join replaceChildren(LogicalPlan left, LogicalPlan right) { return new Join(source(), left, right, config); } + @Override + public String commandName() { + return "JOIN"; + } + @Override public int hashCode() { return Objects.hash(config, left(), right()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/LookupJoin.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/LookupJoin.java index 5f1f569e3671b..c29cf0ec7f414 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/LookupJoin.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/LookupJoin.java @@ -9,7 +9,6 @@ import org.elasticsearch.index.IndexMode; import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.common.Failures; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -28,7 +27,7 @@ /** * Lookup join - specialized LEFT (OUTER) JOIN between the main left side and a lookup index (index_mode = lookup) on the right. */ -public class LookupJoin extends Join implements SurrogateLogicalPlan, PostAnalysisVerificationAware, TelemetryAware { +public class LookupJoin extends Join implements SurrogateLogicalPlan, PostAnalysisVerificationAware { public LookupJoin(Source source, LogicalPlan left, LogicalPlan right, List joinFields) { this(source, left, right, new UsingJoinType(LEFT, joinFields), emptyList(), emptyList(), emptyList()); @@ -78,11 +77,6 @@ protected NodeInfo info() { ); } - @Override - public String telemetryLabel() { - return "LOOKUP JOIN"; - } - @Override public void postAnalysisVerification(Failures failures) { super.postAnalysisVerification(failures); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/StubRelation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/StubRelation.java index 33e1f385f9eec..4f04024d61d46 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/StubRelation.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/join/StubRelation.java @@ -67,6 +67,11 @@ protected NodeInfo info() { return NodeInfo.create(this, StubRelation::new, output); } + @Override + public String commandName() { + return ""; + } + @Override public int hashCode() { return Objects.hash(StubRelation.class, output); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/LocalRelation.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/LocalRelation.java index d6106bae6b6b8..07432481d2341 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/LocalRelation.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/LocalRelation.java @@ -63,6 +63,14 @@ public LocalSupplier supplier() { return supplier; } + @Override + public String commandName() { + // this colud be an empty source, a lookup table or something else + // but it should not be present in a pre-analyzed plan + // maybe we sholud throw exception? + return ""; + } + @Override public boolean expressionsResolved() { return true; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowInfo.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowInfo.java index 99c917ba803a9..fa432537d27e3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowInfo.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/show/ShowInfo.java @@ -10,7 +10,6 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.Build; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.ReferenceAttribute; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; @@ -23,7 +22,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; -public class ShowInfo extends LeafPlan implements TelemetryAware { +public class ShowInfo extends LeafPlan { private final List attributes; @@ -60,7 +59,7 @@ public List> values() { } @Override - public String telemetryLabel() { + public String commandName() { return "SHOW"; } 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 8c95992cf9f5a..0505955e450d7 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 @@ -73,7 +73,7 @@ import org.elasticsearch.xpack.esql.plan.physical.FragmentExec; import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan; import org.elasticsearch.xpack.esql.planner.mapper.Mapper; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; +import org.elasticsearch.xpack.esql.stats.PlanningMetrics; import java.util.ArrayList; import java.util.Arrays; @@ -112,7 +112,7 @@ public interface PlanRunner { private final Mapper mapper; private final PhysicalPlanOptimizer physicalPlanOptimizer; - private final PlanTelemetry planTelemetry; + private final PlanningMetrics planningMetrics; private final IndicesExpressionGrouper indicesExpressionGrouper; private final QueryBuilderResolver queryBuilderResolver; @@ -126,7 +126,7 @@ public EsqlSession( LogicalPlanOptimizer logicalPlanOptimizer, Mapper mapper, Verifier verifier, - PlanTelemetry planTelemetry, + PlanningMetrics planningMetrics, IndicesExpressionGrouper indicesExpressionGrouper, QueryBuilderResolver queryBuilderResolver ) { @@ -140,7 +140,7 @@ public EsqlSession( this.mapper = mapper; this.logicalPlanOptimizer = logicalPlanOptimizer; this.physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration)); - this.planTelemetry = planTelemetry; + this.planningMetrics = planningMetrics; this.indicesExpressionGrouper = indicesExpressionGrouper; this.queryBuilderResolver = queryBuilderResolver; } @@ -280,7 +280,7 @@ private LocalRelation resultToPlan(LogicalPlan plan, Result result) { } private LogicalPlan parse(String query, QueryParams params) { - var parsed = new EsqlParser().createStatement(query, params, planTelemetry); + var parsed = new EsqlParser().createStatement(query, params); LOGGER.debug("Parsed logical plan:\n{}", parsed); return parsed; } @@ -297,6 +297,7 @@ public void analyzedPlan( } Function analyzeAction = (l) -> { + planningMetrics.gatherPreAnalysisMetrics(parsed); Analyzer analyzer = new Analyzer( new AnalyzerContext(configuration, functionRegistry, l.indices, l.lookupIndices, l.enrichResolution), verifier 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/stats/FeatureMetric.java similarity index 98% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/FeatureMetric.java index 3a36f5b0d7c04..4cae2a9c247f3 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/stats/FeatureMetric.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import org.elasticsearch.xpack.esql.plan.logical.Aggregate; import org.elasticsearch.xpack.esql.plan.logical.Dissect; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/Metrics.java similarity index 99% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/Metrics.java index b8962b47809a0..092fecb3142db 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/Metrics.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import org.elasticsearch.common.metrics.CounterMetric; import org.elasticsearch.common.util.Maps; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java new file mode 100644 index 0000000000000..7b452e50fd525 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.stats; + +import org.elasticsearch.xpack.esql.expression.function.UnresolvedFunction; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * This class is responsible for collecting metrics related to ES|QL planning. + */ +public class PlanningMetrics { + private Map commands = new HashMap<>(); + private Map functions = new HashMap<>(); + + public void gatherPreAnalysisMetrics(LogicalPlan plan) { + plan.forEachDown(p -> add(commands, p.commandName())); + plan.forEachExpressionDown(UnresolvedFunction.class, p -> add(functions, p.name().toUpperCase(Locale.ROOT))); + } + + private void add(Map map, String key) { + Integer cmd = map.get(key); + map.put(key, cmd == null ? 1 : cmd + 1); + } + + public Map commands() { + return commands; + } + + public Map functions() { + return functions; + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java similarity index 89% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java index 2cd536daf389c..a2d00a1f530e9 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import org.elasticsearch.telemetry.metric.LongCounter; import org.elasticsearch.telemetry.metric.MeterRegistry; @@ -17,7 +17,7 @@ * * @see METERING */ -public class PlanTelemetryManager { +public class PlanningMetricsManager { // APM counters private final LongCounter featuresCounter; @@ -59,7 +59,7 @@ public class PlanTelemetryManager { */ public static final String SUCCESS = "success"; - public PlanTelemetryManager(MeterRegistry meterRegistry) { + public PlanningMetricsManager(MeterRegistry meterRegistry) { featuresCounter = meterRegistry.registerLongCounter( FEATURE_METRICS, "ESQL features, total number of queries that use them", @@ -77,9 +77,9 @@ public PlanTelemetryManager(MeterRegistry meterRegistry) { /** * Publishes the collected metrics to the meter registry */ - public void publish(PlanTelemetry metrics, boolean success) { - metrics.commands().forEach((key, value) -> incCommand(key, value, success)); - metrics.functions().forEach((key, value) -> incFunction(key, value, success)); + public void publish(PlanningMetrics metrics, boolean success) { + metrics.commands().entrySet().forEach(x -> incCommand(x.getKey(), x.getValue(), success)); + metrics.functions().entrySet().forEach(x -> incFunction(x.getKey(), x.getValue(), success)); } private void incCommand(String name, int count, boolean success) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java similarity index 93% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java index 567b4b0a84937..e862006d058ac 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import java.util.Locale; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java deleted file mode 100644 index 6fe1314524f10..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.telemetry; - -import org.elasticsearch.xpack.esql.capabilities.TelemetryAware; -import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; -import org.elasticsearch.xpack.esql.core.expression.function.Function; -import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.elasticsearch.common.Strings.format; - -/** - * This class is responsible for collecting metrics related to ES|QL planning. - */ -public class PlanTelemetry { - private final EsqlFunctionRegistry functionRegistry; - private final Set telemetryAwares = new HashSet<>(); - private final Map commands = new HashMap<>(); - private final Map functions = new HashMap<>(); - - public PlanTelemetry(EsqlFunctionRegistry functionRegistry) { - this.functionRegistry = functionRegistry; - } - - private void add(Map map, String key) { - map.compute(key.toUpperCase(Locale.ROOT), (k, count) -> count == null ? 1 : count + 1); - } - - public void command(TelemetryAware command) { - if (telemetryAwares.add(command)) { - if (command.telemetryLabel() == null) { - throw new QlIllegalArgumentException(format("TelemetryAware [{}] has no metric name", command)); - } - add(commands, command.telemetryLabel()); - } - } - - public void function(String name) { - var functionName = functionRegistry.resolveAlias(name); - if (functionRegistry.functionExists(functionName)) { - // The metrics have been collected initially with their uppercase spelling - add(functions, functionName); - } - } - - public void function(Class clazz) { - add(functions, functionRegistry.functionName(clazz)); - } - - public Map commands() { - return commands; - } - - public Map functions() { - return functions; - } -} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index bae20bb9b26d3..350befc219f6e 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -90,7 +90,7 @@ import org.elasticsearch.xpack.esql.session.EsqlSession.PlanRunner; import org.elasticsearch.xpack.esql.session.Result; import org.elasticsearch.xpack.esql.stats.DisabledSearchStats; -import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry; +import org.elasticsearch.xpack.esql.stats.PlanningMetrics; import org.junit.After; import org.junit.Before; import org.mockito.Mockito; @@ -514,7 +514,7 @@ private ActualResults executePlan(BigArrays bigArrays) throws Exception { new LogicalPlanOptimizer(new LogicalOptimizerContext(configuration, foldCtx)), mapper, TEST_VERIFIER, - new PlanTelemetry(functionRegistry), + new PlanningMetrics(), null, EsqlTestUtils.MOCK_QUERY_BUILDER_RESOLVER ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java index cf2de30e44456..e507640c7b23c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/CheckLicenseTests.java @@ -29,7 +29,7 @@ import org.elasticsearch.xpack.esql.parser.EsqlParser; import org.elasticsearch.xpack.esql.plan.logical.Limit; import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; -import org.elasticsearch.xpack.esql.telemetry.Metrics; +import org.elasticsearch.xpack.esql.stats.Metrics; import java.util.List; import java.util.Objects; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java index d99118df7e684..310d680cfbf41 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java @@ -248,6 +248,11 @@ public UnaryPlan replaceChild(LogicalPlan newChild) { return new MockFieldAttributeCommand(source(), newChild, field); } + @Override + public String commandName() { + return "MOCK"; + } + @Override public boolean expressionsResolved() { return true; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java index 8bdd7a4e1645f..aae2d012fc3a6 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java @@ -74,9 +74,9 @@ import org.elasticsearch.xpack.esql.querydsl.query.SingleValueQuery; import org.elasticsearch.xpack.esql.rule.Rule; import org.elasticsearch.xpack.esql.session.Configuration; +import org.elasticsearch.xpack.esql.stats.Metrics; import org.elasticsearch.xpack.esql.stats.SearchContextStats; import org.elasticsearch.xpack.esql.stats.SearchStats; -import org.elasticsearch.xpack.esql.telemetry.Metrics; import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter; import org.elasticsearch.xpack.kql.query.KqlQueryBuilder; import org.junit.Before; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/QueryTranslatorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/QueryTranslatorTests.java index f9732272dbd74..57210fda07f2b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/QueryTranslatorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/planner/QueryTranslatorTests.java @@ -21,7 +21,7 @@ import org.elasticsearch.xpack.esql.optimizer.TestPlannerOptimizer; import org.elasticsearch.xpack.esql.plan.physical.EsQueryExec; import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan; -import org.elasticsearch.xpack.esql.telemetry.Metrics; +import org.elasticsearch.xpack.esql.stats.Metrics; import org.hamcrest.Matcher; import org.junit.BeforeClass; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java similarity index 99% rename from x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java rename to x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java index 4c2913031271f..a3c5cd9168b4f 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.OriginalIndices; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java similarity index 93% rename from x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java rename to x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java index de377fe78588c..eda906b147956 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java @@ -5,7 +5,7 @@ * 2.0. */ -package org.elasticsearch.xpack.esql.telemetry; +package org.elasticsearch.xpack.esql.stats; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; @@ -22,23 +22,23 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning; import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.analyzer; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.DISSECT; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.DROP; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.ENRICH; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.EVAL; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.FROM; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.GROK; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.KEEP; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.LIMIT; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.MV_EXPAND; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.RENAME; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.ROW; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.SHOW; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.SORT; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.STATS; -import static org.elasticsearch.xpack.esql.telemetry.FeatureMetric.WHERE; -import static org.elasticsearch.xpack.esql.telemetry.Metrics.FPREFIX; -import static org.elasticsearch.xpack.esql.telemetry.Metrics.FUNC_PREFIX; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.DISSECT; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.DROP; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.ENRICH; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.EVAL; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.FROM; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.GROK; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.KEEP; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.LIMIT; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.MV_EXPAND; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.RENAME; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.ROW; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.SHOW; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.SORT; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.STATS; +import static org.elasticsearch.xpack.esql.stats.FeatureMetric.WHERE; +import static org.elasticsearch.xpack.esql.stats.Metrics.FPREFIX; +import static org.elasticsearch.xpack.esql.stats.Metrics.FUNC_PREFIX; public class VerifierMetricsTests extends ESTestCase {