Skip to content

Commit ee802ad

Browse files
authored
Test: Add dump of integ test cluster logs on failure (#23688)
This commit adds a build listener to the integ test runner which will print out an excerpt of the logs from the integ test cluster if the test run fails. There are future improvements that can be made (for example, to dump excerpts from dependent clusters like in tribe node tests), but this is a start, and would help with simple rest tests failures that we currently don't know what actually happened on the node.
1 parent b31ed6a commit ee802ad

File tree

1 file changed

+62
-1
lines changed

1 file changed

+62
-1
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/RestIntegTestTask.groovy

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ import com.carrotsearch.gradle.junit4.RandomizedTestingTask
2222
import org.elasticsearch.gradle.BuildPlugin
2323
import org.gradle.api.DefaultTask
2424
import org.gradle.api.Task
25+
import org.gradle.api.execution.TaskExecutionAdapter
2526
import org.gradle.api.internal.tasks.options.Option
2627
import org.gradle.api.plugins.JavaBasePlugin
2728
import org.gradle.api.tasks.Input
28-
import org.gradle.util.ConfigureUtil
29+
import org.gradle.api.tasks.TaskState
30+
31+
import java.nio.charset.StandardCharsets
32+
import java.nio.file.Files
33+
import java.util.stream.Stream
2934

3035
/**
3136
* A wrapper task around setting up a cluster and running rest tests.
@@ -71,6 +76,24 @@ public class RestIntegTestTask extends DefaultTask {
7176
// both as separate sysprops
7277
runner.systemProperty('tests.cluster', "${-> nodes[0].transportUri()}")
7378

79+
// dump errors and warnings from cluster log on failure
80+
TaskExecutionAdapter logDumpListener = new TaskExecutionAdapter() {
81+
@Override
82+
void afterExecute(Task task, TaskState state) {
83+
if (state.failure != null) {
84+
for (NodeInfo nodeInfo : nodes) {
85+
printLogExcerpt(nodeInfo)
86+
}
87+
}
88+
}
89+
}
90+
runner.doFirst {
91+
project.gradle.addListener(logDumpListener)
92+
}
93+
runner.doLast {
94+
project.gradle.removeListener(logDumpListener)
95+
}
96+
7497
// copy the rest spec/tests into the test resources
7598
RestSpecHack.configureDependencies(project)
7699
project.afterEvaluate {
@@ -126,4 +149,42 @@ public class RestIntegTestTask extends DefaultTask {
126149
public Task mustRunAfter(Object... tasks) {
127150
clusterInit.mustRunAfter(tasks)
128151
}
152+
153+
/** Print out an excerpt of the log from the given node. */
154+
protected static void printLogExcerpt(NodeInfo nodeInfo) {
155+
File logFile = new File(nodeInfo.homeDir, "logs/${nodeInfo.clusterName}.log")
156+
println("\nCluster ${nodeInfo.clusterName} - node ${nodeInfo.nodeNum} log excerpt:")
157+
println("(full log at ${logFile})")
158+
println('-----------------------------------------')
159+
Stream<String> stream = Files.lines(logFile.toPath(), StandardCharsets.UTF_8)
160+
try {
161+
boolean inStartup = true
162+
boolean inExcerpt = false
163+
int linesSkipped = 0
164+
for (String line : stream) {
165+
if (line.startsWith("[")) {
166+
inExcerpt = false // clear with the next log message
167+
}
168+
if (line =~ /(\[WARN\])|(\[ERROR\])/) {
169+
inExcerpt = true // show warnings and errors
170+
}
171+
if (inStartup || inExcerpt) {
172+
if (linesSkipped != 0) {
173+
println("... SKIPPED ${linesSkipped} LINES ...")
174+
}
175+
println(line)
176+
linesSkipped = 0
177+
} else {
178+
++linesSkipped
179+
}
180+
if (line =~ /recovered \[\d+\] indices into cluster_state/) {
181+
inStartup = false
182+
}
183+
}
184+
} finally {
185+
stream.close()
186+
}
187+
println('=========================================')
188+
189+
}
129190
}

0 commit comments

Comments
 (0)