Split Gradle and JPS metrics

#KT-58026 In progress
This commit is contained in:
Nataliya.Valtman
2023-07-19 12:57:06 +02:00
committed by Space Team
parent 524df83265
commit ed2dd4b2ae
55 changed files with 918 additions and 546 deletions
@@ -7,13 +7,13 @@ package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
data class BuildMetrics(
val buildTimes: BuildTimes = BuildTimes(),
val buildPerformanceMetrics: BuildPerformanceMetrics = BuildPerformanceMetrics(),
data class BuildMetrics<B : BuildTime, P : BuildPerformanceMetric>(
val buildTimes: BuildTimes<B> = BuildTimes(),
val buildPerformanceMetrics: BuildPerformanceMetrics<P> = BuildPerformanceMetrics(),
val buildAttributes: BuildAttributes = BuildAttributes(),
val gcMetrics: GcMetrics = GcMetrics()
) : Serializable {
fun addAll(other: BuildMetrics) {
fun addAll(other: BuildMetrics<B, P>) {
buildTimes.addAll(other.buildTimes)
buildPerformanceMetrics.addAll(other.buildPerformanceMetrics)
buildAttributes.addAll(other.buildAttributes)
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.build.report.metrics
import java.lang.management.ManagementFactory
interface BuildMetricsReporter {
fun startMeasure(time: BuildTime)
fun endMeasure(time: BuildTime)
fun addTimeMetricNs(time: BuildTime, durationNs: Long)
fun addTimeMetricMs(time: BuildTime, durationMs: Long) = addTimeMetricNs(time, durationMs * 1_000_000)
interface BuildMetricsReporter<B : BuildTime, P : BuildPerformanceMetric> {
fun startMeasure(time: B)
fun endMeasure(time: B)
fun addTimeMetricNs(time: B, durationNs: Long)
fun addTimeMetricMs(time: B, durationMs: Long) = addTimeMetricNs(time, durationMs * 1_000_000)
fun addMetric(metric: BuildPerformanceMetric, value: Long)
fun addTimeMetric(metric: BuildPerformanceMetric)
fun addMetric(metric: P, value: Long)
fun addTimeMetric(metric: P)
//Change metric to enum if possible
fun addGcMetric(metric: String, value: GcMetric)
@@ -23,11 +23,11 @@ interface BuildMetricsReporter {
fun addAttribute(attribute: BuildAttribute)
fun getMetrics(): BuildMetrics
fun addMetrics(metrics: BuildMetrics)
fun getMetrics(): BuildMetrics<B, P>
fun addMetrics(metrics: BuildMetrics<B, P>)
}
inline fun <T> BuildMetricsReporter.measure(time: BuildTime, fn: () -> T): T {
inline fun <B : BuildTime, P : BuildPerformanceMetric, T> BuildMetricsReporter<B, P>.measure(time: B, fn: () -> T): T {
startMeasure(time)
try {
return fn()
@@ -37,13 +37,13 @@ inline fun <T> BuildMetricsReporter.measure(time: BuildTime, fn: () -> T): T {
}
fun BuildMetricsReporter.startMeasureGc() {
fun <B : BuildTime, P : BuildPerformanceMetric> BuildMetricsReporter<B, P>.startMeasureGc() {
ManagementFactory.getGarbageCollectorMXBeans().forEach {
startGcMetric(it.name, GcMetric(it.collectionTime, it.collectionCount))
}
}
fun BuildMetricsReporter.endMeasureGc() {
fun <B : BuildTime, P : BuildPerformanceMetric> BuildMetricsReporter<B, P>.endMeasureGc() {
ManagementFactory.getGarbageCollectorMXBeans().forEach {
endGcMetric(it.name, GcMetric(it.collectionTime, it.collectionCount))
}
@@ -6,27 +6,24 @@
package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
import java.util.*
import kotlin.collections.HashMap
class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
private val myBuildTimeStartNs: EnumMap<BuildTime, Long> =
EnumMap(
BuildTime::class.java
)
open class BuildMetricsReporterImpl<B : BuildTime, P : BuildPerformanceMetric> : BuildMetricsReporter<B, P>, Serializable {
private val myBuildTimeStartNs = HashMap<BuildTime, Long>()
private val myGcPerformance = HashMap<String, GcMetric>()
private val myBuildTimes = BuildTimes()
private val myBuildMetrics = BuildPerformanceMetrics()
private val myBuildTimes = BuildTimes<B>()
private val myBuildMetrics = BuildPerformanceMetrics<P>()
private val myBuildAttributes = BuildAttributes()
private val myGcMetrics = GcMetrics()
override fun startMeasure(time: BuildTime) {
override fun startMeasure(time: B) {
if (time in myBuildTimeStartNs) {
error("$time was restarted before it finished")
}
myBuildTimeStartNs[time] = System.nanoTime()
}
override fun endMeasure(time: BuildTime) {
override fun endMeasure(time: B) {
val startNs = myBuildTimeStartNs.remove(time) ?: error("$time finished before it started")
val durationNs = System.nanoTime() - startNs
myBuildTimes.addTimeNs(time, durationNs)
@@ -45,20 +42,20 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
myGcMetrics.add(name, diff)
}
override fun addTimeMetricNs(time: BuildTime, durationNs: Long) {
override fun addTimeMetricNs(time: B, durationNs: Long) {
myBuildTimes.addTimeNs(time, durationNs)
}
override fun addMetric(metric: BuildPerformanceMetric, value: Long) {
override fun addMetric(metric: P, value: Long) {
myBuildMetrics.add(metric, value)
}
override fun addTimeMetric(metric: BuildPerformanceMetric) {
when (metric.type) {
override fun addTimeMetric(metric: P) {
when (metric.getType()) {
ValueType.NANOSECONDS -> myBuildMetrics.add(metric, System.nanoTime())
ValueType.MILLISECONDS -> myBuildMetrics.add(metric, System.currentTimeMillis())
ValueType.TIME -> myBuildMetrics.add(metric, System.currentTimeMillis())
else -> error("Unable to add time metric for '${metric.type}' type")
else -> error("Unable to add time metric for '${metric.getType()}' type")
}
}
@@ -71,7 +68,7 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
myBuildAttributes.add(attribute)
}
override fun getMetrics(): BuildMetrics =
override fun getMetrics(): BuildMetrics<B, P> =
BuildMetrics(
buildTimes = myBuildTimes,
buildPerformanceMetrics = myBuildMetrics,
@@ -79,7 +76,7 @@ class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable {
gcMetrics = myGcMetrics
)
override fun addMetrics(metrics: BuildMetrics) {
override fun addMetrics(metrics: BuildMetrics<B, P>) {
myBuildAttributes.addAll(metrics.buildAttributes)
myBuildTimes.addAll(metrics.buildTimes)
myBuildMetrics.addAll(metrics.buildPerformanceMetrics)
@@ -7,11 +7,65 @@ package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
interface BuildPerformanceMetric : BuildTime, Serializable {
override fun getParent(): BuildPerformanceMetric?
override fun getAllMetrics(): List<BuildPerformanceMetric>
override fun children(): List<BuildPerformanceMetric>?
fun getType(): ValueType
}
enum class JpsBuildPerformanceMetric(
private val parent: JpsBuildPerformanceMetric? = null,
private val readableString: String,
private val type: ValueType,
) : BuildPerformanceMetric {
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),
ANALYSIS_LPS(parent = COMPILE_ITERATION, "Analysis lines per second", type = ValueType.NUMBER),
CODE_GENERATION_LPS(parent = COMPILE_ITERATION, "Code generation lines per second", type = ValueType.NUMBER),
;
override fun getReadableString(): String = readableString
override fun getType(): ValueType = type
override fun getParent(): BuildPerformanceMetric? = parent
override fun children(): List<BuildPerformanceMetric>? {
return children[this]
}
override fun getName(): String = this.name
override fun getAllMetrics(): List<BuildPerformanceMetric> {
return entries
}
companion object {
const val serialVersionUID = 1L
val children by lazy {
entries.filter { it.parent != null }.groupBy { it.parent }
}
}
}
@Suppress("Reformat")
enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, val readableString: String, val type: ValueType) : Serializable {
enum class GradleBuildPerformanceMetric(
private val parent: GradleBuildPerformanceMetric? = null,
private val readableString: String,
private val type: ValueType,
) :
BuildPerformanceMetric {
CACHE_DIRECTORY_SIZE(readableString = "Total size of the cache directory", type = ValueType.BYTES),
LOOKUP_SIZE(CACHE_DIRECTORY_SIZE, "Lookups size", type = ValueType.BYTES),
SNAPSHOT_SIZE(CACHE_DIRECTORY_SIZE, "ABI snapshot size", type = ValueType.BYTES),
LOOKUP_SIZE(CACHE_DIRECTORY_SIZE, "Lookups size", type = ValueType.BYTES),
SNAPSHOT_SIZE(CACHE_DIRECTORY_SIZE, "ABI snapshot size", type = ValueType.BYTES),
BUNDLE_SIZE(readableString = "Total size of the final bundle", type = ValueType.BYTES),
@@ -22,24 +76,64 @@ enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, va
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),
ANALYSIS_LPS(parent = COMPILE_ITERATION, "Analysis lines per second", type = ValueType.NUMBER),
CODE_GENERATION_LPS(parent = COMPILE_ITERATION, "Code generation lines per second", 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),
ANALYSIS_LPS(parent = COMPILE_ITERATION, "Analysis lines per second", type = ValueType.NUMBER),
CODE_GENERATION_LPS(parent = COMPILE_ITERATION, "Code generation lines per second", type = ValueType.NUMBER),
// Metrics for the `kotlin.incremental.useClasspathSnapshot` feature
CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT(parent = null, "Number of times 'ClasspathEntrySnapshotTransform' ran", type = ValueType.NUMBER),
JAR_CLASSPATH_ENTRY_SIZE(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT, "Size of jar classpath entry", type = ValueType.BYTES),
JAR_CLASSPATH_ENTRY_SNAPSHOT_SIZE(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT, "Size of jar classpath entry's snapshot", type = ValueType.BYTES),
DIRECTORY_CLASSPATH_ENTRY_SNAPSHOT_SIZE(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT, "Size of directory classpath entry's snapshot", type = ValueType.BYTES),
CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT(
parent = null,
"Number of times 'ClasspathEntrySnapshotTransform' ran",
type = ValueType.NUMBER
),
JAR_CLASSPATH_ENTRY_SIZE(
parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT,
"Size of jar classpath entry",
type = ValueType.BYTES
),
JAR_CLASSPATH_ENTRY_SNAPSHOT_SIZE(
parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT,
"Size of jar classpath entry's snapshot",
type = ValueType.BYTES
),
DIRECTORY_CLASSPATH_ENTRY_SNAPSHOT_SIZE(
parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM_EXECUTION_COUNT,
"Size of directory classpath entry's snapshot",
type = ValueType.BYTES
),
COMPUTE_CLASSPATH_CHANGES_EXECUTION_COUNT(parent = null, "Number of times classpath changes are computed", type = ValueType.NUMBER),
SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT(parent = null, "Number of times classpath snapshot is shrunk and saved after compilation", type = ValueType.NUMBER),
CLASSPATH_ENTRY_COUNT(parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT, "Number of classpath entries", type = ValueType.NUMBER),
CLASSPATH_SNAPSHOT_SIZE(parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT, "Size of classpath snapshot", type = ValueType.BYTES),
SHRUNK_CLASSPATH_SNAPSHOT_SIZE(parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT, "Size of shrunk classpath snapshot", type = ValueType.BYTES),
SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT(
parent = null,
"Number of times classpath snapshot is shrunk and saved after compilation",
type = ValueType.NUMBER
),
CLASSPATH_ENTRY_COUNT(
parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT,
"Number of classpath entries",
type = ValueType.NUMBER
),
CLASSPATH_SNAPSHOT_SIZE(
parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT,
"Size of classpath snapshot",
type = ValueType.BYTES
),
SHRUNK_CLASSPATH_SNAPSHOT_SIZE(
parent = SHRINK_AND_SAVE_CLASSPATH_SNAPSHOT_EXECUTION_COUNT,
"Size of shrunk classpath snapshot",
type = ValueType.BYTES
),
LOAD_CLASSPATH_SNAPSHOT_EXECUTION_COUNT(parent = null, "Number of times classpath snapshot is loaded", type = ValueType.NUMBER),
LOAD_CLASSPATH_ENTRY_SNAPSHOT_CACHE_HITS(parent = LOAD_CLASSPATH_SNAPSHOT_EXECUTION_COUNT, "Number of cache hits when loading classpath entry snapshots", type = ValueType.NUMBER),
LOAD_CLASSPATH_ENTRY_SNAPSHOT_CACHE_MISSES(parent = LOAD_CLASSPATH_SNAPSHOT_EXECUTION_COUNT, "Number of cache misses when loading classpath entry snapshots", type = ValueType.NUMBER),
LOAD_CLASSPATH_ENTRY_SNAPSHOT_CACHE_HITS(
parent = LOAD_CLASSPATH_SNAPSHOT_EXECUTION_COUNT,
"Number of cache hits when loading classpath entry snapshots",
type = ValueType.NUMBER
),
LOAD_CLASSPATH_ENTRY_SNAPSHOT_CACHE_MISSES(
parent = LOAD_CLASSPATH_SNAPSHOT_EXECUTION_COUNT,
"Number of cache misses when loading classpath entry snapshots",
type = ValueType.NUMBER
),
//time metrics
START_TASK_ACTION_EXECUTION(readableString = "Start time of task action", type = ValueType.TIME),
@@ -50,11 +144,27 @@ enum class BuildPerformanceMetric(val parent: BuildPerformanceMetric? = null, va
START_WORKER_EXECUTION(readableString = "Start time of worker execution", type = ValueType.NANOSECONDS),
START_KOTLIN_DAEMON_EXECUTION(readableString = "Start time of kotlin daemon task execution", type = ValueType.NANOSECONDS),
;
override fun getReadableString(): String = readableString
override fun getParent(): BuildPerformanceMetric? = parent
override fun getType(): ValueType = type
override fun getName(): String = this.name
override fun children(): List<BuildPerformanceMetric>? {
return children[this]
}
override fun getAllMetrics(): List<BuildPerformanceMetric> {
return entries
}
companion object {
const val serialVersionUID = 0L
const val serialVersionUID = 1L
val children by lazy {
values().filter { it.parent != null }.groupBy { it.parent }
entries.filter { it.parent != null }.groupBy { it.parent }
}
}
}
@@ -7,24 +7,25 @@ package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
import java.util.*
import kotlin.collections.HashMap
class BuildPerformanceMetrics : Serializable {
class BuildPerformanceMetrics<T: BuildPerformanceMetric> : Serializable {
companion object {
const val serialVersionUID = 0L
}
private val myBuildMetrics = EnumMap<BuildPerformanceMetric, Long>(BuildPerformanceMetric::class.java)
private val myBuildMetrics = HashMap<T, Long>()
fun addAll(other: BuildPerformanceMetrics) {
fun addAll(other: BuildPerformanceMetrics<T>) {
for ((bt, timeNs) in other.myBuildMetrics) {
add(bt, timeNs)
}
}
fun add(metric: BuildPerformanceMetric, value: Long = 1) {
fun add(metric: T, value: Long = 1) {
myBuildMetrics[metric] = myBuildMetrics.getOrDefault(metric, 0) + value
}
fun asMap(): Map<BuildPerformanceMetric, Long> = myBuildMetrics
fun asMap(): Map<T, Long> = myBuildMetrics
}
@@ -7,82 +7,151 @@ package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
interface BuildTime : Serializable {
fun getReadableString(): String
fun getParent(): BuildTime?
fun getAllMetrics(): List<BuildTime>
fun children(): List<BuildTime>?
fun getName(): String
}
enum class JpsBuildTime(private val parent: JpsBuildTime? = null, private val readableString: String) : BuildTime {
JPS_ITERATION(readableString = "Jps iteration")
;
override fun getReadableString(): String = readableString
override fun getParent(): BuildTime? = parent
override fun getAllMetrics(): List<BuildTime> {
return entries
}
override fun children(): List<BuildTime>? {
return children[this]
}
override fun getName(): String = this.name
companion object {
const val serialVersionUID = 1L
val children by lazy {
entries.filter { it.parent != null }.groupBy { it.parent }
}
}
}
@Suppress("Reformat")
enum class BuildTime(val parent: BuildTime? = null, val readableString: String) : Serializable {
enum class GradleBuildTime(private val parent: GradleBuildTime? = null, private val readableString: String) : BuildTime {
GRADLE_TASK(readableString = "Total Gradle task time"),
GRADLE_TASK_PREPARATION(readableString = "Spent time before task action"),
GRADLE_TASK_ACTION(readableString = "Task action"),
OUT_OF_WORKER_TASK_ACTION(GRADLE_TASK_ACTION, "Task action before worker execution"),
BACKUP_OUTPUT(OUT_OF_WORKER_TASK_ACTION, "Backup output"),
RUN_WORKER_DELAY(readableString = "Start gradle worker"),
RUN_COMPILATION_IN_WORKER(GRADLE_TASK_ACTION, "Run compilation in Gradle worker"),
CLEAR_JAR_CACHE(RUN_COMPILATION_IN_WORKER, "Clear jar cache"),
CLEAR_OUTPUT(RUN_COMPILATION_IN_WORKER, "Clear output"),
PRECISE_BACKUP_OUTPUT(RUN_COMPILATION_IN_WORKER, "Precise backup output"),
RESTORE_OUTPUT_FROM_BACKUP(RUN_COMPILATION_IN_WORKER, "Restore output"),
CLEAN_BACKUP_STASH(RUN_COMPILATION_IN_WORKER, "Cleaning up the backup stash"),
CONNECT_TO_DAEMON(RUN_COMPILATION_IN_WORKER, "Connect to Kotlin daemon"),
CALCULATE_OUTPUT_SIZE(RUN_COMPILATION_IN_WORKER, "Calculate output size"),
RUN_COMPILATION(RUN_COMPILATION_IN_WORKER, "Run compilation"),
NON_INCREMENTAL_COMPILATION_IN_PROCESS(RUN_COMPILATION, "Non incremental inprocess compilation"),
NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS(RUN_COMPILATION, "Non incremental out of process compilation"),
NON_INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILATION, "Non incremental compilation in daemon"),
INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILATION, "Incremental compilation in daemon"),
STORE_BUILD_INFO(INCREMENTAL_COMPILATION_DAEMON, "Store build info"),
JAR_SNAPSHOT(INCREMENTAL_COMPILATION_DAEMON, "ABI JAR Snapshot support"),
SET_UP_ABI_SNAPSHOTS(JAR_SNAPSHOT, "Set up ABI snapshot"),
IC_ANALYZE_JAR_FILES(JAR_SNAPSHOT, "Analyze jar files"),
IC_CALCULATE_INITIAL_DIRTY_SET(INCREMENTAL_COMPILATION_DAEMON, "Calculate initial dirty sources set"), //TODO
COMPUTE_CLASSPATH_CHANGES(IC_CALCULATE_INITIAL_DIRTY_SET, "Compute classpath changes"),
LOAD_CURRENT_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Load current classpath snapshot"),
REMOVE_DUPLICATE_CLASSES(LOAD_CURRENT_CLASSPATH_SNAPSHOT, "Remove duplicate classes"),
SHRINK_CURRENT_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Shrink current classpath snapshot"),
GET_LOOKUP_SYMBOLS(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Get lookup symbols"),
FIND_REFERENCED_CLASSES(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Find referenced classes"),
FIND_TRANSITIVELY_REFERENCED_CLASSES(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Find transitively referenced classes"),
LOAD_SHRUNK_PREVIOUS_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Load shrunk previous classpath snapshot"),
COMPUTE_CHANGED_AND_IMPACTED_SET(COMPUTE_CLASSPATH_CHANGES, "Compute changed and impacted set"),
COMPUTE_CLASS_CHANGES(COMPUTE_CHANGED_AND_IMPACTED_SET, "Compute class changes"),
COMPUTE_KOTLIN_CLASS_CHANGES(COMPUTE_CLASS_CHANGES, "Compute Kotlin class changes"),
COMPUTE_JAVA_CLASS_CHANGES(COMPUTE_CLASS_CHANGES, "Compute Java class changes"),
COMPUTE_IMPACTED_SET(COMPUTE_CHANGED_AND_IMPACTED_SET, "Compute impacted set"),
IC_ANALYZE_CHANGES_IN_DEPENDENCIES(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze dependency changes"),
IC_FIND_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES, "Find history files"),
IC_ANALYZE_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES, "Analyze history files"),
IC_ANALYZE_CHANGES_IN_JAVA_SOURCES(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze Java file changes"),
IC_ANALYZE_CHANGES_IN_ANDROID_LAYOUTS(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze Android layouts"),
IC_DETECT_REMOVED_CLASSES(IC_CALCULATE_INITIAL_DIRTY_SET, "Detect removed classes"),
CLEAR_OUTPUT_ON_REBUILD(INCREMENTAL_COMPILATION_DAEMON, "Clear outputs on rebuild"),
IC_UPDATE_CACHES(INCREMENTAL_COMPILATION_DAEMON, "Update caches"),
COMPILATION_ROUND(INCREMENTAL_COMPILATION_DAEMON, "Sources compilation round"),
COMPILER_PERFORMANCE(COMPILATION_ROUND, readableString = "Compiler time"),
COMPILER_INITIALIZATION(COMPILER_PERFORMANCE, "Compiler initialization time"),
CODE_ANALYSIS(COMPILER_PERFORMANCE, "Compiler code analysis"),
CODE_GENERATION(COMPILER_PERFORMANCE, "Compiler code generation"),
IC_WRITE_HISTORY_FILE(INCREMENTAL_COMPILATION_DAEMON, "Write history file"),
SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION(INCREMENTAL_COMPILATION_DAEMON, "Shrink and save current classpath snapshot after compilation"),
INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT(SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION, "Shrink current classpath snapshot incrementally"),
INCREMENTAL_LOAD_CURRENT_CLASSPATH_SNAPSHOT(INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Load current classpath snapshot"),
INCREMENTAL_LOAD_SHRUNK_CURRENT_CLASSPATH_SNAPSHOT_AGAINST_PREVIOUS_LOOKUPS(INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Load shrunk current classpath snapshot against previous lookups"),
NON_INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT(SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION, "Shrink current classpath snapshot non-incrementally"),
NON_INCREMENTAL_LOAD_CURRENT_CLASSPATH_SNAPSHOT(NON_INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Load current classpath snapshot"),
SAVE_SHRUNK_CURRENT_CLASSPATH_SNAPSHOT(SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION, "Save shrunk current classpath snapshot"),
OUT_OF_WORKER_TASK_ACTION(GRADLE_TASK_ACTION, "Task action before worker execution"),
BACKUP_OUTPUT(OUT_OF_WORKER_TASK_ACTION, "Backup output"),
RUN_WORKER_DELAY(readableString = "Start gradle worker"),
RUN_COMPILATION_IN_WORKER(GRADLE_TASK_ACTION, "Run compilation in Gradle worker"),
CLEAR_JAR_CACHE(RUN_COMPILATION_IN_WORKER, "Clear jar cache"),
CLEAR_OUTPUT(RUN_COMPILATION_IN_WORKER, "Clear output"),
PRECISE_BACKUP_OUTPUT(RUN_COMPILATION_IN_WORKER, "Precise backup output"),
RESTORE_OUTPUT_FROM_BACKUP(RUN_COMPILATION_IN_WORKER, "Restore output"),
CLEAN_BACKUP_STASH(RUN_COMPILATION_IN_WORKER, "Cleaning up the backup stash"),
CONNECT_TO_DAEMON(RUN_COMPILATION_IN_WORKER, "Connect to Kotlin daemon"),
CALCULATE_OUTPUT_SIZE(RUN_COMPILATION_IN_WORKER, "Calculate output size"),
RUN_COMPILATION(RUN_COMPILATION_IN_WORKER, "Run compilation"),
NON_INCREMENTAL_COMPILATION_IN_PROCESS(RUN_COMPILATION, "Non incremental inprocess compilation"),
NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS(RUN_COMPILATION, "Non incremental out of process compilation"),
NON_INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILATION, "Non incremental compilation in daemon"),
INCREMENTAL_COMPILATION_DAEMON(RUN_COMPILATION, "Incremental compilation in daemon"),
STORE_BUILD_INFO(INCREMENTAL_COMPILATION_DAEMON, "Store build info"),
JAR_SNAPSHOT(INCREMENTAL_COMPILATION_DAEMON, "ABI JAR Snapshot support"),
SET_UP_ABI_SNAPSHOTS(JAR_SNAPSHOT, "Set up ABI snapshot"),
IC_ANALYZE_JAR_FILES(JAR_SNAPSHOT, "Analyze jar files"),
IC_CALCULATE_INITIAL_DIRTY_SET(INCREMENTAL_COMPILATION_DAEMON, "Calculate initial dirty sources set"), //TODO
COMPUTE_CLASSPATH_CHANGES(IC_CALCULATE_INITIAL_DIRTY_SET, "Compute classpath changes"),
LOAD_CURRENT_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Load current classpath snapshot"),
REMOVE_DUPLICATE_CLASSES(LOAD_CURRENT_CLASSPATH_SNAPSHOT, "Remove duplicate classes"),
SHRINK_CURRENT_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Shrink current classpath snapshot"),
GET_LOOKUP_SYMBOLS(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Get lookup symbols"),
FIND_REFERENCED_CLASSES(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Find referenced classes"),
FIND_TRANSITIVELY_REFERENCED_CLASSES(SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Find transitively referenced classes"),
LOAD_SHRUNK_PREVIOUS_CLASSPATH_SNAPSHOT(COMPUTE_CLASSPATH_CHANGES, "Load shrunk previous classpath snapshot"),
COMPUTE_CHANGED_AND_IMPACTED_SET(COMPUTE_CLASSPATH_CHANGES, "Compute changed and impacted set"),
COMPUTE_CLASS_CHANGES(COMPUTE_CHANGED_AND_IMPACTED_SET, "Compute class changes"),
COMPUTE_KOTLIN_CLASS_CHANGES(COMPUTE_CLASS_CHANGES, "Compute Kotlin class changes"),
COMPUTE_JAVA_CLASS_CHANGES(COMPUTE_CLASS_CHANGES, "Compute Java class changes"),
COMPUTE_IMPACTED_SET(COMPUTE_CHANGED_AND_IMPACTED_SET, "Compute impacted set"),
IC_ANALYZE_CHANGES_IN_DEPENDENCIES(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze dependency changes"),
IC_FIND_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES, "Find history files"),
IC_ANALYZE_HISTORY_FILES(IC_ANALYZE_CHANGES_IN_DEPENDENCIES, "Analyze history files"),
IC_ANALYZE_CHANGES_IN_JAVA_SOURCES(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze Java file changes"),
IC_ANALYZE_CHANGES_IN_ANDROID_LAYOUTS(IC_CALCULATE_INITIAL_DIRTY_SET, "Analyze Android layouts"),
IC_DETECT_REMOVED_CLASSES(IC_CALCULATE_INITIAL_DIRTY_SET, "Detect removed classes"),
CLEAR_OUTPUT_ON_REBUILD(INCREMENTAL_COMPILATION_DAEMON, "Clear outputs on rebuild"),
IC_UPDATE_CACHES(INCREMENTAL_COMPILATION_DAEMON, "Update caches"),
COMPILATION_ROUND(INCREMENTAL_COMPILATION_DAEMON, "Sources compilation round"),
COMPILER_PERFORMANCE(COMPILATION_ROUND, readableString = "Compiler time"),
COMPILER_INITIALIZATION(COMPILER_PERFORMANCE, "Compiler initialization time"),
CODE_ANALYSIS(COMPILER_PERFORMANCE, "Compiler code analysis"),
CODE_GENERATION(COMPILER_PERFORMANCE, "Compiler code generation"),
IC_WRITE_HISTORY_FILE(INCREMENTAL_COMPILATION_DAEMON, "Write history file"),
SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION(
INCREMENTAL_COMPILATION_DAEMON,
"Shrink and save current classpath snapshot after compilation"
),
INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT(
SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION,
"Shrink current classpath snapshot incrementally"
),
INCREMENTAL_LOAD_CURRENT_CLASSPATH_SNAPSHOT(INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Load current classpath snapshot"),
INCREMENTAL_LOAD_SHRUNK_CURRENT_CLASSPATH_SNAPSHOT_AGAINST_PREVIOUS_LOOKUPS(
INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT,
"Load shrunk current classpath snapshot against previous lookups"
),
NON_INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT(
SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION,
"Shrink current classpath snapshot non-incrementally"
),
NON_INCREMENTAL_LOAD_CURRENT_CLASSPATH_SNAPSHOT(NON_INCREMENTAL_SHRINK_CURRENT_CLASSPATH_SNAPSHOT, "Load current classpath snapshot"),
SAVE_SHRUNK_CURRENT_CLASSPATH_SNAPSHOT(
SHRINK_AND_SAVE_CURRENT_CLASSPATH_SNAPSHOT_AFTER_COMPILATION,
"Save shrunk current classpath snapshot"
),
TASK_FINISH_LISTENER_NOTIFICATION(readableString = "Task finish event notification"),
CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM(readableString = "Classpath entry snapshot transform"),
LOAD_CLASSES_PATHS_ONLY(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Load classes (paths only)"),
SNAPSHOT_CLASSES(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Snapshot classes"),
LOAD_CONTENTS_OF_CLASSES(parent = SNAPSHOT_CLASSES, "Load contents of classes"),
SNAPSHOT_KOTLIN_CLASSES(parent = SNAPSHOT_CLASSES, "Snapshot Kotlin classes"),
SNAPSHOT_JAVA_CLASSES(parent = SNAPSHOT_CLASSES, "Snapshot Java classes"),
SAVE_CLASSPATH_ENTRY_SNAPSHOT(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Save classpath entry snapshot"),
LOAD_CLASSES_PATHS_ONLY(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Load classes (paths only)"),
SNAPSHOT_CLASSES(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Snapshot classes"),
LOAD_CONTENTS_OF_CLASSES(parent = SNAPSHOT_CLASSES, "Load contents of classes"),
SNAPSHOT_KOTLIN_CLASSES(parent = SNAPSHOT_CLASSES, "Snapshot Kotlin classes"),
SNAPSHOT_JAVA_CLASSES(parent = SNAPSHOT_CLASSES, "Snapshot Java classes"),
SAVE_CLASSPATH_ENTRY_SNAPSHOT(parent = CLASSPATH_ENTRY_SNAPSHOT_TRANSFORM, "Save classpath entry snapshot"),
;
override fun getReadableString(): String = readableString
override fun getParent(): BuildTime? = parent
override fun children(): List<BuildTime>? {
return children[this]
}
override fun getAllMetrics(): List<BuildTime> {
return entries
}
override fun getName(): String = this.name
companion object {
const val serialVersionUID = 0L
const val serialVersionUID = 1L
val children by lazy {
values().filter { it.parent != null }.groupBy { it.parent }
entries.filter { it.parent != null }.groupBy { it.parent }
}
}
}
@@ -7,23 +7,24 @@ package org.jetbrains.kotlin.build.report.metrics
import java.io.Serializable
import java.util.*
import kotlin.collections.HashMap
class BuildTimes : Serializable {
private val buildTimesNs = EnumMap<BuildTime, Long>(BuildTime::class.java)
class BuildTimes<T : BuildTime> : Serializable {
private val buildTimesNs = HashMap<T, Long>()
fun addAll(other: BuildTimes) {
fun addAll(other: BuildTimes<T>) {
for ((buildTime, timeNs) in other.buildTimesNs) {
addTimeNs(buildTime, timeNs)
}
}
fun addTimeNs(buildTime: BuildTime, timeNs: Long) {
fun addTimeNs(buildTime: T, timeNs: Long) {
buildTimesNs[buildTime] = buildTimesNs.getOrDefault(buildTime, 0) + timeNs
}
fun addTimeMs(buildTime: BuildTime, timeMs: Long) = addTimeNs(buildTime, timeMs * 1_000_000)
fun addTimeMs(buildTime: T, timeMs: Long) = addTimeNs(buildTime, timeMs * 1_000_000)
fun asMapMs(): Map<BuildTime, Long> = buildTimesNs.mapValues { it.value / 1_000_000 }
fun asMapMs(): Map<T, Long> = buildTimesNs.mapValues { it.value / 1_000_000 }
companion object {
const val serialVersionUID = 0L
@@ -5,20 +5,20 @@
package org.jetbrains.kotlin.build.report.metrics
object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun startMeasure(time: BuildTime) {
object DoNothingBuildMetricsReporter : BuildMetricsReporter<GradleBuildTime, GradleBuildPerformanceMetric> {
override fun startMeasure(time: GradleBuildTime) {
}
override fun endMeasure(time: BuildTime) {
override fun endMeasure(time: GradleBuildTime) {
}
override fun addTimeMetricNs(time: BuildTime, durationNs: Long) {
override fun addTimeMetricNs(time: GradleBuildTime, durationNs: Long) {
}
override fun addMetric(metric: BuildPerformanceMetric, value: Long) {
override fun addMetric(metric: GradleBuildPerformanceMetric, value: Long) {
}
override fun addTimeMetric(metric: BuildPerformanceMetric) {
override fun addTimeMetric(metric: GradleBuildPerformanceMetric) {
}
override fun addAttribute(attribute: BuildAttribute) {
@@ -33,12 +33,12 @@ object DoNothingBuildMetricsReporter : BuildMetricsReporter {
override fun endGcMetric(name: String, value: GcMetric) {
}
override fun getMetrics(): BuildMetrics =
override fun getMetrics(): BuildMetrics<GradleBuildTime, GradleBuildPerformanceMetric> =
BuildMetrics(
BuildTimes(),
BuildPerformanceMetrics(),
BuildAttributes()
)
override fun addMetrics(metrics: BuildMetrics) {}
override fun addMetrics(metrics: BuildMetrics<GradleBuildTime, GradleBuildPerformanceMetric>) {}
}
@@ -5,44 +5,43 @@
package org.jetbrains.kotlin.build.report.statistics
import org.jetbrains.kotlin.build.report.metrics.BuildAttribute
import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.*
import java.text.SimpleDateFormat
import java.util.*
//Sensitive data. This object is used directly for statistic via http
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC")}
data class CompileStatisticsData(
val version: Int = 3,
val projectName: String?,
val label: String?,
val taskName: String,
val taskResult: String?,
val startTimeMs: Long,
val durationMs: Long,
val tags: Set<StatTag>,
val changes: List<String>,
val buildUuid: String = "Unset",
val kotlinVersion: String,
val kotlinLanguageVersion: String?,
val hostName: String? = "Unset",
val finishTime: Long,
val timestamp: String = formatter.format(finishTime),
val compilerArguments: List<String>,
val nonIncrementalAttributes: Set<BuildAttribute>,
//TODO think about it,time in milliseconds
val buildTimesMetrics: Map<BuildTime, Long>,
val performanceMetrics: Map<BuildPerformanceMetric, Long>,
val gcTimeMetrics: Map<String, Long>?,
val gcCountMetrics: Map<String, Long>?,
val type: String = BuildDataType.TASK_DATA.name,
val fromKotlinPlugin: Boolean?,
val compiledSources: List<String> = emptyList(),
val skipMessage: String?,
val icLogLines: List<String>,
)
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC") }
interface CompileStatisticsData<B : BuildTime, P : BuildPerformanceMetric> {
fun getVersion(): Int = 4
fun getProjectName(): String?
fun getLabel(): String?
fun getTaskName(): String
fun getTaskResult(): String?
fun getStartTimeMs(): Long
fun getDurationMs(): Long
fun getTags(): Set<StatTag>
fun getChanges(): List<String>
fun getBuildUuid(): String = "Unset"
fun getKotlinVersion(): String
fun getKotlinLanguageVersion(): String?
fun getHostName(): String? = "Unset"
fun getFinishTime(): Long
fun getTimestamp(): String = formatter.format(getFinishTime())
fun getCompilerArguments(): List<String>
fun getNonIncrementalAttributes(): Set<BuildAttribute>
//TODO think about it,time in milliseconds
fun getBuildTimesMetrics(): Map<B, Long>
fun getPerformanceMetrics(): Map<P, Long>
fun getGcTimeMetrics(): Map<String, Long>?
fun getGcCountMetrics(): Map<String, Long>?
fun getType(): String = BuildDataType.TASK_DATA.name
fun getFromKotlinPlugin(): Boolean?
fun getCompiledSources(): List<String> = emptyList()
fun getSkipMessage(): String?
fun getIcLogLines(): List<String>
}
enum class StatTag(val readableString: String) {
ABI_SNAPSHOT("ABI Snapshot"),
@@ -86,7 +85,7 @@ data class BuildFinishStatisticsData(
val timestamp: String = formatter.format(finishTime),
val hostName: String? = "Unset",
val tags: Set<StatTag>,
val gitBranch: String = "Unset"
val gitBranch: String = "Unset",
)
@@ -15,26 +15,26 @@ import java.io.Serializable
import java.text.SimpleDateFormat
import java.util.*
class FileReportService(
class FileReportService<B : BuildTime, P : BuildPerformanceMetric>(
private val outputFile: File,
private val printMetrics: Boolean,
private val logger: KotlinLogger
private val logger: KotlinLogger,
) : Serializable {
companion object {
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC")}
fun reportBuildStatInFile(
private val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").also { it.timeZone = TimeZone.getTimeZone("UTC") }
fun <B : BuildTime, P : BuildPerformanceMetric> reportBuildStatInFile(
buildReportDir: File,
projectName: String,
includeMetricsInReport: Boolean,
buildData: List<CompileStatisticsData>,
buildData: List<CompileStatisticsData<B, P>>,
startParameters: BuildStartParameters,
failureMessages: List<String>,
logger: KotlinLogger
logger: KotlinLogger,
) {
val ts = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Calendar.getInstance().time)
val reportFile = buildReportDir.resolve("$projectName-build-$ts.txt")
FileReportService(
FileReportService<B, P>(
outputFile = reportFile,
printMetrics = includeMetricsInReport,
logger = logger
@@ -45,9 +45,9 @@ class FileReportService(
private lateinit var p: Printer
fun process(
statisticsData: List<CompileStatisticsData>,
statisticsData: List<CompileStatisticsData<B, P>>,
startParameters: BuildStartParameters,
failureMessages: List<String> = emptyList()
failureMessages: List<String> = emptyList(),
) {
val buildReportPath = outputFile.toPath().toUri().toString()
try {
@@ -69,9 +69,9 @@ class FileReportService(
}
private fun printBuildReport(
statisticsData: List<CompileStatisticsData>,
statisticsData: List<CompileStatisticsData<B, P>>,
startParameters: BuildStartParameters,
failureMessages: List<String>
failureMessages: List<String>,
) {
// NOTE: BuildExecutionData / BuildOperationRecord contains data for both tasks and transforms.
// Where possible, we still use the term "tasks" because saying "tasks/transforms" is a bit verbose and "build operations" may sound
@@ -80,13 +80,13 @@ class FileReportService(
printBuildInfo(startParameters, failureMessages)
if (printMetrics && statisticsData.isNotEmpty()) {
printMetrics(
statisticsData.map { it.buildTimesMetrics }.reduce { agg, value ->
statisticsData.map { it.getBuildTimesMetrics() }.reduce { agg, value ->
(agg.keys + value.keys).associateWith { (agg[it] ?: 0) + (value[it] ?: 0) }
},
statisticsData.map { it.performanceMetrics }.reduce { agg, value ->
statisticsData.map { it.getPerformanceMetrics() }.reduce { agg, value ->
(agg.keys + value.keys).associateWith { (agg[it] ?: 0) + (value[it] ?: 0) }
},
statisticsData.map { it.nonIncrementalAttributes.asSequence() }.reduce { agg, value -> agg + value }.toList(),
statisticsData.map { it.getNonIncrementalAttributes().asSequence() }.reduce { agg, value -> agg + value }.toList(),
aggregatedMetric = true
)
p.println()
@@ -114,12 +114,12 @@ class FileReportService(
}
private fun printMetrics(
buildTimesMetrics: Map<BuildTime, Long>,
performanceMetrics: Map<BuildPerformanceMetric, Long>,
buildTimesMetrics: Map<out BuildTime, Long>,
performanceMetrics: Map<out BuildPerformanceMetric, Long>,
nonIncrementalAttributes: Collection<BuildAttribute>,
gcTimeMetrics: Map<String, Long>? = emptyMap(),
gcCountMetrics: Map<String, Long>? = emptyMap(),
aggregatedMetric: Boolean = false
aggregatedMetric: Boolean = false,
) {
printBuildTimes(buildTimesMetrics)
if (aggregatedMetric) p.println()
@@ -129,7 +129,7 @@ class FileReportService(
printBuildAttributes(nonIncrementalAttributes)
//TODO: KT-57310 Implement build GC metric in
//TODO: KT-57310 Implement build GC metric in
if (!aggregatedMetric) {
printGcMetrics(gcTimeMetrics, gcCountMetrics)
}
@@ -137,7 +137,7 @@ class FileReportService(
private fun printGcMetrics(
gcTimeMetrics: Map<String, Long>?,
gcCountMetrics: Map<String, Long>?
gcCountMetrics: Map<String, Long>?,
) {
val keys = HashSet<String>()
gcCountMetrics?.keys?.also { keys.addAll(it) }
@@ -155,7 +155,7 @@ class FileReportService(
}
}
private fun printBuildTimes(buildTimes: Map<BuildTime, Long>) {
private fun printBuildTimes(buildTimes: Map<out BuildTime, Long>) {
if (buildTimes.isEmpty()) return
p.println("Time metrics:")
@@ -166,29 +166,29 @@ class FileReportService(
val timeMs = buildTimes[buildTime]
if (timeMs != null) {
p.println("${buildTime.readableString}: ${formatTime(timeMs)}")
p.println("${buildTime.getReadableString()}: ${formatTime(timeMs)}")
p.withIndent {
BuildTime.children[buildTime]?.forEach { printBuildTime(it) }
buildTime.children()?.forEach { printBuildTime(it) }
}
} else {
//Skip formatting if parent metric does not set
BuildTime.children[buildTime]?.forEach { printBuildTime(it) }
buildTime.children()?.forEach { printBuildTime(it) }
}
}
for (buildTime in BuildTime.values()) {
if (buildTime.parent != null) continue
for (buildTime in buildTimes.keys.first().getAllMetrics()) {
if (buildTime.getParent() != null) continue
printBuildTime(buildTime)
}
}
}
private fun printBuildPerformanceMetrics(buildMetrics: Map<BuildPerformanceMetric, Long>) {
private fun printBuildPerformanceMetrics(buildMetrics: Map<out BuildPerformanceMetric, Long>) {
if (buildMetrics.isEmpty()) return
p.withIndent("Size metrics:") {
for (metric in BuildPerformanceMetric.values()) {
for (metric in buildMetrics.keys.first().getAllMetrics()) {
buildMetrics[metric]?.let { printSizeMetric(metric, it) }
}
}
@@ -197,10 +197,10 @@ class FileReportService(
private fun printSizeMetric(sizeMetric: BuildPerformanceMetric, value: Long) {
fun BuildPerformanceMetric.numberOfAncestors(): Int {
var count = 0
var parent: BuildPerformanceMetric? = parent
var parent: BuildPerformanceMetric? = getParent()
while (parent != null) {
count++
parent = parent.parent
parent = parent.getParent()
}
return count
}
@@ -208,12 +208,12 @@ class FileReportService(
val indentLevel = sizeMetric.numberOfAncestors()
repeat(indentLevel) { p.pushIndent() }
when (sizeMetric.type) {
ValueType.BYTES -> p.println("${sizeMetric.readableString}: ${formatSize(value)}")
ValueType.NUMBER -> p.println("${sizeMetric.readableString}: $value")
ValueType.NANOSECONDS -> p.println("${sizeMetric.readableString}: $value")
ValueType.MILLISECONDS -> p.println("${sizeMetric.readableString}: ${formatTime(value)}")
ValueType.TIME -> p.println("${sizeMetric.readableString}: ${formatter.format(value)}")
when (sizeMetric.getType()) {
ValueType.BYTES -> p.println("${sizeMetric.getReadableString()}: ${formatSize(value)}")
ValueType.NUMBER -> p.println("${sizeMetric.getReadableString()}: $value")
ValueType.NANOSECONDS -> p.println("${sizeMetric.getReadableString()}: $value")
ValueType.MILLISECONDS -> p.println("${sizeMetric.getReadableString()}: ${formatTime(value)}")
ValueType.TIME -> p.println("${sizeMetric.getReadableString()}: ${formatter.format(value)}")
}
repeat(indentLevel) { p.popIndent() }
}
@@ -230,16 +230,16 @@ class FileReportService(
}
}
private fun printTaskOverview(statisticsData: Collection<CompileStatisticsData>) {
private fun printTaskOverview(statisticsData: Collection<CompileStatisticsData<B, P>>) {
var allTasksTimeMs = 0L
var kotlinTotalTimeMs = 0L
val kotlinTasks = ArrayList<CompileStatisticsData>()
val kotlinTasks = ArrayList<CompileStatisticsData<B, P>>()
for (task in statisticsData) {
val taskTimeMs = task.durationMs
val taskTimeMs = task.getDurationMs()
allTasksTimeMs += taskTimeMs
if (task.fromKotlinPlugin == true) {
if (task.getFromKotlinPlugin() == true) {
kotlinTotalTimeMs += taskTimeMs
kotlinTasks.add(task)
}
@@ -254,45 +254,47 @@ class FileReportService(
p.println("Total time for Kotlin tasks: ${formatTime(kotlinTotalTimeMs)} ($ktTaskPercent % of all tasks time)")
val table = TextTable("Time", "% of Kotlin time", "Task")
for (task in kotlinTasks.sortedWith(compareBy({ -it.durationMs }, { it.startTimeMs }))) {
val timeMs = task.durationMs
for (task in kotlinTasks.sortedWith(compareBy({ -it.getDurationMs() }, { it.getStartTimeMs() }))) {
val timeMs = task.getDurationMs()
val percent = (timeMs.toDouble() / kotlinTotalTimeMs * 100).asString(1)
table.addRow(formatTime(timeMs), "$percent %", task.taskName)
table.addRow(formatTime(timeMs), "$percent %", task.getTaskName())
}
table.printTo(p)
p.println()
}
private fun printTasksLog(statisticsData: List<CompileStatisticsData>) {
for (task in statisticsData.sortedWith(compareBy({ -it.durationMs }, { it.startTimeMs }))) {
private fun printTasksLog(statisticsData: List<CompileStatisticsData<B, P>>) {
for (task in statisticsData.sortedWith(compareBy({ -it.getDurationMs() }, { it.getStartTimeMs() }))) {
printTaskLog(task)
p.println()
}
}
private fun printTaskLog(statisticsData: CompileStatisticsData) {
val skipMessage = statisticsData.skipMessage
private fun <B : BuildTime, P : BuildPerformanceMetric> printTaskLog(statisticsData: CompileStatisticsData<B, P>) {
val skipMessage = statisticsData.getSkipMessage()
if (skipMessage != null) {
p.println("Task '${statisticsData.taskName}' was skipped: $skipMessage")
p.println("Task '${statisticsData.getTaskName()}' was skipped: $skipMessage")
} else {
p.println("Task '${statisticsData.taskName}' finished in ${formatTime(statisticsData.durationMs)}")
p.println("Task '${statisticsData.getTaskName()}' finished in ${formatTime(statisticsData.getDurationMs())}")
}
statisticsData.kotlinLanguageVersion?.also {
statisticsData.getKotlinLanguageVersion()?.also {
p.withIndent("Task info:") {
p.println("Kotlin language version: $it")
}
}
if (statisticsData.icLogLines.isNotEmpty()) {
p.withIndent("Compilation log for task '${statisticsData.taskName}':") {
statisticsData.icLogLines.forEach { p.println(it) }
if (statisticsData.getIcLogLines().isNotEmpty()) {
p.withIndent("Compilation log for task '${statisticsData.getTaskName()}':") {
statisticsData.getIcLogLines().forEach { p.println(it) }
}
}
if (printMetrics) {
printMetrics(statisticsData.buildTimesMetrics, statisticsData.performanceMetrics, statisticsData.nonIncrementalAttributes,
statisticsData.gcTimeMetrics, statisticsData.gcCountMetrics)
printMetrics(
statisticsData.getBuildTimesMetrics(), statisticsData.getPerformanceMetrics(), statisticsData.getNonIncrementalAttributes(),
statisticsData.getGcTimeMetrics(), statisticsData.getGcCountMetrics()
)
}
}
}