Add GC metric to build statistic

This commit is contained in:
nataliya.valtman
2023-02-27 18:59:00 +01:00
committed by Space Team
parent c16dabba1f
commit a34657195b
12 changed files with 122 additions and 4 deletions
@@ -10,12 +10,14 @@ import java.io.Serializable
data class BuildMetrics(
val buildTimes: BuildTimes = BuildTimes(),
val buildPerformanceMetrics: BuildPerformanceMetrics = BuildPerformanceMetrics(),
val buildAttributes: BuildAttributes = BuildAttributes()
val buildAttributes: BuildAttributes = BuildAttributes(),
val gcMetrics: GcMetrics = GcMetrics()
) : Serializable {
fun addAll(other: BuildMetrics) {
buildTimes.addAll(other.buildTimes)
buildPerformanceMetrics.addAll(other.buildPerformanceMetrics)
buildAttributes.addAll(other.buildAttributes)
gcMetrics.addAll(other.gcMetrics)
}
companion object {
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.build.report.metrics
import java.lang.management.ManagementFactory
interface BuildMetricsReporter {
fun startMeasure(time: BuildTime)
fun endMeasure(time: BuildTime)
@@ -14,6 +16,11 @@ interface BuildMetricsReporter {
fun addMetric(metric: BuildPerformanceMetric, value: Long)
fun addTimeMetric(metric: BuildPerformanceMetric)
//Change metric to enum if possible
fun addGcMetric(metric: String, value: GcMetric)
fun startGcMetric(name: String, value: GcMetric)
fun endGcMetric(name: String, value: GcMetric)
fun addAttribute(attribute: BuildAttribute)
fun getMetrics(): BuildMetrics
@@ -27,4 +34,17 @@ inline fun <T> BuildMetricsReporter.measure(time: BuildTime, fn: () -> T): T {
} finally {
endMeasure(time)
}
}
fun BuildMetricsReporter.startMeasureGc() {
ManagementFactory.getGarbageCollectorMXBeans().forEach {
startGcMetric(it.name, GcMetric(it.collectionTime, it.collectionCount))
}
}
fun BuildMetricsReporter.endMeasureGc() {
ManagementFactory.getGarbageCollectorMXBeans().forEach {
endGcMetric(it.name, GcMetric(it.collectionTime, it.collectionCount))
}
}
@@ -13,9 +13,11 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
EnumMap(
BuildTime::class.java
)
private val myGcPerformance = HashMap<String, GcMetric>()
private val myBuildTimes = BuildTimes()
private val myBuildMetrics = BuildPerformanceMetrics()
private val myBuildAttributes = BuildAttributes()
private val myGcMetrics = GcMetrics()
override fun startMeasure(time: BuildTime) {
if (time in myBuildTimeStartNs) {
@@ -30,6 +32,19 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
myBuildTimes.addTimeNs(time, durationNs)
}
override fun startGcMetric(name: String, value: GcMetric) {
if (name in myGcPerformance) {
error("$name was restarted before it finished")
}
myGcPerformance[name] = value
}
override fun endGcMetric(name: String, value: GcMetric) {
val startValue = myGcPerformance.remove(name) ?: error("$name finished before it started")
val diff = value - startValue
myGcMetrics.add(name, diff)
}
override fun addTimeMetricNs(time: BuildTime, durationNs: Long) {
myBuildTimes.addTimeNs(time, durationNs)
}
@@ -47,6 +62,10 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
}
override fun addGcMetric(metric: String, value: GcMetric) {
myGcMetrics.add(metric, value)
}
override fun addAttribute(attribute: BuildAttribute) {
myBuildAttributes.add(attribute)
}
@@ -55,12 +74,14 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
BuildMetrics(
buildTimes = myBuildTimes,
buildPerformanceMetrics = myBuildMetrics,
buildAttributes = myBuildAttributes
buildAttributes = myBuildAttributes,
gcMetrics = myGcMetrics
)
override fun addMetrics(metrics: BuildMetrics) {
myBuildAttributes.addAll(metrics.buildAttributes)
myBuildTimes.addAll(metrics.buildTimes)
myBuildMetrics.addAll(metrics.buildPerformanceMetrics)
myGcMetrics.addAll(metrics.gcMetrics)
}
}
@@ -18,6 +18,9 @@ enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, va
DAEMON_INCREASED_MEMORY(readableString = "Increase memory usage", type = ValueType.BYTES),
DAEMON_MEMORY_USAGE(readableString = "Total memory usage at the end of build", type = ValueType.BYTES),
DAEMON_GC_TIME(readableString = "Time spent in GC", type = ValueType.NANOSECONDS),
DAEMON_GC_COUNT(readableString = "Count of GC", type = ValueType.NUMBER),
COMPILE_ITERATION(parent = null, "Total compiler iteration", type = ValueType.NUMBER),
ANALYZED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines analyzed", type = ValueType.NUMBER),
CODE_GENERATED_LINES_NUMBER(parent = COMPILE_ITERATION, "Number of lines for code generation", type = ValueType.NUMBER),
@@ -24,6 +24,15 @@ object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun addAttribute(attribute: BuildAttribute) {
}
override fun addGcMetric(metric: String, value: GcMetric) {
}
override fun startGcMetric(name: String, value: GcMetric) {
}
override fun endGcMetric(name: String, value: GcMetric) {
}
override fun getMetrics(): BuildMetrics =
BuildMetrics(
BuildTimes(),
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2023 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.build.report.metrics
import java.io.Serializable
import kotlin.collections.HashMap
class GcMetrics : Serializable {
private val myGcMetrics = HashMap<String, GcMetric>()
fun addAll(gcMetrics: GcMetrics) {
myGcMetrics.putAll(gcMetrics.myGcMetrics)
}
fun add(metric: String, value: GcMetric) {
myGcMetrics[metric] = value
}
fun asGcCountMap(): Map<String, Long> = myGcMetrics.mapValues { it.value.count }
fun asGcTimeMap(): Map<String, Long> = myGcMetrics.mapValues { it.value.time }
fun asMap(): Map<String, GcMetric> = myGcMetrics
}
data class GcMetric(
val time: Long,
val count: Long
): Serializable {
operator fun minus(increment: GcMetric): GcMetric {
return GcMetric(time - increment.time, count - increment.count)
}
}