Coverage Summary for Class: Profiling (dev.suresh)

Class Method, % Branch, % Line, % Instruction, %
Profiling 0% (0/9) 0% (0/9) 0% (0/66)
Profiling$convertJfr-8Mi8wO0$$inlined$runOnVirtualThread$1 0% (0/1)
Profiling$heapdump$$inlined$runOnVirtualThread$1 0% (0/1)
Profiling$jfrSnapshot$2$3 0% (0/1) 0% (0/1) 0% (0/15)
Profiling$jfrSnapshot-KLykuaI$$inlined$runOnVirtualThread$1 0% (0/1)
Profiling$threaddump$$inlined$runOnVirtualThread$1 0% (0/1)
Total 0% (0/14) 0% (0/10) 0% (0/81)


 @file:Suppress("DuplicatedCode")
 
 package dev.suresh
 
 import BuildConfig
 import com.sun.management.HotSpotDiagnosticMXBean
 import io.github.oshai.kotlinlogging.KotlinLogging
 import java.io.ByteArrayOutputStream
 import java.lang.management.ManagementFactory
 import java.nio.charset.StandardCharsets
 import java.nio.file.Path
 import jdk.jfr.Configuration
 import jdk.jfr.FlightRecorder
 import jdk.jfr.consumer.RecordingStream
 import jdk.management.VirtualThreadSchedulerMXBean
 import kotlin.io.path.*
 import kotlin.time.Duration
 import kotlin.time.Duration.Companion.milliseconds
 import kotlin.time.Duration.Companion.minutes
 import kotlin.time.Duration.Companion.seconds
 import kotlin.time.toJavaDuration
 import me.saket.bytesize.*
 import one.convert.*
 import one.jfr.JfrReader
 
 object Profiling {
 
   private val log = KotlinLogging.logger {}
 
   const val diagnosticObjName = "com.sun.management:type=HotSpotDiagnostic"
 
   val virtualThreadMxBean by lazy {
     ManagementFactory.getPlatformMXBean(VirtualThreadSchedulerMXBean::class.java)
   }
 
   suspend fun threaddump(): Path = runOnVirtualThread {
     val server = ManagementFactory.getPlatformMBeanServer()
     val hotspot =
         ManagementFactory.newPlatformMXBeanProxy(
             server, diagnosticObjName, HotSpotDiagnosticMXBean::class.java)
 
     val heapDumpPath = createTempFile("heapdump", ".hprof")
     heapDumpPath.deleteIfExists()
     // hotspot.dumpThreads(ThreadDumpFormat.valueOf())
     hotspot.dumpHeap(heapDumpPath.pathString, true)
     heapDumpPath
   }
 
   suspend fun heapdump(): Path = runOnVirtualThread {
     val server = ManagementFactory.getPlatformMBeanServer()
     val hotspot =
         ManagementFactory.newPlatformMXBeanProxy(
             server, diagnosticObjName, HotSpotDiagnosticMXBean::class.java)
 
     val heapDumpPath = createTempFile("heapdump", ".hprof")
     heapDumpPath.deleteIfExists()
     hotspot.dumpHeap(heapDumpPath.pathString, true)
     heapDumpPath
   }
 
   suspend fun jfrSnapshot(maxAge: Duration = 2.minutes, maxSizeBytes: Long = 100_000_000): Path =
       runOnVirtualThread {
         val jfrPath = createTempFile("profile", ".jfr")
         val flightRecorder = FlightRecorder.getFlightRecorder()
         when {
           flightRecorder.recordings.isEmpty() ->
               RecordingStream(Configuration.getConfiguration("profile")).use {
                 it.setMaxSize(maxSizeBytes)
                 it.setMaxAge(maxAge.toJavaDuration())
                 it.enable("jdk.CPULoad").withPeriod(100.milliseconds.toJavaDuration())
                 it.enable("jdk.JavaMonitorEnter").withStackTrace()
                 it.startAsync()
                 Thread.sleep(5.seconds.toJavaDuration())
                 it.dump(jfrPath)
               }
           else ->
               flightRecorder.takeSnapshot().use {
                 if (it.size > 0) {
                   it.maxSize = maxSizeBytes
                   it.maxAge = maxAge.toJavaDuration()
                   it.dump(jfrPath)
                 }
               }
         }
         log.info {
           "JFR file written to ${jfrPath.toAbsolutePath()} (${jfrPath.fileSize().decimalBytes})"
         }
         jfrPath
       }
 
   suspend fun convertJfr(format: String = "html", maxAge: Duration = 2.minutes): String =
       runOnVirtualThread {
         val jfrPath = jfrSnapshot(maxAge, 100_000_000)
         val args = Arguments("--output", format, "--reverse", "--title", BuildConfig.name)
 
         val converter =
             JfrReader(jfrPath.pathString).use {
               when (format) {
                 "heatmap" -> JfrToHeatmap(it, args)
                 "html" -> JfrToFlame(it, args)
                 else -> error("Unsupported format: $format")
               }.apply { convert() }
             }
 
         val result =
             ByteArrayOutputStream().use { out ->
               when (converter) {
                 is JfrToHeatmap -> converter.dump(out)
                 is JfrToFlame -> converter.dump(out)
                 else -> error("Unsupported converter for $format")
               }
               out.toString(StandardCharsets.UTF_8)
             }
         jfrPath.deleteIfExists()
         result
       }
 }