@@ -10,13 +10,15 @@ tasks.withType(Test).configureEach { testTask ->
10
10
t
11
11
})
12
12
13
- // Calculate delay for taking dumps as test timeout minus 2 minutes, but no less than 1 minute.
14
- def delayMinutes = Math . max(1L , timeout. get(). minusMinutes(2 ). toMinutes())
13
+ // Calculate delay for taking dumps as test timeout minus 1 minutes, but no less than 1 minute.
14
+ def delayMinutes = Math . max(1L , timeout. get(). minusMinutes(1 ). toMinutes())
15
15
16
16
def future = scheduler. schedule({
17
+ logger. warn(" Taking dumps for: ${ testTask.getPath()} after ${ delayMinutes} minutes." )
18
+
17
19
try {
18
20
// Use Gradle's build dir and adjust for CI artifacts collection if needed.
19
- def dumpDir = layout. buildDirectory. dir(' dumps' ). map {
21
+ def dumpsDir = layout. buildDirectory. dir(' dumps' ). map {
20
22
if (providers. environmentVariable(" CI" ). isPresent()) {
21
23
// Move reports into the folder collected by the collect_reports.sh script.
22
24
new File (it. getAsFile(). absolutePath. replace(' dd-trace-java/dd-java-agent' , ' dd-trace-java/workspace/dd-java-agent' ))
@@ -25,7 +27,15 @@ tasks.withType(Test).configureEach { testTask ->
25
27
}
26
28
}. get()
27
29
28
- dumpDir. mkdirs()
30
+ dumpsDir. mkdirs()
31
+
32
+ // For simplicity, use `0` as the PID, which collects all thread dumps across JVMs.
33
+ // Single file can be useful for quick search.
34
+ def threadDumpsFile = new File (dumpsDir, " all-thread-dumps-${ System.currentTimeMillis()} .log" )
35
+ new ProcessBuilder (" jcmd" , " 0" , " Thread.print" , " -l" )
36
+ .redirectErrorStream(true )
37
+ .redirectOutput(threadDumpsFile)
38
+ .start(). waitFor()
29
39
30
40
// Collect PIDs of all Java processes.
31
41
def jvmProcesses = ' jcmd -l' . execute(). text. readLines()
@@ -36,20 +46,18 @@ tasks.withType(Test).configureEach { testTask ->
36
46
.collect({ it. substring(0 , it. indexOf(' ' )) })
37
47
38
48
pids. each { pid ->
39
- logger. warn(" Taking dumps for: ${ testTask.getPath()} " )
49
+ // Collect heap dump by pid.
50
+ def heapDumpFile = new File (dumpsDir, " ${ pid} -heap-dump-${ System.currentTimeMillis()} .hprof" ). absolutePath
51
+ def cmd = " jcmd ${ pid} GC.heap_dump ${ heapDumpFile} "
52
+ cmd. execute(). waitFor()
40
53
41
- // Collect thread dump.
42
- def threadDumpFile = new File (dumpDir , " ${ pid} -thread-dump-${ System.currentTimeMillis()} .log" )
54
+ // Collect thread dump by pid .
55
+ def threadDumpFile = new File (dumpsDir , " ${ pid} -thread-dump-${ System.currentTimeMillis()} .log" )
43
56
new ProcessBuilder (' jcmd' , pid, ' Thread.print' , ' -l' )
44
57
.redirectErrorStream(true )
45
58
.redirectOutput(threadDumpFile)
46
59
.start()
47
60
.waitFor()
48
-
49
- // Collect heap dump.
50
- def heapDumpFile = new File (dumpDir, " ${ pid} -heap-dump-${ System.currentTimeMillis()} .hprof" ). absolutePath
51
- def cmd = " jcmd ${ pid} GC.heap_dump ${ heapDumpFile} "
52
- cmd. execute(). waitFor()
53
61
}
54
62
} catch (Throwable e) {
55
63
logger. warn(" Dumping failed: ${ e.message} " )
0 commit comments