Settings for heap dumps creation (#304)
This commit is contained in:
82
src/main/kotlin/io/emeraldpay/dshackle/HeapDumpCreator.kt
Normal file
82
src/main/kotlin/io/emeraldpay/dshackle/HeapDumpCreator.kt
Normal file
@@ -0,0 +1,82 @@
|
||||
package io.emeraldpay.dshackle
|
||||
|
||||
import com.sun.management.HotSpotDiagnosticMXBean
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.util.ResourceUtils
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.lang.management.ManagementFactory
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class HeapDumpCreator {
|
||||
companion object {
|
||||
private const val MAX_DUMPS = 3
|
||||
|
||||
private val log = LoggerFactory.getLogger(HeapDumpCreator::class.java)
|
||||
private val executorService = Executors.newSingleThreadScheduledExecutor()
|
||||
|
||||
fun init() {
|
||||
val envVars = System.getenv()
|
||||
val enableCreateDumps = envVars["HEAP_DUMP_ENABLE"]?.toBoolean() ?: true
|
||||
val dumpsPath = envVars["HEAP_DUMP_PATH"] ?: "/etc/dshackle/dumps"
|
||||
val dumpsPathExists = heapDumpsPathExists(dumpsPath)
|
||||
.also {
|
||||
if (!it) {
|
||||
log.warn("$dumpsPath does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
if (enableCreateDumps && dumpsPathExists) {
|
||||
executorService.scheduleAtFixedRate({ dumpCheckTask(dumpsPath) }, 0, 30, TimeUnit.MINUTES)
|
||||
|
||||
configHeapDump(dumpsPath)
|
||||
} else {
|
||||
log.warn("Heap dump creation is turned off")
|
||||
}
|
||||
}
|
||||
|
||||
private fun configHeapDump(dumpsPath: String) {
|
||||
val date = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
|
||||
val fileName = "$dumpsPath/heap_$date.hprof"
|
||||
|
||||
val bean = ManagementFactory.newPlatformMXBeanProxy(
|
||||
ManagementFactory.getPlatformMBeanServer(),
|
||||
"com.sun.management:type=HotSpotDiagnostic",
|
||||
HotSpotDiagnosticMXBean::class.java
|
||||
)
|
||||
bean.setVMOption("HeapDumpOnOutOfMemoryError", "true")
|
||||
bean.setVMOption("HeapDumpPath", fileName)
|
||||
}
|
||||
|
||||
private fun heapDumpsPathExists(dumpsPath: String): Boolean {
|
||||
return try {
|
||||
ResourceUtils.getFile(dumpsPath).exists()
|
||||
} catch (e: FileNotFoundException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun dumpCheckTask(dumpsPath: String) {
|
||||
val files = File(dumpsPath).listFiles()
|
||||
?.filter { it.name.endsWith("hprof") }
|
||||
?: emptyList()
|
||||
|
||||
if (files.isNotEmpty()) {
|
||||
log.warn("There are some heap dumps, please send them to dshackle developers")
|
||||
}
|
||||
if (files.size >= MAX_DUMPS) {
|
||||
files.minBy {
|
||||
Files.readAttributes(Paths.get(it.absolutePath), BasicFileAttributes::class.java).creationTime()
|
||||
}.run {
|
||||
this.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,8 @@ fun main(args: Array<String>) {
|
||||
|
||||
Schedulers.enableMetrics()
|
||||
|
||||
HeapDumpCreator.init()
|
||||
|
||||
val maxMemory: Long = Runtime.getRuntime().maxMemory() / (1024 * 1024).toLong()
|
||||
log.info("Max heap size: {} MB", maxMemory)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user