@@ -10,13 +10,15 @@ tasks.withType(Test).configureEach { testTask ->
1010 t
1111 })
1212
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())
1515
1616 def future = scheduler. schedule({
17+ logger. warn(" Taking dumps for: ${ testTask.getPath()} after ${ delayMinutes} minutes." )
18+
1719 try {
1820 // 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 {
2022 if (providers. environmentVariable(" CI" ). isPresent()) {
2123 // Move reports into the folder collected by the collect_reports.sh script.
2224 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 ->
2527 }
2628 }. get()
2729
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()
2939
3040 // Collect PIDs of all Java processes.
3141 def jvmProcesses = ' jcmd -l' . execute(). text. readLines()
@@ -36,20 +46,18 @@ tasks.withType(Test).configureEach { testTask ->
3646 .collect({ it. substring(0 , it. indexOf(' ' )) })
3747
3848 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()
4053
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" )
4356 new ProcessBuilder (' jcmd' , pid, ' Thread.print' , ' -l' )
4457 .redirectErrorStream(true )
4558 .redirectOutput(threadDumpFile)
4659 .start()
4760 .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()
5361 }
5462 } catch (Throwable e) {
5563 logger. warn(" Dumping failed: ${ e.message} " )
0 commit comments