Skip to content

Commit 55c54dc

Browse files
authored
Merge branch 'main' into fine-grained-loggers
2 parents be7f2b2 + 7ac6e5f commit 55c54dc

File tree

10 files changed

+159
-12
lines changed

10 files changed

+159
-12
lines changed

benchmarks/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ base {
2525
archivesName = 'elasticsearch-benchmarks'
2626
}
2727

28-
tasks.named("test").configure { enabled = false }
2928
tasks.named("javadoc").configure { enabled = false }
3029

3130
configurations {
@@ -52,8 +51,10 @@ dependencies {
5251
api "org.openjdk.jmh:jmh-core:$versions.jmh"
5352
annotationProcessor "org.openjdk.jmh:jmh-generator-annprocess:$versions.jmh"
5453
// Dependencies of JMH
55-
runtimeOnly 'net.sf.jopt-simple:jopt-simple:5.0.4'
54+
runtimeOnly 'net.sf.jopt-simple:jopt-simple:5.0.2'
5655
runtimeOnly 'org.apache.commons:commons-math3:3.6.1'
56+
57+
testImplementation(project(':test:framework'))
5758
}
5859

5960
// enable the JMH's BenchmarkProcessor to generate the final benchmark classes

benchmarks/src/main/java/org/elasticsearch/benchmark/compute/operator/EvalBenchmark.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import org.apache.lucene.util.BytesRef;
1313
import org.elasticsearch.common.breaker.NoopCircuitBreaker;
14+
import org.elasticsearch.common.logging.LogConfigurator;
1415
import org.elasticsearch.common.settings.Settings;
1516
import org.elasticsearch.common.util.BigArrays;
1617
import org.elasticsearch.compute.data.Block;
@@ -28,6 +29,8 @@
2829
import org.elasticsearch.compute.operator.EvalOperator;
2930
import org.elasticsearch.compute.operator.Operator;
3031
import org.elasticsearch.core.TimeValue;
32+
import org.elasticsearch.logging.LogManager;
33+
import org.elasticsearch.logging.Logger;
3134
import org.elasticsearch.xpack.esql.core.expression.Expression;
3235
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
3336
import org.elasticsearch.xpack.esql.core.expression.FoldContext;
@@ -89,9 +92,16 @@ public class EvalBenchmark {
8992
static final DriverContext driverContext = new DriverContext(BigArrays.NON_RECYCLING_INSTANCE, blockFactory);
9093

9194
static {
95+
LogConfigurator.configureESLogging();
9296
// Smoke test all the expected values and force loading subclasses more like prod
97+
selfTest();
98+
}
99+
100+
static void selfTest() {
101+
Logger log = LogManager.getLogger(EvalBenchmark.class);
93102
try {
94103
for (String operation : EvalBenchmark.class.getField("operation").getAnnotationsByType(Param.class)[0].value()) {
104+
log.info("self testing {}", operation);
95105
run(operation);
96106
}
97107
} catch (NoSuchFieldException e) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.benchmark.compute.operator;
11+
12+
import org.elasticsearch.test.ESTestCase;
13+
14+
public class EvalBenchmarkTests extends ESTestCase {
15+
public void testSelfTest() {
16+
EvalBenchmark.selfTest();
17+
}
18+
}

distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
6666
"-Dlog4j2.disable.jmx=true",
6767
"-Dlog4j2.formatMsgNoLookups=true",
6868
"-Djava.locale.providers=CLDR",
69+
// Enable vectorization for whatever version we are running. This ensures we use vectorization even when running EA builds.
70+
"-Dorg.apache.lucene.vectorization.upperJavaFeatureVersion=" + Runtime.version().feature(),
6971
// Pass through distribution type
7072
"-Des.distribution.type=" + distroType
7173
),

docs/changelog/124823.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 124823
2+
summary: Report failures on partial results
3+
area: "ES|QL"
4+
type: enhancement
5+
issues: []

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractCrossClusterTestCase.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.util.concurrent.atomic.AtomicLong;
4141

4242
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
43+
import static org.hamcrest.Matchers.aMapWithSize;
4344
import static org.hamcrest.Matchers.equalTo;
4445
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
4546

@@ -143,7 +144,27 @@ protected static void assertClusterMetadataInResponse(EsqlQueryResponse resp, bo
143144
assertThat((int) inner.get("total"), equalTo(numClusters));
144145
assertTrue(inner.containsKey("details"));
145146
} else {
146-
assertNull(clusters);
147+
final Object partial = esqlResponseAsMap.get("is_partial");
148+
if (partial != null && (Boolean) partial) {
149+
// If we have partial response, we could have cluster metadata, it should contain details.
150+
// Details should not be empty, and it should contain clusters with failures.
151+
if (clusters != null) {
152+
@SuppressWarnings("unchecked")
153+
Map<String, Object> inner = (Map<String, Object>) clusters;
154+
assertThat(inner, aMapWithSize(1));
155+
assertTrue(inner.containsKey("details"));
156+
@SuppressWarnings("unchecked")
157+
Map<String, Object> details = (Map<String, Object>) inner.get("details");
158+
assertThat(details.size(), greaterThanOrEqualTo(1));
159+
details.forEach((k, v) -> {
160+
@SuppressWarnings("unchecked")
161+
Map<String, Object> cluster = (Map<String, Object>) v;
162+
assertTrue(cluster.containsKey("failures"));
163+
});
164+
}
165+
} else {
166+
assertNull(clusters);
167+
}
147168
}
148169
} catch (IOException e) {
149170
fail("Could not convert ESQLQueryResponse to Map: " + e);

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlExecutionInfo.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ public boolean isCrossClusterSearch() {
218218
|| clusterInfo.size() == 1 && clusterInfo.containsKey(RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY) == false;
219219
}
220220

221+
/**
222+
* Is there any metadata to report in the response?
223+
* This is true on cross-cluster search with includeCCSMetadata=true or when there are partial failures.
224+
*/
225+
public boolean hasMetadataToReport() {
226+
return isCrossClusterSearch() && includeCCSMetadata
227+
|| (isPartial && clusterInfo.values().stream().anyMatch(c -> c.getFailures().isEmpty() == false));
228+
}
229+
221230
public Cluster getCluster(String clusterAlias) {
222231
return clusterInfo.get(clusterAlias);
223232
}
@@ -257,9 +266,13 @@ public Cluster swapCluster(String clusterAlias, BiFunction<String, Cluster, Clus
257266

258267
@Override
259268
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
260-
if (isCrossClusterSearch() == false || clusterInfo.isEmpty()) {
269+
if (clusterInfo.isEmpty()) {
261270
return Collections.emptyIterator();
262271
}
272+
if (includeCCSMetadata == false) {
273+
// If includeCCSMetadata is false, the only reason we're here is partial failures, so just report them.
274+
return onlyFailuresToXContent();
275+
}
263276
Map<Cluster.Status, Integer> clusterStatuses = new EnumMap<>(Cluster.Status.class);
264277
for (Cluster info : clusterInfo.values()) {
265278
clusterStatuses.merge(info.getStatus(), 1, Integer::sum);
@@ -280,6 +293,19 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params
280293
);
281294
}
282295

296+
private Iterator<? extends ToXContent> onlyFailuresToXContent() {
297+
Iterator<Cluster> failuresIterator = clusterInfo.values().stream().filter(c -> (c.getFailures().isEmpty() == false)).iterator();
298+
if (failuresIterator.hasNext()) {
299+
return Iterators.concat(
300+
ChunkedToXContentHelper.startObject(),
301+
ChunkedToXContentHelper.object("details", failuresIterator),
302+
ChunkedToXContentHelper.endObject()
303+
);
304+
} else {
305+
return Collections.emptyIterator();
306+
}
307+
}
308+
283309
/**
284310
* @param status the status you want to access
285311
* @return a stream of clusters with that status

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponse.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,9 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params
228228
Iterator<ToXContent> profileRender = profile != null
229229
? ChunkedToXContentHelper.field("profile", profile, params)
230230
: Collections.emptyIterator();
231-
Iterator<ToXContent> executionInfoRender = executionInfo != null
232-
&& executionInfo.isCrossClusterSearch()
233-
&& executionInfo.includeCCSMetadata()
234-
? ChunkedToXContentHelper.field("_clusters", executionInfo, params)
235-
: Collections.emptyIterator();
231+
Iterator<ToXContent> executionInfoRender = executionInfo != null && executionInfo.hasMetadataToReport()
232+
? ChunkedToXContentHelper.field("_clusters", executionInfo, params)
233+
: Collections.emptyIterator();
236234
return Iterators.concat(
237235
ChunkedToXContentHelper.startObject(),
238236
asyncPropertiesOrEmpty(),

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/AbstractConvertFunction.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
import joptsimple.internal.Strings;
1111

12-
import org.apache.commons.logging.Log;
13-
import org.apache.commons.logging.LogFactory;
1412
import org.elasticsearch.common.io.stream.StreamInput;
1513
import org.elasticsearch.compute.data.Block;
1614
import org.elasticsearch.compute.data.Page;
@@ -19,6 +17,8 @@
1917
import org.elasticsearch.compute.operator.EvalOperator;
2018
import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
2119
import org.elasticsearch.compute.operator.Warnings;
20+
import org.elasticsearch.logging.LogManager;
21+
import org.elasticsearch.logging.Logger;
2222
import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException;
2323
import org.elasticsearch.xpack.esql.core.expression.Expression;
2424
import org.elasticsearch.xpack.esql.core.tree.Source;
@@ -127,7 +127,7 @@ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) {
127127

128128
public abstract static class AbstractEvaluator implements EvalOperator.ExpressionEvaluator {
129129

130-
private static final Log logger = LogFactory.getLog(AbstractEvaluator.class);
130+
private static final Logger logger = LogManager.getLogger(AbstractEvaluator.class);
131131

132132
protected final DriverContext driverContext;
133133
private final Warnings warnings;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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.action;
9+
10+
import org.elasticsearch.action.search.ShardSearchFailure;
11+
import org.elasticsearch.test.ESTestCase;
12+
import org.elasticsearch.transport.RemoteClusterService;
13+
14+
import java.util.List;
15+
16+
public class EsqlExecutionInfoTests extends ESTestCase {
17+
18+
static final EsqlExecutionInfo.Cluster localCluster = new EsqlExecutionInfo.Cluster(
19+
RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY,
20+
"test"
21+
);
22+
static final EsqlExecutionInfo.Cluster remoteCluster = new EsqlExecutionInfo.Cluster("remote", "test");
23+
24+
public void testHasMetadataInclude() {
25+
// includeCCSMetadata + non-local clusters will produce true
26+
EsqlExecutionInfo info = new EsqlExecutionInfo(true);
27+
assertFalse(info.hasMetadataToReport());
28+
info.swapCluster(RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY, (k, v) -> localCluster);
29+
assertFalse(info.hasMetadataToReport());
30+
info.swapCluster("remote", (k, v) -> remoteCluster);
31+
assertTrue(info.hasMetadataToReport());
32+
// Only remote is enough
33+
info = new EsqlExecutionInfo(true);
34+
info.swapCluster("remote", (k, v) -> remoteCluster);
35+
assertTrue(info.hasMetadataToReport());
36+
}
37+
38+
public void testHasMetadataIncludeFalse() {
39+
// If includeCCSMetadata is false, then it should always return false
40+
EsqlExecutionInfo info = new EsqlExecutionInfo(false);
41+
assertFalse(info.hasMetadataToReport());
42+
assertFalse(info.hasMetadataToReport());
43+
info.swapCluster(RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY, (k, v) -> localCluster);
44+
assertFalse(info.hasMetadataToReport());
45+
info.swapCluster("remote", (k, v) -> remoteCluster);
46+
assertFalse(info.hasMetadataToReport());
47+
}
48+
49+
public void testHasMetadataPartial() {
50+
EsqlExecutionInfo info = new EsqlExecutionInfo(false);
51+
String key = randomFrom(RemoteClusterService.LOCAL_CLUSTER_GROUP_KEY, "remote");
52+
info.swapCluster(key, (k, v) -> new EsqlExecutionInfo.Cluster(k, "test", false, EsqlExecutionInfo.Cluster.Status.SUCCESSFUL));
53+
assertFalse(info.isPartial());
54+
assertFalse(info.hasMetadataToReport());
55+
info.swapCluster(key, (k, v) -> new EsqlExecutionInfo.Cluster(k, "test", false, EsqlExecutionInfo.Cluster.Status.PARTIAL));
56+
assertTrue(info.isPartial());
57+
assertFalse(info.hasMetadataToReport());
58+
info.swapCluster(key, (k, v) -> {
59+
EsqlExecutionInfo.Cluster.Builder builder = new EsqlExecutionInfo.Cluster.Builder(v);
60+
builder.setFailures(List.of(new ShardSearchFailure(new IllegalStateException("shard failure"))));
61+
return builder.build();
62+
});
63+
assertTrue(info.hasMetadataToReport());
64+
}
65+
66+
}

0 commit comments

Comments
 (0)