diff --git a/docs/changelog/121074.yaml b/docs/changelog/121074.yaml
new file mode 100644
index 0000000000000..6e07ab295ea66
--- /dev/null
+++ b/docs/changelog/121074.yaml
@@ -0,0 +1,5 @@
+pr: 121074
+summary: Implement a `MetricsAware` interface
+area: ES|QL
+type: enhancement
+issues: []
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 217bf6692aa27..919a963f7fc98 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
@@ -74,8 +74,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 25603acece3cb..7036216ebbbcf 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.stats.PlanningMetricsManager;
+import org.elasticsearch.xpack.esql.telemetry.PlanTelemetryManager;
import org.junit.Before;
import java.util.Collection;
@@ -113,6 +113,41 @@ public static Iterable
*/
-public class InlineStats extends UnaryPlan implements NamedWriteable, SurrogateLogicalPlan {
+public class InlineStats extends UnaryPlan implements NamedWriteable, SurrogateLogicalPlan, TelemetryAware {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
LogicalPlan.class,
"InlineStats",
@@ -80,11 +81,6 @@ 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 4c03d68e6e6f7..67108afb94668 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,6 +7,7 @@
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;
@@ -14,7 +15,7 @@
import java.util.List;
import java.util.Objects;
-public class Keep extends Project {
+public class Keep extends Project implements TelemetryAware {
public Keep(Source source, LogicalPlan child, List extends NamedExpression> projections) {
super(source, child, projections);
@@ -44,9 +45,4 @@ 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 09879e47859c9..a59433e94f965 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,6 +9,7 @@
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;
@@ -17,7 +18,7 @@
import java.io.IOException;
import java.util.Objects;
-public class Limit extends UnaryPlan {
+public class Limit extends UnaryPlan implements TelemetryAware {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Limit", Limit::new);
private final Expression limit;
@@ -100,11 +101,6 @@ public Limit withDuplicated(boolean duplicated) {
return new Limit(source(), limit, child(), duplicated);
}
- @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 e845c25bd3b32..ac4baea8bc853 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,8 +75,6 @@ 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 6e7f421003292..1c05ceb124529 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,6 +11,7 @@
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;
@@ -31,7 +32,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 {
+public class Lookup extends UnaryPlan implements SurrogateLogicalPlan, TelemetryAware {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Lookup", Lookup::new);
private final Expression tableName;
@@ -117,11 +118,6 @@ 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 9b0168ddd739d..e700ad90afdab 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,6 +10,7 @@
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;
@@ -22,7 +23,7 @@
import java.util.List;
import java.util.Objects;
-public class MvExpand extends UnaryPlan {
+public class MvExpand extends UnaryPlan implements TelemetryAware {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "MvExpand", MvExpand::new);
private final NamedExpression target;
@@ -83,7 +84,7 @@ protected AttributeSet computeReferences() {
return target.references();
}
- public String commandName() {
+ public String telemetryLabel() {
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 d927d78701c65..051e2c7769bde 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,6 +10,7 @@
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;
@@ -24,7 +25,7 @@
import static org.elasticsearch.xpack.esql.common.Failure.fail;
-public class OrderBy extends UnaryPlan implements PostAnalysisVerificationAware {
+public class OrderBy extends UnaryPlan implements PostAnalysisVerificationAware, TelemetryAware {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "OrderBy", OrderBy::new);
private final List order;
@@ -69,7 +70,7 @@ public List order() {
}
@Override
- public String commandName() {
+ public String telemetryLabel() {
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 841e7fbe81896..e12a8cb557fde 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,14 +78,6 @@ 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 773d3fd015e5f..7887d8ed66b99 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,6 +9,7 @@
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;
@@ -20,7 +21,7 @@
import java.util.List;
import java.util.Objects;
-public class Rename extends UnaryPlan {
+public class Rename extends UnaryPlan implements TelemetryAware {
private final List renamings;
@@ -51,11 +52,6 @@ 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 65d1adf5e2799..005ca45d19131 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,6 +9,7 @@
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;
@@ -23,7 +24,7 @@
import static org.elasticsearch.xpack.esql.common.Failure.fail;
-public class Row extends LeafPlan implements PostAnalysisVerificationAware {
+public class Row extends LeafPlan implements PostAnalysisVerificationAware, TelemetryAware {
private final List fields;
@@ -51,11 +52,6 @@ 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 d6e0e4334bd47..a9a5dbddc544f 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,13 +55,6 @@ 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 0a20e1dd9080d..5d22a86b2cdf7 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,11 +8,13 @@
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;
@@ -20,7 +22,7 @@
import static java.util.Collections.singletonList;
-public class UnresolvedRelation extends LeafPlan implements Unresolvable {
+public class UnresolvedRelation extends LeafPlan implements Unresolvable, TelemetryAware {
private final IndexPattern indexPattern;
private final boolean frozen;
@@ -56,6 +58,17 @@ 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");
@@ -86,7 +99,7 @@ public boolean resolved() {
/**
*
- * This is used by {@link org.elasticsearch.xpack.esql.stats.PlanningMetrics} to collect query statistics
+ * This is used by {@link PlanTelemetry} to collect query statistics
* It can return
*
* - "FROM" if this a
|FROM idx
command
@@ -95,7 +108,7 @@ public boolean resolved() {
*
*/
@Override
- public String commandName() {
+ public String telemetryLabel() {
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 a541142f952e0..997bff70663bd 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,11 +189,6 @@ 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 c29cf0ec7f414..5f1f569e3671b 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,6 +9,7 @@
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;
@@ -27,7 +28,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 {
+public class LookupJoin extends Join implements SurrogateLogicalPlan, PostAnalysisVerificationAware, TelemetryAware {
public LookupJoin(Source source, LogicalPlan left, LogicalPlan right, List joinFields) {
this(source, left, right, new UsingJoinType(LEFT, joinFields), emptyList(), emptyList(), emptyList());
@@ -77,6 +78,11 @@ 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 4f04024d61d46..33e1f385f9eec 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,11 +67,6 @@ 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 07432481d2341..d6106bae6b6b8 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,14 +63,6 @@ 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 fa432537d27e3..99c917ba803a9 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,6 +10,7 @@
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;
@@ -22,7 +23,7 @@
import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD;
-public class ShowInfo extends LeafPlan {
+public class ShowInfo extends LeafPlan implements TelemetryAware {
private final List attributes;
@@ -59,7 +60,7 @@ public List> values() {
}
@Override
- public String commandName() {
+ public String telemetryLabel() {
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 0505955e450d7..8c95992cf9f5a 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.stats.PlanningMetrics;
+import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry;
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 PlanningMetrics planningMetrics;
+ private final PlanTelemetry planTelemetry;
private final IndicesExpressionGrouper indicesExpressionGrouper;
private final QueryBuilderResolver queryBuilderResolver;
@@ -126,7 +126,7 @@ public EsqlSession(
LogicalPlanOptimizer logicalPlanOptimizer,
Mapper mapper,
Verifier verifier,
- PlanningMetrics planningMetrics,
+ PlanTelemetry planTelemetry,
IndicesExpressionGrouper indicesExpressionGrouper,
QueryBuilderResolver queryBuilderResolver
) {
@@ -140,7 +140,7 @@ public EsqlSession(
this.mapper = mapper;
this.logicalPlanOptimizer = logicalPlanOptimizer;
this.physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration));
- this.planningMetrics = planningMetrics;
+ this.planTelemetry = planTelemetry;
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);
+ var parsed = new EsqlParser().createStatement(query, params, planTelemetry);
LOGGER.debug("Parsed logical plan:\n{}", parsed);
return parsed;
}
@@ -297,7 +297,6 @@ 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/stats/PlanningMetrics.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java
deleted file mode 100644
index 7b452e50fd525..0000000000000
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetrics.java
+++ /dev/null
@@ -1,41 +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.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/stats/FeatureMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
similarity index 98%
rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/FeatureMetric.java
rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
index 4cae2a9c247f3..3a36f5b0d7c04 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/FeatureMetric.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
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/stats/Metrics.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java
similarity index 99%
rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/Metrics.java
rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java
index 092fecb3142db..b8962b47809a0 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/Metrics.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/Metrics.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
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/telemetry/PlanTelemetry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java
new file mode 100644
index 0000000000000..10b48c243d3b1
--- /dev/null
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetry.java
@@ -0,0 +1,59 @@
+/*
+ * 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.expression.function.Function;
+import org.elasticsearch.xpack.esql.core.util.Check;
+import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry;
+
+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 PlanTelemetry {
+ private final EsqlFunctionRegistry functionRegistry;
+ 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) {
+ Check.notNull(command.telemetryLabel(), "TelemetryAware [{}] has no telemetry label", 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 extends Function> clazz) {
+ add(functions, functionRegistry.functionName(clazz));
+ }
+
+ public Map commands() {
+ return commands;
+ }
+
+ public Map functions() {
+ return functions;
+ }
+}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java
similarity index 89%
rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java
rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java
index a2d00a1f530e9..2cd536daf389c 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/PlanningMetricsManager.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/PlanTelemetryManager.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
import org.elasticsearch.telemetry.metric.LongCounter;
import org.elasticsearch.telemetry.metric.MeterRegistry;
@@ -17,7 +17,7 @@
*
* @see METERING
*/
-public class PlanningMetricsManager {
+public class PlanTelemetryManager {
// APM counters
private final LongCounter featuresCounter;
@@ -59,7 +59,7 @@ public class PlanningMetricsManager {
*/
public static final String SUCCESS = "success";
- public PlanningMetricsManager(MeterRegistry meterRegistry) {
+ public PlanTelemetryManager(MeterRegistry meterRegistry) {
featuresCounter = meterRegistry.registerLongCounter(
FEATURE_METRICS,
"ESQL features, total number of queries that use them",
@@ -77,9 +77,9 @@ public PlanningMetricsManager(MeterRegistry meterRegistry) {
/**
* Publishes the collected metrics to the meter registry
*/
- 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));
+ 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));
}
private void incCommand(String name, int count, boolean success) {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java
similarity index 93%
rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java
rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java
index e862006d058ac..567b4b0a84937 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/stats/QueryMetric.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/QueryMetric.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
import java.util.Locale;
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 350befc219f6e..bae20bb9b26d3 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.stats.PlanningMetrics;
+import org.elasticsearch.xpack.esql.telemetry.PlanTelemetry;
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 PlanningMetrics(),
+ new PlanTelemetry(functionRegistry),
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 e507640c7b23c..cf2de30e44456 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.stats.Metrics;
+import org.elasticsearch.xpack.esql.telemetry.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 c9821aea343bf..98f3d1d2d8d8e 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
@@ -249,11 +249,6 @@ 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 aae2d012fc3a6..8bdd7a4e1645f 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 57210fda07f2b..f9732272dbd74 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.stats.Metrics;
+import org.elasticsearch.xpack.esql.telemetry.Metrics;
import org.hamcrest.Matcher;
import org.junit.BeforeClass;
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java
similarity index 99%
rename from x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java
rename to x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java
index a3c5cd9168b4f..4c2913031271f 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/PlanExecutorMetricsTests.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.OriginalIndices;
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java
similarity index 93%
rename from x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java
rename to x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java
index eda906b147956..de377fe78588c 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/VerifierMetricsTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/telemetry/VerifierMetricsTests.java
@@ -5,7 +5,7 @@
* 2.0.
*/
-package org.elasticsearch.xpack.esql.stats;
+package org.elasticsearch.xpack.esql.telemetry;
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.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;
+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;
public class VerifierMetricsTests extends ESTestCase {