Skip to content

Commit eadfc3d

Browse files
authored
Fix handling of duplicate error messages in test cluster logs (#69494)
1 parent 271dfa7 commit eadfc3d

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java

+19-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.gradle.VersionProperties;
2323
import org.elasticsearch.gradle.http.WaitForHttpResource;
2424
import org.elasticsearch.gradle.info.BuildParams;
25+
import org.elasticsearch.gradle.util.Pair;
2526
import org.gradle.api.Action;
2627
import org.gradle.api.Named;
2728
import org.gradle.api.NamedDomainObjectContainer;
@@ -83,6 +84,7 @@
8384
import java.util.stream.Stream;
8485

8586
import static java.util.Objects.requireNonNull;
87+
import static java.util.Optional.ofNullable;
8688

8789
public class ElasticsearchNode implements TestClusterConfiguration {
8890

@@ -948,7 +950,7 @@ private void logProcessInfo(String prefix, ProcessHandle.Info info) {
948950
}
949951

950952
private void logFileContents(String description, Path from, boolean tailLogs) {
951-
final Map<String, Integer> errorsAndWarnings = new LinkedHashMap<>();
953+
final Map<String, Pair<String, Integer>> errorsAndWarnings = new LinkedHashMap<>();
952954
LinkedList<String> ring = new LinkedList<>();
953955
try (LineNumberReader reader = new LineNumberReader(Files.newBufferedReader(from))) {
954956
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
@@ -960,10 +962,18 @@ private void logFileContents(String description, Path from, boolean tailLogs) {
960962
lineToAdd = line;
961963
// check to see if the previous message (possibly combined from multiple lines) was an error or
962964
// warning as we want to show all of them
963-
String previousMessage = normalizeLogLine(ring.getLast());
964-
if (MESSAGES_WE_DONT_CARE_ABOUT.stream().noneMatch(previousMessage::contains)
965-
&& (previousMessage.contains("ERROR") || previousMessage.contains("WARN"))) {
966-
errorsAndWarnings.put(ring.getLast(), errorsAndWarnings.getOrDefault(previousMessage, 0) + 1);
965+
String normalizedMessage = normalizeLogLine(ring.getLast());
966+
if (MESSAGES_WE_DONT_CARE_ABOUT.stream().noneMatch(normalizedMessage::contains)
967+
&& (normalizedMessage.contains("ERROR") || normalizedMessage.contains("WARN"))) {
968+
969+
// De-duplicate repeated errors
970+
errorsAndWarnings.put(
971+
normalizedMessage,
972+
Pair.of(
973+
ring.getLast(), // Original, non-normalized message (so we keep the first timestamp)
974+
ofNullable(errorsAndWarnings.get(normalizedMessage)).map(p -> p.right() + 1).orElse(1)
975+
)
976+
);
967977
}
968978
} else {
969979
// We combine multi line log messages to make sure we never break exceptions apart
@@ -996,10 +1006,10 @@ private void logFileContents(String description, Path from, boolean tailLogs) {
9961006
}
9971007
if (errorsAndWarnings.isEmpty() == false) {
9981008
LOGGER.lifecycle("\n» ↓ errors and warnings from " + from + " ↓");
999-
errorsAndWarnings.forEach((message, count) -> {
1000-
LOGGER.lifecycle("» " + message.replace("\n", "\n» "));
1001-
if (count > 1) {
1002-
LOGGER.lifecycle("» ↑ repeated " + count + " times ↑");
1009+
errorsAndWarnings.forEach((key, pair) -> {
1010+
LOGGER.lifecycle("» " + pair.left().replace("\n", "\n» "));
1011+
if (pair.right() > 1) {
1012+
LOGGER.lifecycle("» ↑ repeated " + pair.right() + " times ↑");
10031013
}
10041014
});
10051015
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.util;
10+
11+
public class Pair<L, R> {
12+
private final L left;
13+
private final R right;
14+
15+
private Pair(L left, R right) {
16+
this.left = left;
17+
this.right = right;
18+
}
19+
20+
public static <L, R> Pair<L, R> of(L left, R right) {
21+
return new Pair<>(left, right);
22+
}
23+
24+
public L left() {
25+
return left;
26+
}
27+
28+
public R right() {
29+
return right;
30+
}
31+
}

0 commit comments

Comments
 (0)