Skip to content

Commit 7d4ba31

Browse files
authored
Document logs essentials restricted ESQL commands for Kibana (#130346)
1 parent 8b6acd0 commit 7d4ba31

File tree

8 files changed

+98
-13
lines changed

8 files changed

+98
-13
lines changed

docs/reference/query-languages/esql/kibana/definition/commands/change_point.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/definition/functions/categorize.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/ConsumeProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public Set<String> getSupportedOptions() {
3535
@Override
3636
public Set<String> getSupportedAnnotationTypes() {
3737
return Set.of(
38+
"org.elasticsearch.xpack.esql.SupportsObservabilityTier",
3839
"org.elasticsearch.core.Nullable",
3940
"org.elasticsearch.injection.guice.Inject",
4041
"org.elasticsearch.xpack.esql.expression.function.FunctionInfo",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.esql;
9+
10+
import java.lang.annotation.ElementType;
11+
import java.lang.annotation.Retention;
12+
import java.lang.annotation.RetentionPolicy;
13+
import java.lang.annotation.Target;
14+
15+
@Retention(RetentionPolicy.RUNTIME)
16+
@Target(ElementType.TYPE)
17+
public @interface SupportsObservabilityTier {
18+
19+
ObservabilityTier tier();
20+
21+
enum ObservabilityTier {
22+
COMPLETE,
23+
LOGS_ESSENTIALS
24+
}
25+
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Categorize.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.common.io.stream.StreamOutput;
1313
import org.elasticsearch.license.XPackLicenseState;
1414
import org.elasticsearch.xpack.esql.LicenseAware;
15+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier;
1516
import org.elasticsearch.xpack.esql.core.expression.Expression;
1617
import org.elasticsearch.xpack.esql.core.expression.Nullability;
1718
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
@@ -27,6 +28,7 @@
2728
import java.io.IOException;
2829
import java.util.List;
2930

31+
import static org.elasticsearch.xpack.esql.SupportsObservabilityTier.ObservabilityTier.COMPLETE;
3032
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT;
3133
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString;
3234

@@ -39,6 +41,7 @@
3941
* For the implementation, see {@link org.elasticsearch.compute.aggregation.blockhash.CategorizeBlockHash}
4042
* </p>
4143
*/
44+
@SupportsObservabilityTier(tier = COMPLETE)
4245
public class Categorize extends GroupingFunction.NonEvaluatableGroupingFunction implements LicenseAware {
4346
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
4447
Expression.class,

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/ChangePoint.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.elasticsearch.compute.operator.ChangePointOperator;
1111
import org.elasticsearch.license.XPackLicenseState;
1212
import org.elasticsearch.xpack.esql.LicenseAware;
13+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier;
1314
import org.elasticsearch.xpack.esql.capabilities.PostAnalysisVerificationAware;
1415
import org.elasticsearch.xpack.esql.common.Failures;
1516
import org.elasticsearch.xpack.esql.core.expression.Attribute;
@@ -27,6 +28,7 @@
2728
import java.util.List;
2829
import java.util.Objects;
2930

31+
import static org.elasticsearch.xpack.esql.SupportsObservabilityTier.ObservabilityTier.COMPLETE;
3032
import static org.elasticsearch.xpack.esql.common.Failure.fail;
3133

3234
/**
@@ -41,6 +43,7 @@
4143
* Furthermore, ChangePoint should be called with at most 1000 data points. That's
4244
* enforced by the Limit in the surrogate plan.
4345
*/
46+
@SupportsObservabilityTier(tier = COMPLETE)
4447
public class ChangePoint extends UnaryPlan implements SurrogateLogicalPlan, PostAnalysisVerificationAware, LicenseAware {
4548

4649
private final Attribute value;

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import org.elasticsearch.xcontent.XContentBuilder;
1919
import org.elasticsearch.xcontent.json.JsonXContent;
2020
import org.elasticsearch.xpack.esql.CsvTestsDataLoader;
21+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier;
22+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier.ObservabilityTier;
2123
import org.elasticsearch.xpack.esql.core.type.DataType;
2224
import org.elasticsearch.xpack.esql.expression.function.fulltext.MatchOperator;
2325
import org.elasticsearch.xpack.esql.expression.function.scalar.string.regex.RLike;
@@ -572,7 +574,7 @@ private void renderDocs(FunctionDefinition definition) throws Exception {
572574
boolean hasAppendix = renderAppendix(info.appendix());
573575
renderFullLayout(info, hasExamples, hasAppendix, hasFunctionOptions);
574576
renderKibanaInlineDocs(name, null, info);
575-
renderKibanaFunctionDefinition(name, null, info, description.args(), description.variadic());
577+
renderKibanaFunctionDefinition(name, null, info, description.args(), description.variadic(), getObservabilityTier());
576578
}
577579

578580
private void renderFunctionNamedParams(EsqlFunctionRegistry.MapArgSignature mapArgSignature) throws IOException {
@@ -666,6 +668,11 @@ private String addInclude(String section) {
666668
:::
667669
""".replace("$NAME$", name).replace("$SECTION$", section);
668670
}
671+
672+
private ObservabilityTier getObservabilityTier() {
673+
SupportsObservabilityTier supportsObservabilityTier = definition.clazz().getAnnotation(SupportsObservabilityTier.class);
674+
return supportsObservabilityTier != null ? supportsObservabilityTier.tier() : null;
675+
}
669676
}
670677

671678
/** Operator specific docs generating, since it is currently quite different from the function docs generating */
@@ -712,7 +719,7 @@ public void renderDocs() throws Exception {
712719
if (ctor != null) {
713720
FunctionInfo functionInfo = ctor.getAnnotation(FunctionInfo.class);
714721
assert functionInfo != null;
715-
renderDocsForOperators(op.name(), op.titleName(), ctor, functionInfo, op.variadic());
722+
renderDocsForOperators(op.name(), op.titleName(), ctor, functionInfo, op.variadic(), getObservabilityTier());
716723
} else {
717724
logger.info("Skipping rendering docs for operator '" + op.name() + "' with no @FunctionInfo");
718725
}
@@ -787,11 +794,17 @@ public Example[] examples() {
787794
}
788795
};
789796
String name = "not_" + baseName;
790-
renderDocsForOperators(name, null, ctor, functionInfo, op.variadic());
797+
renderDocsForOperators(name, null, ctor, functionInfo, op.variadic(), getObservabilityTier());
791798
}
792799

793-
void renderDocsForOperators(String name, String titleName, Constructor<?> ctor, FunctionInfo info, boolean variadic)
794-
throws Exception {
800+
void renderDocsForOperators(
801+
String name,
802+
String titleName,
803+
Constructor<?> ctor,
804+
FunctionInfo info,
805+
boolean variadic,
806+
ObservabilityTier observabilityTier
807+
) throws Exception {
795808
renderKibanaInlineDocs(name, titleName, info);
796809

797810
var params = ctor.getParameters();
@@ -808,7 +821,7 @@ void renderDocsForOperators(String name, String titleName, Constructor<?> ctor,
808821
}
809822
}
810823
}
811-
renderKibanaFunctionDefinition(name, titleName, info, args, variadic);
824+
renderKibanaFunctionDefinition(name, titleName, info, args, variadic, observabilityTier);
812825
renderDetailedDescription(info.detailedDescription(), info.note());
813826
renderTypes(name, args);
814827
renderExamples(info);
@@ -831,17 +844,35 @@ void renderDetailedDescription(String detailedDescription, String note) throws I
831844
writeToTempSnippetsDir("detailedDescription", rendered.toString());
832845
}
833846
}
847+
848+
private ObservabilityTier getObservabilityTier() {
849+
if (op != null) {
850+
SupportsObservabilityTier supportsObservabilityTier = op.clazz().getAnnotation(SupportsObservabilityTier.class);
851+
if (supportsObservabilityTier != null) {
852+
return supportsObservabilityTier.tier();
853+
}
854+
}
855+
return null;
856+
}
834857
}
835858

836859
/** Command specific docs generating, currently very empty since we only render kibana definition files */
837860
public static class CommandsDocsSupport extends DocsV3Support {
838861
private final LogicalPlan command;
839862
private final XPackLicenseState licenseState;
863+
private final ObservabilityTier observabilityTier;
840864

841-
public CommandsDocsSupport(String name, Class<?> testClass, LogicalPlan command, XPackLicenseState licenseState) {
865+
public CommandsDocsSupport(
866+
String name,
867+
Class<?> testClass,
868+
LogicalPlan command,
869+
XPackLicenseState licenseState,
870+
ObservabilityTier observabilityTier
871+
) {
842872
super("commands", name, testClass, Map::of);
843873
this.command = command;
844874
this.licenseState = licenseState;
875+
this.observabilityTier = observabilityTier;
845876
}
846877

847878
@Override
@@ -867,6 +898,9 @@ void renderKibanaCommandDefinition() throws Exception {
867898
if (license != null && license != License.OperationMode.BASIC) {
868899
builder.field("license", license.toString());
869900
}
901+
if (observabilityTier != null && observabilityTier != ObservabilityTier.LOGS_ESSENTIALS) {
902+
builder.field("observability_tier", observabilityTier.toString());
903+
}
870904
String rendered = Strings.toString(builder.endObject());
871905
logger.info("Writing kibana command definition for [{}]:\n{}", name, rendered);
872906
writeToTempKibanaDir("definition", "json", rendered);
@@ -1044,7 +1078,8 @@ void renderKibanaFunctionDefinition(
10441078
String titleName,
10451079
FunctionInfo info,
10461080
List<EsqlFunctionRegistry.ArgSignature> args,
1047-
boolean variadic
1081+
boolean variadic,
1082+
ObservabilityTier observabilityTier
10481083
) throws Exception {
10491084

10501085
try (XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint().lfAtEnd().startObject()) {
@@ -1067,6 +1102,9 @@ void renderKibanaFunctionDefinition(
10671102
if (license != null && license != License.OperationMode.BASIC) {
10681103
builder.field("license", license.toString());
10691104
}
1105+
if (observabilityTier != null && observabilityTier != ObservabilityTier.LOGS_ESSENTIALS) {
1106+
builder.field("observability_tier", observabilityTier.toString());
1107+
}
10701108
if (titleName != null && titleName.equals(name) == false) {
10711109
builder.field("titleName", titleName);
10721110
}

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/logical/CommandLicenseTests.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.elasticsearch.logging.Logger;
1515
import org.elasticsearch.test.ESTestCase;
1616
import org.elasticsearch.xpack.esql.LicenseAware;
17+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier;
18+
import org.elasticsearch.xpack.esql.SupportsObservabilityTier.ObservabilityTier;
1719
import org.elasticsearch.xpack.esql.core.tree.Node;
1820
import org.elasticsearch.xpack.esql.core.tree.Source;
1921
import org.elasticsearch.xpack.esql.expression.function.DocsV3Support;
@@ -74,21 +76,32 @@ private static XPackLicenseState makeLicenseState(License.OperationMode mode) {
7476
private static void checkLicense(String commandName, LogicalPlan command) throws Exception {
7577
log.info("Running function license checks");
7678
TestCheckLicense checkLicense = new TestCheckLicense();
79+
ObservabilityTier observabilityTier = null;
80+
SupportsObservabilityTier supportsObservabilityTier = command.getClass().getAnnotation(SupportsObservabilityTier.class);
81+
if (supportsObservabilityTier != null) {
82+
observabilityTier = supportsObservabilityTier.tier();
83+
}
7784
if (command instanceof LicenseAware licenseAware) {
7885
log.info("Command " + commandName + " implements LicenseAware.");
79-
saveLicenseState(commandName, command, checkLicense.licenseLevel(licenseAware));
86+
saveLicenseState(commandName, command, checkLicense.licenseLevel(licenseAware), observabilityTier);
8087
} else {
8188
log.info("Command " + commandName + " does not implement LicenseAware.");
82-
saveLicenseState(commandName, command, checkLicense.basicLicense);
89+
saveLicenseState(commandName, command, checkLicense.basicLicense, observabilityTier);
8390
}
8491
}
8592

86-
private static void saveLicenseState(String name, LogicalPlan command, XPackLicenseState licenseState) throws Exception {
93+
private static void saveLicenseState(
94+
String name,
95+
LogicalPlan command,
96+
XPackLicenseState licenseState,
97+
SupportsObservabilityTier.ObservabilityTier observabilityTier
98+
) throws Exception {
8799
DocsV3Support.CommandsDocsSupport docs = new DocsV3Support.CommandsDocsSupport(
88100
name.toLowerCase(Locale.ROOT),
89101
CommandLicenseTests.class,
90102
command,
91-
licenseState
103+
licenseState,
104+
observabilityTier
92105
);
93106
docs.renderDocs();
94107
}

0 commit comments

Comments
 (0)