Skip to content

Commit 508fd0a

Browse files
committed
feat(cli): Add the flag --monitor-stack-traces
If `ort` executes slowly this can become handy for getting a first hint where the CPU work is happening. Note: Print the stack traces in reverse order and the `main` thread's trace at the bottom to have the likely desired information at the most prominent place. Signed-off-by: Frank Viernau <[email protected]>
1 parent 1ba1071 commit 508fd0a

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

cli/src/main/kotlin/OrtMain.kt

+35
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import com.github.ajalt.mordant.rendering.Widget
4242
import com.github.ajalt.mordant.table.ColumnWidth
4343
import com.github.ajalt.mordant.table.grid
4444

45+
import java.time.Duration
46+
4547
import kotlin.system.exitProcess
4648

4749
import org.apache.logging.log4j.kotlin.Logging
@@ -104,6 +106,8 @@ class OrtMain : CliktCommand(
104106
"--debug" to Level.DEBUG
105107
).default(Level.WARN)
106108

109+
private val monitorStackTraces by option(help = "Continuously print out the stack traces of all threads.").flag()
110+
107111
private val stacktrace by option(help = "Print out the stacktrace for all exceptions.").flag()
108112

109113
private val configArguments by option(
@@ -146,6 +150,8 @@ class OrtMain : CliktCommand(
146150
// Make the parameter globally available.
147151
printStackTrace = stacktrace
148152

153+
if (monitorStackTraces) startStacktraceMonitoring()
154+
149155
// Make options available to subcommands and apply static configuration.
150156
val ortConfig = OrtConfiguration.load(args = configArguments, file = configFile)
151157
currentContext.findOrSetObject { ortConfig }
@@ -211,3 +217,32 @@ class OrtMain : CliktCommand(
211217
}
212218
}
213219
}
220+
221+
private fun startStacktraceMonitoring(interval: Duration = Duration.ofSeconds(1)) {
222+
Thread {
223+
while (true) {
224+
Thread.sleep(interval.toMillis())
225+
println(getAllStackTracesAsString())
226+
}
227+
}.start()
228+
}
229+
230+
private fun getAllStackTracesAsString(): String =
231+
buildString {
232+
appendLine("Thread dump")
233+
appendLine()
234+
235+
Thread.getAllStackTraces().entries.sortedWith(
236+
compareBy({ it.key.name == "main" }, { it.key.name })
237+
).forEach { (thread, stackTraceElements) ->
238+
appendLine("[${thread.name}]")
239+
appendLine()
240+
241+
stackTraceElements.reversed().forEach { element ->
242+
append("${element.className}.${element.methodName}() ")
243+
appendLine("[${element.fileName}:${element.lineNumber}]")
244+
}
245+
246+
appendLine()
247+
}
248+
}

0 commit comments

Comments
 (0)