Added heapDumper for perfTests

This commit is contained in:
Vladimir Dolzhenko
2020-05-26 11:09:02 +02:00
parent 2f79b4c412
commit bf5c7aea4d
3 changed files with 70 additions and 4 deletions
@@ -207,7 +207,7 @@ class Stats(
if (k == TEST_KEY) continue if (k == TEST_KEY) continue
TeamCity.statValue("$n $k", v) TeamCity.statValue("$n $k", v)
(v as? Number)?.let { (v as? Number)?.let {
TeamCity.testMetadata(n, k, it) TeamCity.metadata(n, k, it)
} }
} }
} }
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.perf.util
import com.intellij.openapi.util.io.FileUtilRt
import com.sun.management.HotSpotDiagnosticMXBean
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.lang.management.ManagementFactory
import java.text.SimpleDateFormat
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
object HeapDumper {
private const val HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"
private val hotspotMBean = initHotspotMBean()
private fun initHotspotMBean() = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
HOTSPOT_BEAN_NAME,
HotSpotDiagnosticMXBean::class.java
)
fun dumpHeap(fileNamePrefix: String, live: Boolean = true) {
val format = SimpleDateFormat("yyyyMMdd-HHmmss")
val timestamp = format.format(Date())
val tempFile = File.createTempFile(fileNamePrefix, ".hprof")
tempFile.delete()
val fileName = "build/$fileNamePrefix-$timestamp.hprof.zip"
logMessage { "Dumping a heap into $tempFile ..." }
try {
hotspotMBean.dumpHeap(tempFile.toString(), live)
logMessage { "Heap dump is $tempFile ready." }
zipFile(tempFile, File(fileName))
val testName = "Heap dump $timestamp"
TeamCity.test(testName) {
TeamCity.artifact(testName, "heapDump", fileName)
}
} catch (e: Exception) {
logMessage { "Error on making a heap dump: ${e.message}" }
e.printStackTrace()
}
}
private fun zipFile(srcFile: File, targetFile: File) {
FileInputStream(srcFile).use { fis ->
ZipOutputStream(FileOutputStream(targetFile)).use { os ->
os.putNextEntry(ZipEntry(srcFile.name))
FileUtilRt.copy(fis, os)
os.closeEntry()
}
}
}
}
@@ -9,7 +9,7 @@ import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
inline fun gradleMessage(block: () -> String) { inline fun gradleMessage(block: () -> String) {
print("#gradle ${block()}") //print("#gradle ${block()}")
} }
inline fun logMessage(message: () -> String) { inline fun logMessage(message: () -> String) {
@@ -64,12 +64,16 @@ object TeamCity {
message { "testStarted name='$testName'" } message { "testStarted name='$testName'" }
} }
inline fun testMetadata(testName: String, name: String, value: Number) { inline fun metadata(testName: String, name: String, value: Number) {
message { "testMetadata testName='$testName' name='$name' type='number' value='$value'" } message { "testMetadata testName='$testName' name='$name' type='number' value='$value'" }
} }
inline fun artifact(testName: String, name: String, artifactPath: String) {
message { "testMetadata testName='$testName' name='$name' type='artifact' value='$artifactPath'" }
}
inline fun testFinished(testName: String, durationMs: Long? = null) { inline fun testFinished(testName: String, durationMs: Long? = null) {
message { "testFinished name='$testName'${durationMs?.let { " duration='$durationMs'" }}" } message { "testFinished name='$testName'${durationMs?.let { " duration='$durationMs'" } ?: ""}" }
} }
fun testFailed(testName: String, error: Throwable) = testFailed(testName, toDetails(listOf(error))!!) fun testFailed(testName: String, error: Throwable) = testFailed(testName, toDetails(listOf(error))!!)