Report compiler performance data to ES

This commit is contained in:
nataliya.valtman
2021-07-28 05:42:15 +03:00
parent 7357aeb1c9
commit 260d301100
20 changed files with 136 additions and 29 deletions
@@ -9,10 +9,12 @@ import java.io.Serializable
data class BuildMetrics(
val buildTimes: BuildTimes = BuildTimes(),
val buildPerformanceMetrics: BuildPerformanceMetrics = BuildPerformanceMetrics(),
val buildAttributes: BuildAttributes = BuildAttributes()
) : Serializable {
fun addAll(other: BuildMetrics) {
buildTimes.addAll(other.buildTimes)
buildPerformanceMetrics.addAll(other.buildPerformanceMetrics)
buildAttributes.addAll(other.buildAttributes)
}
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.build.report.metrics
interface BuildMetricsReporter {
fun startMeasure(time: BuildTime, startNs: Long)
fun endMeasure(time: BuildTime, endNs: Long)
fun addMetric(metric: BuildTime, value: Long)
fun addTimeMetric(time: BuildTime, durationMs: Long)
fun addMetric(metric: BuildPerformanceMetric, value: Long)
fun addAttribute(attribute: BuildAttribute)
@@ -13,6 +13,7 @@ class BuildMetricsReporterImpl : BuildMetricsReporter {
BuildTime::class.java
)
private val myBuildTimes = BuildTimes()
private val myBuildMetrics = BuildPerformanceMetrics()
private val myBuildAttributes = BuildAttributes()
override fun startMeasure(time: BuildTime, startNs: Long) {
@@ -28,8 +29,12 @@ class BuildMetricsReporterImpl : BuildMetricsReporter {
myBuildTimes.add(time, durationMs)
}
override fun addMetric(metric: BuildTime, value: Long) {
myBuildTimes.add(metric, value)
override fun addTimeMetric(time: BuildTime, durationMs: Long) {
myBuildTimes.add(time, durationMs)
}
override fun addMetric(metric: BuildPerformanceMetric, value: Long) {
myBuildMetrics.add(metric, value)
}
override fun addAttribute(attribute: BuildAttribute) {
@@ -39,6 +44,7 @@ class BuildMetricsReporterImpl : BuildMetricsReporter {
override fun getMetrics(): BuildMetrics =
BuildMetrics(
buildTimes = myBuildTimes,
buildPerformanceMetrics = myBuildMetrics,
buildAttributes = myBuildAttributes
)
@@ -47,5 +53,6 @@ class BuildMetricsReporterImpl : BuildMetricsReporter {
myBuildAttributes.addAll(metrics.buildAttributes)
myBuildTimes.addAll(metrics.buildTimes)
myBuildMetrics.addAll(metrics.buildPerformanceMetrics)
}
}
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2021 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
@Suppress("Reformat")
enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, val readableString: String) : Serializable {
OUTPUT_SIZE(readableString = "Total output size"),
LOOKUP_SIZE(OUTPUT_SIZE, "Lookups size"),
SNAPSHOT_SIZE(OUTPUT_SIZE, "ABI snapshot size"),
;
companion object {
const val serialVersionUID = 0L
val children by lazy {
values().filter { it.parent != null }.groupBy { it.parent }
}
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2021 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 java.util.*
class BuildPerformanceMetrics : Serializable {
companion object {
const val serialVersionUID = 0L
}
private val myBuildMetrics = EnumMap<BuildPerformanceMetric, Long>(BuildPerformanceMetric::class.java)
fun addAll(other: BuildPerformanceMetrics) {
for ((bt, timeNs) in other.myBuildMetrics) {
add(bt, timeNs)
}
}
fun add(metric: BuildPerformanceMetric, value: Long) {
myBuildMetrics[metric] = myBuildMetrics.getOrDefault(metric, 0) + value
}
fun asMap(): Map<BuildPerformanceMetric, Long> = myBuildMetrics
}
@@ -38,9 +38,10 @@ enum class BuildTime(val parent: BuildTime? = null, val readableString: String)
INCREMENTAL_ITERATION(INCREMENTAL_COMPILATION, "Incremental iteration"),
NON_INCREMENTAL_ITERATION(INCREMENTAL_COMPILATION, "Non-incremental iteration"),
IC_WRITE_HISTORY_FILE(INCREMENTAL_COMPILATION, "Write history file"),
OUTPUT_SIZE(readableString = "Total output size"),
LOOKUP_SIZE(OUTPUT_SIZE, "Lookups size"),
SNAPSHOT_SIZE(OUTPUT_SIZE, "ABI snapshot size")
COMPILER_PERFORMANCE(readableString = "Compiler time"),
COMPILER_INITIALIZATION(COMPILER_PERFORMANCE, "Compiler initialization time"),
CODE_ANALYSIS(COMPILER_PERFORMANCE, "Compiler code analyse"),
CODE_GENERATION(COMPILER_PERFORMANCE, "Compiler code generation"),
;
companion object {
@@ -12,7 +12,10 @@ object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun endMeasure(time: BuildTime, endNs: Long) {
}
override fun addMetric(time: BuildTime, value: Long) {
override fun addTimeMetric(time: BuildTime, durationMs: Long) {
}
override fun addMetric(metric: BuildPerformanceMetric, value: Long) {
}
override fun addAttribute(attribute: BuildAttribute) {
@@ -21,6 +24,7 @@ object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun getMetrics(): BuildMetrics =
BuildMetrics(
BuildTimes(),
BuildPerformanceMetrics(),
BuildAttributes()
)
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInClassDescriptorFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoots
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
@@ -41,6 +42,7 @@ class BuiltInsSerializer(dependOnOldBuiltIns: Boolean) : MetadataSerializer(Buil
) {
val rootDisposable = Disposer.newDisposable()
val messageCollector = createMessageCollector()
val performanceManager = object : CommonCompilerPerformanceManager(presentableName = "test") {}
try {
val configuration = CompilerConfiguration().apply {
put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
@@ -50,6 +52,7 @@ class BuiltInsSerializer(dependOnOldBuiltIns: Boolean) : MetadataSerializer(Buil
put(CLIConfigurationKeys.METADATA_DESTINATION_DIRECTORY, destDir)
put(CommonConfigurationKeys.MODULE_NAME, "module for built-ins serialization")
put(CLIConfigurationKeys.PERF_MANAGER, performanceManager)
}
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
@@ -329,7 +329,12 @@ abstract class CompileServiceImplBase(
val exitCode = compiler.exec(messageCollector, Services.EMPTY, k2PlatformArgs)
val perfString = compiler.defaultPerformanceManager.renderCompilerPerformance()
(compilationResults as CompilationResults).add(CompilationResultCategory.BUILD_REPORT_LINES.code, arrayListOf(perfString))
compilationResults?.also {
(it as CompilationResults).add(
CompilationResultCategory.BUILD_REPORT_LINES.code,
arrayListOf(perfString)
)
}
exitCode
}
@@ -21,12 +21,11 @@ import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.measure
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.toBooleanLenient
import org.jetbrains.kotlin.compilerRunner.MessageCollectorToOutputItemsCollectorAdapter
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem
@@ -497,5 +496,15 @@ abstract class IncrementalCompilerRunner<
override fun checkCanceled() {
}
}
protected fun reportPerformanceData(defaultPerformanceManager: CommonCompilerPerformanceManager) {
defaultPerformanceManager.getMeasurementResults().forEach {
when (it) {
is CompilerInitializationMeasurement -> reporter.addTimeMetric(BuildTime.COMPILER_INITIALIZATION, it.milliseconds)
is CodeAnalysisMeasurement -> reporter.addTimeMetric(BuildTime.CODE_ANALYSIS, it.milliseconds)
is CodeGenerationMeasurement -> reporter.addTimeMetric(BuildTime.CODE_GENERATION, it.milliseconds)
}
}
}
}
@@ -20,8 +20,9 @@ import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.*
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.isIrBackendEnabled
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -192,7 +193,8 @@ class IncrementalJsCompilerRunner(
compiler.exec(messageCollector, services, args)
} finally {
args.freeArgs = freeArgsBackup
reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
// reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
reportPerformanceData(compiler.defaultPerformanceManager)
}
}
@@ -433,7 +433,8 @@ class IncrementalJvmCompilerRunner(
args.allowNoSourceFiles = true
val exitCode = compiler.exec(messageCollector, services, args)
args.freeArgs = freeArgsBackup
reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
// reporter.report { compiler.defaultPerformanceManager.renderCompilerPerformance() }
reportPerformanceData(compiler.defaultPerformanceManager)
return exitCode
}
}
@@ -21,6 +21,7 @@ data class TaskData(
val path: String,
val typeFqName: String,
val timeMetrics: Map<String, Long>,
val performanceMetrics: Map<String, Long>,
val buildAttributes: Map<String, Int>,
val didWork: Boolean
) : Serializable {
@@ -9,10 +9,7 @@ import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.*
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.incremental.*
import java.io.File
@@ -131,7 +128,8 @@ private object NoOpBuildReporter : BuildReporter(NoOpICReporter, NoOpBuildMetric
object NoOpBuildMetricsReporter : BuildMetricsReporter {
override fun startMeasure(time: BuildTime, startNs: Long) {}
override fun endMeasure(time: BuildTime, endNs: Long) {}
override fun addMetric(metric: BuildTime, value: Long) {}
override fun addTimeMetric(metric: BuildTime, durationMs: Long) {}
override fun addMetric(metric: BuildPerformanceMetric, value: Long) {}
override fun addAttribute(attribute: BuildAttribute) {}
override fun getMetrics(): BuildMetrics = BuildMetrics()
override fun addMetrics(metrics: BuildMetrics?) {}
@@ -60,7 +60,9 @@ class KotlinBuildEsStatListener(val projectName: String, val reportStatistics: L
return;
}
val taskExecutionResult = TaskExecutionResults[taskPath]
val statData = taskExecutionResult?.buildMetrics?.buildTimes?.asMap() ?: emptyMap()
val timeData = taskExecutionResult?.buildMetrics?.buildTimes?.asMap()?.filterValues { value -> value != 0L } ?: emptyMap()
val perfData = taskExecutionResult?.buildMetrics?.buildPerformanceMetrics?.asMap()?.mapValues { it.value / 1000 }
?.filterValues { value -> value != 0L } ?: emptyMap()
val changes = when (val changedFiles = taskExecutionResult?.taskInfo?.changedFiles) {
is ChangedFiles.Known -> changedFiles.modified.map { it.absolutePath } + changedFiles.removed.map { it.absolutePath }
is ChangedFiles.Dependencies -> changedFiles.modified.map { it.absolutePath } + changedFiles.removed.map { it.absolutePath }
@@ -69,7 +71,7 @@ class KotlinBuildEsStatListener(val projectName: String, val reportStatistics: L
}
val compileStatData = CompileStatData(
duration = duration, taskResult = taskResult.name, label = label,
statData = statData, projectName = projectName, taskName = taskPath, changes = changes,
timeData = timeData, perfData = perfData, projectName = projectName, taskName = taskPath, changes = changes,
tags = taskExecutionResult?.taskInfo?.properties?.map { it.name } ?: emptyList(),
nonIncrementalAttributes = taskExecutionResult?.buildMetrics?.buildAttributes?.asMap() ?: emptyMap(),
hostName = hostName, kotlinVersion = "1.6", buildUuid = buildUuid, timeInMillis = System.currentTimeMillis()
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.plugin.stat
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.BuildTime
data class CompileStatData(
@@ -22,7 +23,8 @@ data class CompileStatData(
val hostName: String = "Unset",
val timeInMillis: Long,
val nonIncrementalAttributes: Map<BuildAttribute, Int>,
val statData: Map<BuildTime, Long>
val timeData: Map<BuildTime, Long>,
val perfData: Map<BuildPerformanceMetric, Long>
)
interface ReportStatistics {
@@ -27,7 +27,8 @@ class ReportStatisticsToBuildScan(private val buildScan: BuildScanExtension, pri
data.changes.joinTo(readableString, prefix = "Changes: [", postfix = "]; ") { it.substringAfterLast(File.separator) }
readableString.append("Performance: [")
data.statData.forEach { (key, value) -> readableString.append(key.readableString).append(": ").append(value).append("ms, ") }
data.timeData.forEach { (key, value) -> readableString.append(key.readableString).append(": ").append(value).append("ms, ") }
data.perfData.forEach { (key, value) -> readableString.append(key.readableString).append(": ").append(value).append("kb, ") }
readableString.append("]; ")
return readableString.toString()
}
@@ -38,12 +38,14 @@ internal class MetricsWriter(
val path = data.task.path
val type = data.task::class.java.canonicalName
val buildTimes = data.buildMetrics.buildTimes.asMap().mapKeys { (k, _) -> k.name }
val buildPerfMetrics = data.buildMetrics.buildPerformanceMetrics.asMap().mapKeys { (k, _) -> k.name }
val buildAttributes = data.buildMetrics.buildAttributes.asMap().mapKeys { (k, _) -> k.name }
buildMetricsData.taskData[path] =
TaskData(
path = path,
typeFqName = type,
timeMetrics = buildTimes,
performanceMetrics = buildPerfMetrics,
buildAttributes = buildAttributes,
didWork = data.task.didWork
)
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.gradle.report
import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.build.report.metrics.BuildAttributes
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.BuildTimes
import org.jetbrains.kotlin.build.report.metrics.*
import org.jetbrains.kotlin.gradle.report.data.BuildExecutionData
import org.jetbrains.kotlin.gradle.report.data.BuildExecutionDataProcessor
import org.jetbrains.kotlin.gradle.report.data.TaskExecutionData
@@ -62,6 +59,7 @@ internal class PlainTextBuildReportWriter(
if (!printMetrics) return
printBuildTimes(buildMetrics.buildTimes)
printBuildPerformanceMetrics(buildMetrics.buildPerformanceMetrics)
printBuildAttributes(buildMetrics.buildAttributes)
}
@@ -92,6 +90,18 @@ internal class PlainTextBuildReportWriter(
p.println()
}
private fun printBuildPerformanceMetrics(buildMetrics: BuildPerformanceMetrics) {
val allBuildMetrics = buildMetrics.asMap()
if (allBuildMetrics.isEmpty()) return
p.withIndent("Build performance metrics:") {
for (metric in BuildPerformanceMetric.values()) {
p.println("${metric.name}: ${allBuildMetrics[metric]}")
}
}
p.println()
}
private fun printBuildAttributes(buildAttributes: BuildAttributes) {
val allAttributes = buildAttributes.asMap()
if (allAttributes.isEmpty()) return
@@ -347,12 +347,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> : AbstractKotl
executeImpl(inputChanges)
metrics.measure(BuildTime.CALCULATE_OUTPUT_SIZE) {
metrics.addMetric(
BuildTime.SNAPSHOT_SIZE,
BuildPerformanceMetric.SNAPSHOT_SIZE,
taskBuildDirectory.file("build-history.bin").get().asFile.length() +
taskBuildDirectory.file("last-build.bin").get().asFile.length() +
taskBuildDirectory.file("abi-snapshot.bin").get().asFile.length()
)
metrics.addMetric(BuildTime.OUTPUT_SIZE,
metrics.addMetric(BuildPerformanceMetric.OUTPUT_SIZE,
taskBuildDirectory.dir("caches-jvm").get().asFileTree.files.filter { it.isFile }.map { it.length() }
.sum()
)