diff --git a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt index e68dffac1d6..efe39005eec 100644 --- a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt +++ b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildMetricsReporterImpl.kt @@ -9,7 +9,7 @@ import java.io.Serializable import kotlin.collections.HashMap open class BuildMetricsReporterImpl : BuildMetricsReporter, Serializable { - private val myBuildTimeStartNs = HashMap() + private val myBuildTimeStartNs = HashMap() private val myGcPerformance = HashMap() private val myBuildTimes = BuildTimes() private val myBuildMetrics = BuildPerformanceMetrics

() diff --git a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildTime.kt b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildTime.kt index e63dd171792..060a4a277f0 100644 --- a/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildTime.kt +++ b/compiler/build-tools/kotlin-build-statistics/src/org/jetbrains/kotlin/build/report/metrics/BuildTime.kt @@ -53,84 +53,69 @@ enum class GradleBuildTime(private val parent: GradleBuildTime? = null, private 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"), ; diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 82c1385f766..c4aa99c7215 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.build.GeneratedJvmClass import org.jetbrains.kotlin.build.report.ICReporter.ReportSeverity import org.jetbrains.kotlin.build.report.ICReporterBase import org.jetbrains.kotlin.build.report.debug -import org.jetbrains.kotlin.build.report.metrics.BuildTime import org.jetbrains.kotlin.build.report.metrics.JpsBuildTime import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments @@ -165,7 +164,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { override fun buildFinished(context: CompileContext) { ensureKotlinContextDisposed(context) - reportService.buildFinished(context) + reportService.buildFinish(context) } private fun ensureKotlinContextDisposed(context: CompileContext) { @@ -298,6 +297,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { dirtyFilesHolder: DirtyFilesHolder, outputConsumer: OutputConsumer ): ExitCode { + reportService.moduleBuildStarted(chunk) if (chunk.isDummy(context)) return NOTHING_DONE @@ -322,16 +322,18 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val fsOperations = FSOperationsHelper(context, chunk, kotlinDirtyFilesHolder, LOG) try { - val proposedExitCode = - doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations) + return reportService.reportMetrics(chunk, JpsBuildTime.JPS_ITERATION) { + val proposedExitCode = + doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations) - val actualExitCode = - if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode + val actualExitCode = + if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode - LOG.debug("Build result: $actualExitCode") + LOG.debug("Build result: $actualExitCode") - context.testingContext?.buildLogger?.buildFinished(actualExitCode) - return actualExitCode + context.testingContext?.buildLogger?.buildFinished(actualExitCode) + actualExitCode + } } catch (e: StopBuildException) { LOG.info("Caught exception: $e") throw e @@ -342,6 +344,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { LOG.info("Caught exception: $e") MessageCollectorUtil.reportException(messageCollector, e) return ABORT + } finally { + reportService.moduleBuildFinished(chunk, context) } } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/statistic/JpsStatisticsReportService.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/statistic/JpsStatisticsReportService.kt index 1dbbdf79432..aa80b11162c 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/statistic/JpsStatisticsReportService.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/statistic/JpsStatisticsReportService.kt @@ -6,24 +6,37 @@ package org.jetbrains.kotlin.jps.statistic import com.intellij.openapi.diagnostic.Logger +import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.incremental.CompileContext import org.jetbrains.kotlin.build.report.FileReportSettings import org.jetbrains.kotlin.build.report.HttpReportSettings import org.jetbrains.kotlin.build.report.metrics.* -import org.jetbrains.kotlin.build.report.statistics.* +import org.jetbrains.kotlin.build.report.statistics.BuildDataType +import org.jetbrains.kotlin.build.report.statistics.BuildStartParameters +import org.jetbrains.kotlin.build.report.statistics.HttpReportService +import org.jetbrains.kotlin.build.report.statistics.StatTag import org.jetbrains.kotlin.build.report.statistics.file.FileReportService import org.jetbrains.kotlin.compilerRunner.JpsKotlinLogger import java.io.File -import java.util.* import java.net.InetAddress +import java.util.* +import kotlin.collections.ArrayList interface JpsBuilderMetricReporter : BuildMetricsReporter { fun flush(context: CompileContext): JpsCompileStatisticsData + + fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext) } private const val jpsBuildTaskName = "JPS build" -class JpsBuilderMetricReporterImpl(private val reporter: BuildMetricsReporterImpl) : JpsBuilderMetricReporter, BuildMetricsReporter by reporter { +class JpsBuilderMetricReporterImpl( + chunk: ModuleChunk, + private val reporter: BuildMetricsReporterImpl, + private val label: String? = null, + private val kotlinVersion: String = "kotlin_version" +) : + JpsBuilderMetricReporter, BuildMetricsReporter by reporter { companion object { private val hostName: String? = try { @@ -32,27 +45,34 @@ class JpsBuilderMetricReporterImpl(private val reporter: BuildMetricsReporterImp //do nothing null } + private val uuid = UUID.randomUUID() } - private val uuid = UUID.randomUUID() - private val startTime = System.currentTimeMillis() - @Suppress("UNCHECKED_CAST") + private val startTime = System.currentTimeMillis() + private var finishTime: Long = 0L + private val tags = HashSet() + private val moduleString = chunk.name + + override fun buildFinish(moduleChunk: ModuleChunk, context: CompileContext) { + finishTime = System.currentTimeMillis() + } + override fun flush(context: CompileContext): JpsCompileStatisticsData { val buildMetrics = reporter.getMetrics() return JpsCompileStatisticsData( projectName = context.projectDescriptor.project.name, - label = "JPS build", //TODO will be updated in KT-58026 - taskName = jpsBuildTaskName, + label = label, + taskName = moduleString, taskResult = "Unknown",//TODO will be updated in KT-58026 startTimeMs = startTime, - durationMs = System.currentTimeMillis() - startTime, - tags = emptySet(), + durationMs = finishTime - startTime, + tags = tags, buildUuid = uuid.toString(), changes = emptyList(), //TODO will be updated in KT-58026 - kotlinVersion = "kotlin_version", //TODO will be updated in KT-58026 + kotlinVersion = kotlinVersion, hostName = hostName, - finishTime = System.currentTimeMillis(), + finishTime = finishTime, buildTimesMetrics = buildMetrics.buildTimes.asMapMs(), performanceMetrics = buildMetrics.buildPerformanceMetrics.asMap(), compilerArguments = emptyList(), //TODO will be updated in KT-58026 @@ -91,44 +111,62 @@ class JpsStatisticsReportService { } } - private val contextMetrics = HashMap() + private val buildMetrics = HashMap() + private val finishedModuleBuildMetrics = ArrayList() private val log = Logger.getInstance("#org.jetbrains.kotlin.jps.statistic.KotlinBuilderReportService") private val loggerAdapter = JpsKotlinLogger(log) private val httpService = httpReportSettings?.let { HttpReportService(it.url, it.user, it.password) } - fun buildStarted(context: CompileContext) { - if (contextMetrics[context] != null) { - log.error("Service already initialized for context") - } - contextMetrics[context] = JpsBuilderMetricReporterImpl(BuildMetricsReporterImpl()) - } - fun buildFinished(context: CompileContext) { - val metrics = contextMetrics.remove(context) - if (metrics == null) { - log.error("Service hasn't initialized for context") + fun moduleBuildStarted(chunk: ModuleChunk) { + val moduleName = chunk.name + if (buildMetrics[moduleName] != null) { + log.warn("Service already initialized for context") return } + log.info("JpsStatisticsReportService: Service started") + buildMetrics[moduleName] = JpsBuilderMetricReporterImpl(chunk, BuildMetricsReporterImpl()) + } - val compileStatisticsData = metrics.flush(context) + + fun moduleBuildFinished(chunk: ModuleChunk, context: CompileContext) { + val moduleName = chunk.name + val metrics = buildMetrics.remove(moduleName) + if (metrics == null) { + log.warn("Service hasn't initialized for context") + return + } + log.info("JpsStatisticsReportService: Service finished") + metrics.buildFinish(chunk, context) + finishedModuleBuildMetrics.add(metrics) + } + + fun buildFinish(context: CompileContext) { + val compileStatisticsData = finishedModuleBuildMetrics.map { it.flush(context) } httpService?.sendData(compileStatisticsData, loggerAdapter) fileReportSettings?.also { - FileReportService(it.buildReportDir, true, loggerAdapter) - .process( - listOf(compileStatisticsData), - BuildStartParameters(tasks = listOf(jpsBuildTaskName)) - ) + FileReportService.reportBuildStatInFile( + it.buildReportDir, context.projectDescriptor.project.name, true, compileStatisticsData, + BuildStartParameters(tasks = listOf(jpsBuildTaskName)), emptyList(), loggerAdapter + ) } } - fun reportMetrics(context: CompileContext, metric: JpsBuildTime, action: () -> T): T { - val metrics = contextMetrics.remove(context) + + fun reportMetrics(chunk: ModuleChunk, metric: JpsBuildTime, action: () -> T): T { + val moduleName = chunk.name + val metrics = buildMetrics[moduleName] if (metrics == null) { - log.error("Service hasn't initialized for context") + log.warn("Service hasn't initialized for context") return action.invoke() } + log.info("JpsStatisticsReportService: report metrics") return metrics.measure(metric, action) } + fun buildStarted(context: CompileContext) { + loggerAdapter.info("Build started for $context") + } + }