diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt index 78ede95e3f7..d57bb9dc034 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/FusStatisticsIT.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.gradle.report.BuildReportType import org.jetbrains.kotlin.gradle.testbase.* import org.jetbrains.kotlin.gradle.util.replaceText import org.junit.jupiter.api.DisplayName @@ -175,12 +176,14 @@ class FusStatisticsIT : KGPDaemonsBaseTest() { project( "incrementalMultiproject", gradleVersion, ) { - //after KT-58768 and KT-62616 are done it will be possible to check build metrics also - build("compileKotlin", "-Pkotlin.session.logger.root.path=$projectPath") { + //Collect metrics from BuildMetricsService also + build("compileKotlin", "-Pkotlin.session.logger.root.path=$projectPath", + buildOptions = defaultBuildOptions.copy(buildReport = listOf(BuildReportType.FILE))) { assertFileContains( fusStatisticsPath, "CONFIGURATION_IMPLEMENTATION_COUNT=2", "NUMBER_OF_SUBPROJECTS=2", + "COMPILATIONS_COUNT=2" ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt index 42178d3cd6a..271eea6be86 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerRunnerWithWorkers.kt @@ -17,6 +17,7 @@ import org.gradle.workers.WorkerExecutor import org.jetbrains.kotlin.build.report.metrics.* import org.jetbrains.kotlin.gradle.logging.GradleKotlinLogger import org.jetbrains.kotlin.gradle.tasks.* +import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer import java.io.File import javax.inject.Inject @@ -29,7 +30,8 @@ internal class GradleCompilerRunnerWithWorkers( compilerExecutionSettings: CompilerExecutionSettings, buildMetrics: BuildMetricsReporter, private val workerExecutor: WorkerExecutor, -) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics) { + fusMetricsConsumer: StatisticsValuesConsumer?, +) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics, fusMetricsConsumer) { override fun runCompilerAsync( workArgs: GradleKotlinCompilerWorkArguments, taskOutputsBackup: TaskOutputsBackup?, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index e1bf154c9b9..b85293c190e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -36,13 +36,13 @@ import org.jetbrains.kotlin.gradle.plugin.internal.BuildIdService import org.jetbrains.kotlin.gradle.plugin.internal.JavaSourceSetsAccessor import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.incremental.IncrementalModuleEntry import org.jetbrains.kotlin.incremental.IncrementalModuleInfo import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics +import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer import org.jetbrains.kotlin.statistics.metrics.StringMetrics import java.io.File import java.lang.ref.WeakReference @@ -68,6 +68,7 @@ internal fun createGradleCompilerRunner( cachedClassLoadersService: Property, buildFinishedListenerService: Provider, buildIdService: Provider, + fusMetricsConsumer: StatisticsValuesConsumer?, ): GradleCompilerRunner { return if (runViaBuildToolsApi) { GradleBuildToolsApiCompilerRunner( @@ -79,6 +80,7 @@ internal fun createGradleCompilerRunner( cachedClassLoadersService, buildFinishedListenerService, buildIdService, + fusMetricsConsumer ) } else { GradleCompilerRunnerWithWorkers( @@ -87,6 +89,7 @@ internal fun createGradleCompilerRunner( compilerExecutionSettings, buildMetricsReporter, workerExecutor, + fusMetricsConsumer ) } } @@ -101,6 +104,7 @@ internal open class GradleCompilerRunner( protected val jdkToolsJar: File?, protected val compilerExecutionSettings: CompilerExecutionSettings, protected val buildMetrics: BuildMetricsReporter, + protected val fusMetricsConsumer: StatisticsValuesConsumer?, ) { internal val pathProvider = taskProvider.path.get() @@ -120,7 +124,7 @@ internal open class GradleCompilerRunner( args: K2JVMCompilerArguments, environment: GradleCompilerEnvironment, jdkHome: File, - taskOutputsBackup: TaskOutputsBackup? + taskOutputsBackup: TaskOutputsBackup?, ): WorkQueue? { if (args.jdkHome == null && !args.noJdk) args.jdkHome = jdkHome.absolutePath loggerProvider.kotlinInfo("Kotlin compilation 'jdkHome' argument: ${args.jdkHome}") @@ -134,7 +138,7 @@ internal open class GradleCompilerRunner( fun runJsCompilerAsync( args: K2JSCompilerArguments, environment: GradleCompilerEnvironment, - taskOutputsBackup: TaskOutputsBackup? + taskOutputsBackup: TaskOutputsBackup?, ): WorkQueue? { return runCompilerAsync(KotlinCompilerClass.JS, args, environment, taskOutputsBackup) } @@ -145,7 +149,7 @@ internal open class GradleCompilerRunner( */ fun runMetadataCompilerAsync( args: K2MetadataCompilerArguments, - environment: GradleCompilerEnvironment + environment: GradleCompilerEnvironment, ): WorkQueue? { return runCompilerAsync(KotlinCompilerClass.METADATA, args, environment) } @@ -154,7 +158,7 @@ internal open class GradleCompilerRunner( compilerClassName: String, compilerArgs: CommonCompilerArguments, environment: GradleCompilerEnvironment, - taskOutputsBackup: TaskOutputsBackup? = null + taskOutputsBackup: TaskOutputsBackup? = null, ): WorkQueue? { if (compilerArgs.version) { loggerProvider.lifecycle( @@ -168,42 +172,39 @@ internal open class GradleCompilerRunner( // compilerArgs arguments may have some attributes which are overrided by freeCompilerArguments. // Here we perform the work which is repeated in compiler in order to obtain correct values. This extra work could be avoided when // compiler would report metrics by itself via JMX - KotlinBuildStatsService.applyIfInitialised { + fusMetricsConsumer?.let { metricsConsumer -> when (compilerArgs) { is K2JVMCompilerArguments -> { - KotlinBuildStatsService.getInstance()?.apply { - val args = K2JVMCompilerArguments() - parseCommandLineArguments(argsArray.toList(), args) - report(StringMetrics.JVM_DEFAULTS, args.jvmDefault) - report(StringMetrics.USE_FIR, args.useK2.toString()) + val args = K2JVMCompilerArguments() + parseCommandLineArguments(argsArray.toList(), args) + metricsConsumer.report(StringMetrics.JVM_DEFAULTS, args.jvmDefault) + metricsConsumer.report(StringMetrics.USE_FIR, args.useK2.toString()) - val pluginPatterns = listOf(Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_ALL_OPEN, "kotlin-allopen-.*jar"), - Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_NO_ARG, "kotlin-noarg-.*jar"), - Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_SAM_WITH_RECEIVER, "kotlin-sam-with-receiver-.*jar"), - Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_LOMBOK, "kotlin-lombok-.*jar"), - Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_PARSELIZE, "kotlin-parcelize-compiler-.*jar"), - Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_ATOMICFU, "atomicfu-.*jar") - ) - val pluginJars = args.pluginClasspaths?.map { it.replace("\\", "/").split("/").last() } - if (pluginJars != null) { - for (pluginPattern in pluginPatterns) { - if (pluginJars.any { it.matches(pluginPattern.second.toRegex())}) { - report(pluginPattern.first, true) - } + val pluginPatterns = listOf( + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_ALL_OPEN, "kotlin-allopen-.*jar"), + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_NO_ARG, "kotlin-noarg-.*jar"), + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_SAM_WITH_RECEIVER, "kotlin-sam-with-receiver-.*jar"), + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_LOMBOK, "kotlin-lombok-.*jar"), + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_PARSELIZE, "kotlin-parcelize-compiler-.*jar"), + Pair(BooleanMetrics.ENABLED_COMPILER_PLUGIN_ATOMICFU, "atomicfu-.*jar") + ) + val pluginJars = args.pluginClasspaths?.map { it.replace("\\", "/").split("/").last() } + if (pluginJars != null) { + for (pluginPattern in pluginPatterns) { + if (pluginJars.any { it.matches(pluginPattern.second.toRegex()) }) { + metricsConsumer.report(pluginPattern.first, true) } } } } is K2JSCompilerArguments -> { - KotlinBuildStatsService.getInstance()?.apply { - val args = K2JSCompilerArguments() - parseCommandLineArguments(argsArray.toList(), args) - if (!args.isPreIrBackendDisabled() || args.irProduceJs) { - report(BooleanMetrics.JS_SOURCE_MAP, args.sourceMap) - } - if (args.irProduceJs) { - report(StringMetrics.JS_PROPERTY_LAZY_INITIALIZATION, args.irPropertyLazyInitialization.toString()) - } + val args = K2JSCompilerArguments() + parseCommandLineArguments(argsArray.toList(), args) + if (!args.isPreIrBackendDisabled() || args.irProduceJs) { + metricsConsumer.report(BooleanMetrics.JS_SOURCE_MAP, args.sourceMap) + } + if (args.irProduceJs) { + metricsConsumer.report(StringMetrics.JS_PROPERTY_LAZY_INITIALIZATION, args.irPropertyLazyInitialization.toString()) } } } @@ -245,7 +246,7 @@ internal open class GradleCompilerRunner( protected open fun runCompilerAsync( workArgs: GradleKotlinCompilerWorkArguments, - taskOutputsBackup: TaskOutputsBackup? + taskOutputsBackup: TaskOutputsBackup?, ): WorkQueue? { try { buildMetrics.addTimeMetric(GradleBuildPerformanceMetric.CALL_WORKER) @@ -272,7 +273,7 @@ internal open class GradleCompilerRunner( compilerFullClasspath: List, messageCollector: MessageCollector, daemonJvmArgs: List?, - isDebugEnabled: Boolean + isDebugEnabled: Boolean, ): CompileServiceSession? { val compilerId = CompilerId.makeCompilerId(compilerFullClasspath) val daemonJvmOptions = configureDaemonJVMOptions( @@ -347,7 +348,10 @@ internal open class GradleCompilerRunner( nameToModules.getOrPut(module.name) { HashSet() }.add(module) if (task is Kotlin2JsCompile) { - (jarForJavaSourceSet(project, task.sourceSetName.get()) ?: jarForSingleTargetJs(project, task.sourceSetName.get()))?.let { + (jarForJavaSourceSet(project, task.sourceSetName.get()) ?: jarForSingleTargetJs( + project, + task.sourceSetName.get() + ))?.let { jarToModule[it] = module } } @@ -404,7 +408,7 @@ internal open class GradleCompilerRunner( private fun jarForJavaSourceSet( project: Project, - sourceSetName: String + sourceSetName: String, ): File? { val sourceSets = project.variantImplementationFactory() .getInstance(project) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/GradleBuildToolsApiCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/GradleBuildToolsApiCompilerRunner.kt index cb7c0b9cac2..184746bcd35 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/GradleBuildToolsApiCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/GradleBuildToolsApiCompilerRunner.kt @@ -9,7 +9,6 @@ import org.gradle.api.provider.Provider import org.gradle.workers.WorkQueue import org.gradle.workers.WorkerExecutor import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter -import org.jetbrains.kotlin.build.report.metrics.BuildPerformanceMetric import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric import org.jetbrains.kotlin.build.report.metrics.GradleBuildTime import org.jetbrains.kotlin.compilerRunner.CompilerExecutionSettings @@ -20,6 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.BuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.internal.BuildIdService import org.jetbrains.kotlin.gradle.tasks.GradleCompileTaskProvider import org.jetbrains.kotlin.gradle.tasks.TaskOutputsBackup +import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer import java.io.File internal class GradleBuildToolsApiCompilerRunner( @@ -31,7 +31,8 @@ internal class GradleBuildToolsApiCompilerRunner( private val cachedClassLoadersService: Provider, private val buildFinishedListenerService: Provider, private val buildIdService: Provider, -) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics) { + fusMetricsConsumer: StatisticsValuesConsumer?, +) : GradleCompilerRunner(taskProvider, jdkToolsJar, compilerExecutionSettings, buildMetrics, fusMetricsConsumer) { override fun runCompilerAsync( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index eaa8a37de87..5b32ebea2a0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -33,8 +33,7 @@ import org.jetbrains.kotlin.gradle.plugin.internal.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory -import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFlowService -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFusService import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin @@ -48,7 +47,6 @@ import org.jetbrains.kotlin.gradle.targets.native.internal.CommonizerTargetAttri import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry import org.jetbrains.kotlin.gradle.utils.* -import org.jetbrains.kotlin.statistics.metrics.StringMetrics import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion import kotlin.reflect.KClass @@ -63,10 +61,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin { override fun apply(project: Project) { project.registerDefaultVariantImplementations() - KotlinBuildStatsService.getOrCreateInstance(project)?.apply { - report(StringMetrics.KOTLIN_COMPILER_VERSION, pluginVersion) - } - BuildFlowService.registerIfAbsent(project) + val buildFusService = BuildFusService.registerIfAbsent(project, pluginVersion) project.gradle.projectsEvaluated { whenBuildEvaluated(project) @@ -87,7 +82,7 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin { kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, pluginVersion) } - BuildMetricsService.registerIfAbsent(project) + BuildMetricsService.registerIfAbsent(project, buildFusService) } private fun addKotlinCompilerConfiguration(project: Project) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt index cc937c0841e..ec84bdccba8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/StatisticsBuildFlowManager.kt @@ -10,7 +10,7 @@ import org.gradle.api.flow.* import org.gradle.api.provider.Property import org.gradle.api.services.ServiceReference import org.gradle.api.tasks.Input -import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFlowService +import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFusService import org.jetbrains.kotlin.gradle.report.BuildMetricsService import org.jetbrains.kotlin.gradle.report.BuildScanExtensionHolder import javax.inject.Inject @@ -32,10 +32,7 @@ internal abstract class StatisticsBuildFlowManager @Inject constructor( } } - fun subscribeForBuildScan(project: Project) { - val buildScanExtension = project.rootProject.extensions.findByName("buildScan") - val buildScanHolder = buildScanExtension?.let { BuildScanExtensionHolder(it) } - + fun subscribeForBuildScan(buildScanHolder: BuildScanExtensionHolder) { flowScope.always( BuildScanFlowAction::class.java ) { spec -> @@ -47,10 +44,10 @@ internal abstract class StatisticsBuildFlowManager @Inject constructor( internal class BuildScanFlowAction : FlowAction { interface Parameters : FlowParameters { @get:ServiceReference - val buildMetricService: Property + val buildMetricService: Property @get: Input - val buildScanExtensionHolder: Property + val buildScanExtensionHolder: Property } override fun execute(parameters: Parameters) { @@ -61,7 +58,7 @@ internal class BuildScanFlowAction : FlowAction internal class BuildFinishFlowAction : FlowAction { interface Parameters : FlowParameters { @get:ServiceReference - val buildFlowServiceProperty: Property + val buildFusServiceProperty: Property @get:Input val action: Property @@ -72,7 +69,7 @@ internal class BuildFinishFlowAction : FlowAction, AutoCloseable, OperationCompletionListener { + +internal interface UsesBuildFusService : Task { + @get:Internal + val buildFusService: Property +} +abstract class BuildFusService : BuildService, AutoCloseable, OperationCompletionListener { private var buildFailed: Boolean = false private val log = Logging.getLogger(this.javaClass) @@ -43,8 +51,20 @@ internal abstract class BuildFlowService : BuildService } + internal val fusMetricsConsumer: NonSynchronizedMetricsContainer? by lazy { + // parameters should be already injected on this property access + if (parameters.fusStatisticsAvailable.get()) + NonSynchronizedMetricsContainer() + else + null + } + + internal fun reportFusMetrics(reportAction: (StatisticsValuesConsumer) -> Unit) { + fusMetricsConsumer?.let { reportAction(it) } + } + companion object { - private val serviceName = "${BuildFlowService::class.simpleName}_${BuildFlowService::class.java.classLoader.hashCode()}" + private val serviceName = "${BuildFusService::class.simpleName}_${BuildFusService::class.java.classLoader.hashCode()}" private fun fusStatisticsAvailable(project: Project): Boolean { return when { @@ -55,29 +75,42 @@ internal abstract class BuildFlowService : BuildService !project.isConfigurationCacheRequested } } - fun registerIfAbsent( + + fun registerIfAbsent(project: Project, pluginVersion: String) = registerIfAbsentImpl(project, pluginVersion).also { serviceProvider -> + SingleActionPerProject.run(project, UsesBuildFusService::class.java.name) { + project.tasks.withType().configureEach { task -> + task.buildFusService.value(serviceProvider).disallowChanges() + task.usesService(serviceProvider) + } + } + } + + private fun registerIfAbsentImpl( project: Project, - ): Provider { + pluginVersion: String, + ): Provider { val isProjectIsolationEnabled = project.isProjectIsolationEnabled project.gradle.sharedServices.registrations.findByName(serviceName)?.let { @Suppress("UNCHECKED_CAST") - return (it.service as Provider).also { + return (it.service as Provider).also { it.get().parameters.configurationMetrics.add(project.provider { - KotlinBuildStatsService.getInstance()?.collectProjectConfigurationMetrics(project, isProjectIsolationEnabled) + KotlinBuildStatHandler.collectProjectConfigurationTimeMetrics(project, isProjectIsolationEnabled) }) } } + //init buildStatsService + KotlinBuildStatsService.getOrCreateInstance(project) + val fusStatisticsAvailable = fusStatisticsAvailable(project) val buildReportOutputs = reportingSettings(project).buildReportOutputs - val buildScanReportEnabled = buildReportOutputs.contains(BuildReportType.BUILD_SCAN) //Workaround for known issues for Gradle 8+: https://github.com/gradle/gradle/issues/24887: // when this OperationCompletionListener is called services can be already closed for Gradle 8, // so there is a change that no VariantImplementationFactory will be found - return project.gradle.sharedServices.registerIfAbsent(serviceName, BuildFlowService::class.java) { spec -> + return project.gradle.sharedServices.registerIfAbsent(serviceName, BuildFusService::class.java) { spec -> if (fusStatisticsAvailable) { KotlinBuildStatsService.applyIfInitialised { it.recordProjectsEvaluated(project.gradle) @@ -85,11 +118,11 @@ internal abstract class BuildFlowService : BuildService @@ -100,9 +133,6 @@ internal abstract class BuildFlowService : BuildService StatisticsBuildFlowManager.getInstance(project).subscribeForBuildResult() } } - if (buildScanReportEnabled && GradleVersion.current().baseVersion >= GradleVersion.version("8.1")) { - StatisticsBuildFlowManager.getInstance(project).subscribeForBuildScan(project) - } } } } @@ -123,26 +153,31 @@ internal abstract class BuildFlowService : BuildService + KotlinBuildStatHandler.reportGlobalMetrics(metricsConsumer) + parameters.configurationMetrics.orElse(emptyList()).get().forEach { it.addToConsumer(metricsConsumer) } + KotlinBuildStatsService.applyIfInitialised { + it.recordBuildFinish(action, buildFailed, metricsConsumer) + } } + } } -internal class MetricContainer : Serializable { +class MetricContainer : Serializable { private val numericalMetrics = HashMap() private val booleanMetrics = HashMap() private val stringMetrics = HashMap() - fun report(sessionLogger: IStatisticsValuesConsumer) { + fun addToConsumer(metricsConsumer: StatisticsValuesConsumer) { for ((key, value) in numericalMetrics) { - sessionLogger.report(key, value) + metricsConsumer.report(key, value) } for ((key, value) in booleanMetrics) { - sessionLogger.report(key, value) + metricsConsumer.report(key, value) } for ((key, value) in stringMetrics) { - sessionLogger.report(key, value) + metricsConsumer.report(key, value) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt index c7d0dd2ad51..90ffc3719c4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatHandler.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics import org.jetbrains.kotlin.statistics.metrics.StringMetrics import org.jetbrains.kotlin.statistics.MetricValueValidationFailed +import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer import java.lang.management.ManagementFactory import javax.management.MBeanServer import javax.management.ObjectName @@ -44,6 +45,216 @@ class KotlinBuildStatHandler { getLogger().debug(e.message, e) } + /** + * Collect general configuration metrics + */ + internal fun collectGeneralConfigurationTimeMetrics( + project: Project, + isProjectIsolationEnabled: Boolean, + buildReportOutputs: List, + pluginVersion: String, + ): MetricContainer { + val configurationTimeMetrics = MetricContainer() + + configurationTimeMetrics.put(StringMetrics.KOTLIN_COMPILER_VERSION, pluginVersion) + + val statisticOverhead = measureTimeMillis { + buildReportOutputs.forEach { + when (it) { + BuildReportType.BUILD_SCAN -> configurationTimeMetrics.put(BooleanMetrics.BUILD_SCAN_BUILD_REPORT, true) + BuildReportType.FILE -> configurationTimeMetrics.put(BooleanMetrics.FILE_BUILD_REPORT, true) + BuildReportType.HTTP -> configurationTimeMetrics.put(BooleanMetrics.HTTP_BUILD_REPORT, true) + BuildReportType.SINGLE_FILE -> configurationTimeMetrics.put(BooleanMetrics.SINGLE_FILE_BUILD_REPORT, true) + BuildReportType.TRY_K2_CONSOLE -> {}//ignore + } + } + val gradle = project.gradle + configurationTimeMetrics.put(StringMetrics.PROJECT_PATH, gradle.rootProject.projectDir.absolutePath) + configurationTimeMetrics.put(StringMetrics.GRADLE_VERSION, gradle.gradleVersion) + if (!isProjectIsolationEnabled) { + gradle.taskGraph.whenReady { taskExecutionGraph -> + val executedTaskNames = taskExecutionGraph.allTasks.map { it.name }.distinct() + configurationTimeMetrics.put(BooleanMetrics.MAVEN_PUBLISH_EXECUTED, executedTaskNames.contains("install")) + } + } + } + configurationTimeMetrics.put(NumericalMetrics.STATISTICS_VISIT_ALL_PROJECTS_OVERHEAD, statisticOverhead) + + return configurationTimeMetrics + + } + + /** + * Collect project's configuration metrics + */ + internal fun collectProjectConfigurationTimeMetrics( + project: Project, + isProjectIsolationEnabled: Boolean, + ): MetricContainer { + val configurationTimeMetrics = MetricContainer() + + if (isProjectIsolationEnabled) { //support project isolation - KT-58768 + return configurationTimeMetrics + } + + val statisticOverhead = measureTimeMillis { + collectAppliedPluginsStatistics(project, configurationTimeMetrics) + + val configurations = project.configurations.asMap.values + for (configuration in configurations) { + try { + val configurationName = configuration.name + val dependencies = configuration.dependencies + + when (configurationName) { + "KoverEngineConfig" -> { + configurationTimeMetrics.put(BooleanMetrics.ENABLED_KOVER, true) + } + "kapt" -> { + configurationTimeMetrics.put(BooleanMetrics.ENABLED_KAPT, true) + for (dependency in dependencies) { + when (dependency.group) { + "com.google.dagger" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DAGGER, true) + "com.android.databinding" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DATABINDING, true) + } + } + } + API -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_API_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + IMPLEMENTATION -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_IMPLEMENTATION_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + COMPILE -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_COMPILE_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + COMPILE_ONLY -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_COMPILE_ONLY_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + RUNTIME -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_RUNTIME_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + RUNTIME_ONLY -> { + configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_RUNTIME_ONLY_COUNT, 1) + reportLibrariesVersions(configurationTimeMetrics, dependencies) + } + } + } catch (e: Throwable) { + // log? + } + } + + configurationTimeMetrics.put(NumericalMetrics.NUMBER_OF_SUBPROJECTS, 1) + + + configurationTimeMetrics.put( + BooleanMetrics.KOTLIN_KTS_USED, + project.buildscript.sourceFile?.name?.endsWith(".kts") ?: false + ) + + addTaskMetrics(project, configurationTimeMetrics) + + if (project.name == "buildSrc") { + configurationTimeMetrics.put(NumericalMetrics.BUILD_SRC_COUNT, 1) + configurationTimeMetrics.put(BooleanMetrics.BUILD_SRC_EXISTS, true) + } + } + configurationTimeMetrics.put(NumericalMetrics.STATISTICS_VISIT_ALL_PROJECTS_OVERHEAD, statisticOverhead) + + return configurationTimeMetrics + } + + private fun addTaskMetrics( + project: Project, + configurationTimeMetrics: MetricContainer, + ) { + try { + val taskNames = project.tasks.names.toList() + configurationTimeMetrics.put(NumericalMetrics.GRADLE_NUMBER_OF_TASKS, taskNames.size.toLong()) + configurationTimeMetrics.put( + NumericalMetrics.GRADLE_NUMBER_OF_UNCONFIGURED_TASKS, + taskNames.count { name -> + try { + project.tasks.named(name).javaClass.name.contains("TaskCreatingProvider") + } catch (_: Exception) { + true + } + }.toLong() + ) + } catch (e: Exception) { + //ignore exceptions for KT-62131. + } + } + + private fun collectAppliedPluginsStatistics( + project: Project, + configurationTimeMetrics: MetricContainer, + ) { + for (plugin in ObservablePlugins.values()) { + project.plugins.withId(plugin.title) { + configurationTimeMetrics.put(plugin.metric, true) + } + } + } + + private fun reportLibrariesVersions(configurationTimeMetrics: MetricContainer, dependencies: DependencySet?) { + dependencies?.forEach { dependency -> + when { + dependency.group?.startsWith("org.springframework") ?: false -> configurationTimeMetrics.put( + StringMetrics.LIBRARY_SPRING_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group?.startsWith("com.vaadin") ?: false -> configurationTimeMetrics.put( + StringMetrics.LIBRARY_VAADIN_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group?.startsWith("com.google.gwt") ?: false -> configurationTimeMetrics.put( + StringMetrics.LIBRARY_GWT_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group?.startsWith("org.hibernate") ?: false -> configurationTimeMetrics.put( + StringMetrics.LIBRARY_HIBERNATE_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group == "org.jetbrains.kotlin" && dependency.name.startsWith("kotlin-stdlib") -> configurationTimeMetrics.put( + StringMetrics.KOTLIN_STDLIB_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group == "org.jetbrains.kotlinx" && dependency.name == "kotlinx-coroutines" -> configurationTimeMetrics.put( + StringMetrics.KOTLIN_COROUTINES_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group == "org.jetbrains.kotlin" && dependency.name == "kotlin-reflect" -> configurationTimeMetrics.put( + StringMetrics.KOTLIN_REFLECT_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group == "org.jetbrains.kotlinx" && dependency.name + .startsWith("kotlinx-serialization-runtime") -> configurationTimeMetrics.put( + StringMetrics.KOTLIN_SERIALIZATION_VERSION, + dependency.version ?: "0.0.0" + ) + dependency.group == "com.android.tools.build" && dependency.name.startsWith("gradle") -> configurationTimeMetrics.put( + StringMetrics.ANDROID_GRADLE_PLUGIN_VERSION, + dependency.version ?: "0.0.0" + ) + } + } + } + + internal fun reportGlobalMetrics(metricConsumer: StatisticsValuesConsumer) { + runSafe("${KotlinBuildStatHandler::class.java}.reportGlobalMetrics") { + System.getProperty("os.name")?.also { metricConsumer.report(StringMetrics.OS_TYPE, System.getProperty("os.name")) } + metricConsumer.report(NumericalMetrics.CPU_NUMBER_OF_CORES, Runtime.getRuntime().availableProcessors().toLong()) + metricConsumer.report(BooleanMetrics.EXECUTED_FROM_IDEA, System.getProperty("idea.active") != null) + metricConsumer.report(NumericalMetrics.GRADLE_DAEMON_HEAP_SIZE, Runtime.getRuntime().maxMemory()) + } + } + } fun buildFinished( @@ -57,223 +268,18 @@ class KotlinBuildStatHandler { } } - fun reportGlobalMetrics( - sessionLogger: BuildSessionLogger, - ) { - runSafe("${KotlinBuildStatHandler::class.java}.reportGlobalMetrics") { - System.getProperty("os.name")?.also { sessionLogger.report(StringMetrics.OS_TYPE, System.getProperty("os.name")) } - sessionLogger.report(NumericalMetrics.CPU_NUMBER_OF_CORES, Runtime.getRuntime().availableProcessors().toLong()) - sessionLogger.report(BooleanMetrics.EXECUTED_FROM_IDEA, System.getProperty("idea.active") != null) - sessionLogger.report(NumericalMetrics.GRADLE_DAEMON_HEAP_SIZE, Runtime.getRuntime().maxMemory()) - } - } - internal fun reportBuildFinished( sessionLogger: BuildSessionLogger, action: String?, buildFailed: Boolean, - configurationMetrics: List, + metrics: NonSynchronizedMetricsContainer, ) { runSafe("${KotlinBuildStatHandler::class.java}.reportBuildFinish") { - configurationMetrics.forEach { it.report(sessionLogger) } + metrics.sendToConsumer(sessionLogger) sessionLogger.finishBuildSession(action, buildFailed) } } - internal fun collectGeneralConfigurationTimeMetrics( - project: Project, - sessionLogger: BuildSessionLogger, - isProjectIsolationEnabled: Boolean, - buildReportOutputs: List, - ): MetricContainer { - val configurationTimeMetrics = MetricContainer() - - val statisticOverhead = measureTimeMillis { - buildReportOutputs.forEach { - when (it) { - BuildReportType.BUILD_SCAN -> configurationTimeMetrics.put(BooleanMetrics.BUILD_SCAN_BUILD_REPORT, true) - BuildReportType.FILE -> configurationTimeMetrics.put(BooleanMetrics.FILE_BUILD_REPORT, true) - BuildReportType.HTTP -> configurationTimeMetrics.put(BooleanMetrics.HTTP_BUILD_REPORT, true) - BuildReportType.SINGLE_FILE -> configurationTimeMetrics.put(BooleanMetrics.SINGLE_FILE_BUILD_REPORT, true) - BuildReportType.TRY_K2_CONSOLE -> {}//ignore - } - } - val gradle = project.gradle - configurationTimeMetrics.put(StringMetrics.PROJECT_PATH, gradle.rootProject.projectDir.absolutePath) - configurationTimeMetrics.put(StringMetrics.GRADLE_VERSION, gradle.gradleVersion) - if (!isProjectIsolationEnabled) { - gradle.taskGraph.whenReady { taskExecutionGraph -> - val executedTaskNames = taskExecutionGraph.allTasks.map { it.name }.distinct() - configurationTimeMetrics.put(BooleanMetrics.MAVEN_PUBLISH_EXECUTED, executedTaskNames.contains("install")) - } - } - } - sessionLogger.report(NumericalMetrics.STATISTICS_VISIT_ALL_PROJECTS_OVERHEAD, statisticOverhead) - - return configurationTimeMetrics - - } - - internal fun collectProjectConfigurationTimeMetrics( - project: Project, - sessionLogger: BuildSessionLogger, - isProjectIsolationEnabled: Boolean, - ): MetricContainer { - val configurationTimeMetrics = MetricContainer() - - if (isProjectIsolationEnabled) { //support project isolation - KT-58768 - return configurationTimeMetrics - } - - val statisticOverhead = measureTimeMillis { - collectAppliedPluginsStatistics(project, configurationTimeMetrics) - - val configurations = project.configurations.asMap.values - for (configuration in configurations) { - try { - val configurationName = configuration.name - val dependencies = configuration.dependencies - - when (configurationName) { - "KoverEngineConfig" -> { - configurationTimeMetrics.put(BooleanMetrics.ENABLED_KOVER, true) - } - "kapt" -> { - configurationTimeMetrics.put(BooleanMetrics.ENABLED_KAPT, true) - for (dependency in dependencies) { - when (dependency.group) { - "com.google.dagger" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DAGGER, true) - "com.android.databinding" -> configurationTimeMetrics.put(BooleanMetrics.ENABLED_DATABINDING, true) - } - } - } - API -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_API_COUNT, 1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - IMPLEMENTATION -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_IMPLEMENTATION_COUNT, 1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - COMPILE -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_COMPILE_COUNT, 1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - COMPILE_ONLY -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_COMPILE_ONLY_COUNT, 1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - RUNTIME -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_RUNTIME_COUNT, 1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - RUNTIME_ONLY -> { - configurationTimeMetrics.put(NumericalMetrics.CONFIGURATION_RUNTIME_ONLY_COUNT,1) - reportLibrariesVersions(configurationTimeMetrics, dependencies) - } - } - } catch (e: Throwable) { - // log? - } - } - - configurationTimeMetrics.put(NumericalMetrics.NUMBER_OF_SUBPROJECTS, 1) - - - configurationTimeMetrics.put( - BooleanMetrics.KOTLIN_KTS_USED, - project.buildscript.sourceFile?.name?.endsWith(".kts") ?: false - ) - - addTaskMetrics(project, configurationTimeMetrics) - - if (project.name == "buildSrc") { - configurationTimeMetrics.put(NumericalMetrics.BUILD_SRC_COUNT, 1) - configurationTimeMetrics.put(BooleanMetrics.BUILD_SRC_EXISTS, true) - } - } - sessionLogger.report(NumericalMetrics.STATISTICS_VISIT_ALL_PROJECTS_OVERHEAD, statisticOverhead) - - return configurationTimeMetrics - } - - private fun addTaskMetrics( - project: Project, - configurationTimeMetrics: MetricContainer, - ) { - try { - val taskNames = project.tasks.names.toList() - configurationTimeMetrics.put(NumericalMetrics.GRADLE_NUMBER_OF_TASKS, taskNames.size.toLong()) - configurationTimeMetrics.put( - NumericalMetrics.GRADLE_NUMBER_OF_UNCONFIGURED_TASKS, - taskNames.count { name -> - try { - project.tasks.named(name).javaClass.name.contains("TaskCreatingProvider") - } catch (_: Exception) { - true - } - }.toLong() - ) - } catch (e: Exception) { - //ignore exceptions for KT-62131. - } - } - - private fun collectAppliedPluginsStatistics( - project: Project, - configurationTimeMetrics: MetricContainer, - ) { - for (plugin in ObservablePlugins.values()) { - project.plugins.withId(plugin.title) { - configurationTimeMetrics.put(plugin.metric, true) - } - } - } - - private fun reportLibrariesVersions(configurationTimeMetrics: MetricContainer, dependencies: DependencySet?) { - dependencies?.forEach { dependency -> - when { - dependency.group?.startsWith("org.springframework") ?: false -> configurationTimeMetrics.put( - StringMetrics.LIBRARY_SPRING_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group?.startsWith("com.vaadin") ?: false -> configurationTimeMetrics.put( - StringMetrics.LIBRARY_VAADIN_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group?.startsWith("com.google.gwt") ?: false -> configurationTimeMetrics.put( - StringMetrics.LIBRARY_GWT_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group?.startsWith("org.hibernate") ?: false -> configurationTimeMetrics.put( - StringMetrics.LIBRARY_HIBERNATE_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group == "org.jetbrains.kotlin" && dependency.name.startsWith("kotlin-stdlib") -> configurationTimeMetrics.put( - StringMetrics.KOTLIN_STDLIB_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group == "org.jetbrains.kotlinx" && dependency.name == "kotlinx-coroutines" -> configurationTimeMetrics.put( - StringMetrics.KOTLIN_COROUTINES_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group == "org.jetbrains.kotlin" && dependency.name == "kotlin-reflect" -> configurationTimeMetrics.put( - StringMetrics.KOTLIN_REFLECT_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group == "org.jetbrains.kotlinx" && dependency.name - .startsWith("kotlinx-serialization-runtime") -> configurationTimeMetrics.put( - StringMetrics.KOTLIN_SERIALIZATION_VERSION, - dependency.version ?: "0.0.0" - ) - dependency.group == "com.android.tools.build" && dependency.name.startsWith("gradle") -> configurationTimeMetrics.put( - StringMetrics.ANDROID_GRADLE_PLUGIN_VERSION, - dependency.version ?: "0.0.0" - ) - } - } - } - internal fun report( sessionLogger: BuildSessionLogger, metric: BooleanMetrics, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt index 6de375a8bd7..741df3e381a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildStatsService.kt @@ -19,11 +19,10 @@ import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAc import org.jetbrains.kotlin.gradle.plugin.internal.configurationTimePropertiesAccessor import org.jetbrains.kotlin.gradle.plugin.internal.usedAtConfigurationTime import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatHandler.Companion.runSafe -import org.jetbrains.kotlin.gradle.report.BuildReportType import org.jetbrains.kotlin.statistics.BuildSessionLogger import org.jetbrains.kotlin.statistics.BuildSessionLogger.Companion.STATISTICS_FOLDER_NAME import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics -import org.jetbrains.kotlin.statistics.metrics.IStatisticsValuesConsumer +import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics import org.jetbrains.kotlin.statistics.metrics.StringMetrics import java.io.Closeable @@ -46,7 +45,7 @@ interface KotlinBuildStatsMXBean { fun reportString(name: String, value: String, subprojectName: String?, weight: Long?): Boolean } -internal abstract class KotlinBuildStatsService internal constructor() : IStatisticsValuesConsumer, Closeable { +internal abstract class KotlinBuildStatsService internal constructor() : StatisticsValuesConsumer, Closeable { companion object { // Property name for disabling saving statistical information private const val ENABLE_STATISTICS_PROPERTY_NAME = "enable_kotlin_performance_profile" @@ -188,21 +187,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : IStatis override fun close() { } - - /** - * Collects metrics at the end of a build - */ - open fun recordBuildFinish(action: String?, buildFailed: Boolean, configurationTimeMetrics: List) {} - - /** - * Collect project's configuration metrics - */ - open fun collectProjectConfigurationMetrics(project: Project, isProjectIsolationEnabled: Boolean): MetricContainer = MetricContainer() - - /** - * Collect general configuration metrics - */ - open fun collectGeneralConfigurationMetrics(project: Project, isProjectIsolationEnabled: Boolean, buildReportOutputs: List): MetricContainer = MetricContainer() + open fun recordBuildFinish(action: String?, buildFailed: Boolean, metric: NonSynchronizedMetricsContainer) {} open fun recordProjectsEvaluated(gradle: Gradle) {} } @@ -314,14 +299,7 @@ internal class DefaultKotlinBuildStatsService internal constructor( report(StringMetrics.valueOf(name), value, subprojectName, weight) //only one jmx bean service should report global metrics - override fun recordBuildFinish(action: String?, buildFailed: Boolean, configurationTimeMetrics: List) { - KotlinBuildStatHandler().reportGlobalMetrics(sessionLogger) - KotlinBuildStatHandler().reportBuildFinished(sessionLogger, action, buildFailed, configurationTimeMetrics) + override fun recordBuildFinish(action: String?, buildFailed: Boolean, metrics: NonSynchronizedMetricsContainer) { + KotlinBuildStatHandler().reportBuildFinished(sessionLogger, action, buildFailed, metrics) } - - override fun collectProjectConfigurationMetrics(project: Project, isProjectIsolationEnabled: Boolean) = - KotlinBuildStatHandler().collectProjectConfigurationTimeMetrics(project, sessionLogger, isProjectIsolationEnabled) - - override fun collectGeneralConfigurationMetrics(project: Project, isProjectIsolationEnabled: Boolean, buildReportOutputs: List) = - KotlinBuildStatHandler().collectGeneralConfigurationTimeMetrics(project, sessionLogger, isProjectIsolationEnabled, buildReportOutputs) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/NonSynchronizedMetricsContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/NonSynchronizedMetricsContainer.kt new file mode 100644 index 00000000000..4ceb72031c5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/NonSynchronizedMetricsContainer.kt @@ -0,0 +1,57 @@ +/* + * 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.gradle.plugin.statistics + +import org.jetbrains.kotlin.statistics.metrics.* +import java.io.Serializable +import kotlin.collections.HashMap + +class NonSynchronizedMetricsContainer : StatisticsValuesConsumer, Serializable { + data class MetricDescriptor>(val name: T, val subprojectName: String?) : Comparable> { + override fun compareTo(other: MetricDescriptor): Int { + val compareNames = name.compareTo(other.name) + return when { + compareNames != 0 -> compareNames + subprojectName == other.subprojectName -> 0 + else -> (subprojectName ?: "").compareTo(other.subprojectName ?: "") + } + } + } + + private val numericalMetrics = HashMap, IMetricContainer>() + + private val booleanMetrics = HashMap, IMetricContainer>() + + private val stringMetrics = HashMap, IMetricContainer>() + + override fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String?, weight: Long?): Boolean { + booleanMetrics.getOrPut(MetricDescriptor(metric, subprojectName)) { metric.type.newMetricContainer() }.let { metricContainer -> + metricContainer.addValue(value, weight) + } + return true + } + + override fun report(metric: NumericalMetrics, value: Long, subprojectName: String?, weight: Long?): Boolean { + numericalMetrics.getOrPut(MetricDescriptor(metric, subprojectName)) { metric.type.newMetricContainer() }.let { metricContainer -> + metricContainer.addValue(value, weight) + } + return true + } + + override fun report(metric: StringMetrics, value: String, subprojectName: String?, weight: Long?): Boolean { + stringMetrics.getOrPut(MetricDescriptor(metric, subprojectName)) { metric.type.newMetricContainer() }.let { metricContainer -> + metricContainer.addValue(value, weight) + } + return true + } + + fun sendToConsumer(metricConsumer: StatisticsValuesConsumer) { + booleanMetrics.forEach { metricConsumer.report(it.key.name, it.value.getValue()!!, it.key.subprojectName) } + numericalMetrics.forEach { metricConsumer.report(it.key.name, it.value.getValue()!!, it.key.subprojectName) } + stringMetrics.forEach { metricConsumer.report(it.key.name, it.value.getValue()!!, it.key.subprojectName) } + } + +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt index 2d42f26243a..0fbbc9680c5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/report/BuildMetricsService.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.report import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.file.DirectoryProperty -import org.gradle.api.invocation.Gradle import org.gradle.api.logging.Logging import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property @@ -32,7 +31,6 @@ import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults import org.jetbrains.kotlin.build.report.statistics.BuildStartParameters import org.jetbrains.kotlin.build.report.statistics.StatTag import org.jetbrains.kotlin.buildtools.api.SourcesChanges -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.report.BuildReportsService.Companion.getStartParameters import org.jetbrains.kotlin.gradle.report.data.BuildOperationRecord import org.jetbrains.kotlin.gradle.tasks.withType @@ -42,7 +40,9 @@ import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedQueue import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.plugin.StatisticsBuildFlowManager import org.jetbrains.kotlin.gradle.plugin.internal.isConfigurationCacheRequested +import org.jetbrains.kotlin.gradle.plugin.statistics.BuildFusService import java.lang.management.ManagementFactory internal interface UsesBuildMetricsService : Task { @@ -63,6 +63,7 @@ abstract class BuildMetricsService : BuildService val kotlinVersion: Property val buildConfigurationTags: ListProperty + val fusService: Property } private val log = Logging.getLogger(this.javaClass) @@ -114,9 +115,11 @@ abstract class BuildMetricsService : BuildService + parameters.fusService.orNull?.reportFusMetrics { collector -> collector.report(NumericalMetrics.COMPILATION_DURATION, totalTimeMs) collector.report(BooleanMetrics.KOTLIN_COMPILATION_FAILED, event.result is FailureResult) + collector.report(NumericalMetrics.COMPILATIONS_COUNT, 1) + val metricsMap = buildMetrics.buildPerformanceMetrics.asMap() val linesOfCode = metricsMap[GradleBuildPerformanceMetric.ANALYZED_LINES_NUMBER] @@ -130,7 +133,6 @@ abstract class BuildMetricsService : BuildService ): Provider? { // Return early if the service was already registered to avoid the overhead of reading the reporting settings below project.gradle.sharedServices.registrations.findByName(serviceName)?.let { @@ -221,6 +224,7 @@ abstract class BuildMetricsService : BuildService {}//do nothing, BuildScanFlowAction is used - } - } - - fun registerIfAbsent(project: Project) = registerIfAbsentImpl(project)?.also { serviceProvider -> - SingleActionPerProject.run(project, UsesBuildMetricsService::class.java.name) { - project.tasks.withType().configureEach { task -> - task.buildMetricsService.value(serviceProvider).disallowChanges() - task.usesService(serviceProvider) + else -> { + StatisticsBuildFlowManager.getInstance(project).subscribeForBuildScan(buildScanHolder) } } } + fun registerIfAbsent(project: Project, fusService: Provider) = + registerIfAbsentImpl(project, fusService)?.also { serviceProvider -> + SingleActionPerProject.run(project, UsesBuildMetricsService::class.java.name) { + project.tasks.withType().configureEach { task -> + task.buildMetricsService.value(serviceProvider).disallowChanges() + task.usesService(serviceProvider) + } + } + } + private fun setupTags(project: Project): ArrayList { val gradle = project.gradle val additionalTags = ArrayList() diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt index 253da6568cc..98a5e94819d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/AbstractSetupTask.kt @@ -10,14 +10,14 @@ import org.gradle.api.tasks.* import org.gradle.internal.hash.FileHasher import org.gradle.work.DisableCachingByDefault import org.jetbrains.kotlin.gradle.logging.kotlinInfo -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics import java.io.File import java.net.URI import javax.inject.Inject @DisableCachingByDefault -abstract class AbstractSetupTask> : DefaultTask() { +abstract class AbstractSetupTask> : DefaultTask(), UsesBuildFusService { @get:Internal protected abstract val settings: Settings @@ -77,8 +77,9 @@ abstract class AbstractSetupTask 0) { - KotlinBuildStatsService.getInstance() - ?.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, it.length() * 1000 / downloadDuration) + buildFusService.orNull?.reportFusMetrics { metricsConsumer -> + metricsConsumer.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, it.length() * 1000 / downloadDuration) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrLink.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrLink.kt index ed6fd22fcde..3520886fb86 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrLink.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrLink.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptionsDefault import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.ContributeCompilerArgumentsContext import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode.DEVELOPMENT import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile @@ -39,7 +39,7 @@ abstract class KotlinJsIrLink @Inject constructor( objectFactory.newInstance(KotlinJsCompilerOptionsDefault::class.java).configureExperimentalTryK2(project), objectFactory, workerExecutor -) { +), UsesBuildFusService { init { // Not check sources, only klib module @@ -117,7 +117,7 @@ abstract class KotlinJsIrLink @Inject constructor( } override fun processArgsBeforeCompile(args: K2JSCompilerArguments) { - KotlinBuildStatsService.applyIfInitialised { + buildFusService.orNull?.reportFusMetrics { it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr) val newArgs = K2JSCompilerArguments() parseCommandLineArguments(ArgumentUtils.convertArgumentsToStringList(args), newArgs) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 7be24842574..22ee2e55665 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -37,7 +37,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.Create import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.create import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName import org.jetbrains.kotlin.gradle.plugin.mpp.* -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.gradle.report.* import org.jetbrains.kotlin.gradle.report.UsesBuildMetricsService import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService @@ -45,7 +45,6 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.* import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.gradle.utils.GradleLoggerAdapter import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty -import org.jetbrains.kotlin.incremental.deleteDirectoryContents import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageMode import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER import org.jetbrains.kotlin.konan.properties.saveToFile @@ -307,7 +306,8 @@ internal constructor( KotlinCompile, K2MultiplatformCompilationTask, UsesBuildMetricsService, - KotlinCompilationTask { + KotlinCompilationTask, + UsesBuildFusService { @get:Input override val outputKind = LIBRARY @@ -536,13 +536,13 @@ internal constructor( } private fun collectCommonCompilerStats() { - KotlinBuildStatsService.getInstance()?.apply { - report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get()) + buildFusService.orNull?.reportFusMetrics { + it.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get()) compilerOptions.apiVersion.orNull?.also { v -> - report(StringMetrics.KOTLIN_API_VERSION, v.version) + it.report(StringMetrics.KOTLIN_API_VERSION, v.version) } compilerOptions.languageVersion.orNull?.also { v -> - report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version) + it.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version) } } } @@ -725,7 +725,7 @@ internal class CacheBuilder( private val executionContext: KotlinToolRunner.GradleExecutionContext, private val settings: Settings, private val konanPropertiesService: KonanPropertiesBuildService, - private val metricsReporter: BuildMetricsReporter + private val metricsReporter: BuildMetricsReporter, ) { class Settings( val runnerSettings: KotlinNativeCompilerRunner.Settings, @@ -955,7 +955,8 @@ internal class CacheBuilder( } private fun ensureCompilerProvidedLibsPrecached() { - val distribution = Distribution(settings.runnerSettings.parent.konanHome, konanDataDir = settings.runnerSettings.parent.konanDataDir) + val distribution = + Distribution(settings.runnerSettings.parent.konanHome, konanDataDir = settings.runnerSettings.parent.konanDataDir) val platformLibs = mutableListOf().apply { this += File(distribution.stdlib) this += File(distribution.platformLibs(konanTarget)).listFiles().orEmpty() @@ -1172,7 +1173,7 @@ abstract class CInteropProcess @Inject internal constructor(params: Params) : addAll(extraOpts) } - addBuildMetricsForTaskAction(buildMetrics, languageVersion = null) { + addBuildMetricsForTaskAction(buildMetrics, languageVersion = null) { outputFile.parentFile.mkdirs() KotlinNativeCInteropRunner.createExecutionContext( task = this, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt index 1c18217c812..7c66d8f294a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.gradle.plugin.UsesBuildFinishedListenerService import org.jetbrains.kotlin.gradle.plugin.UsesVariantImplementationFactories import org.jetbrains.kotlin.gradle.plugin.diagnostics.UsesKotlinToolingDiagnostics import org.jetbrains.kotlin.gradle.plugin.internal.UsesBuildIdProviderService -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.gradle.report.* import org.jetbrains.kotlin.gradle.utils.* import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics @@ -60,6 +60,7 @@ abstract class AbstractKotlinCompile @Inject constr UsesClassLoadersCachingBuildService, UsesKotlinToolingDiagnostics, UsesBuildIdProviderService, + UsesBuildFusService, BaseKotlinCompile { init { @@ -201,6 +202,7 @@ abstract class AbstractKotlinCompile @Inject constr classLoadersCachingService, buildFinishedListenerService, buildIdService, + buildFusService.orNull?.fusMetricsConsumer ) } } @@ -247,7 +249,7 @@ abstract class AbstractKotlinCompile @Inject constr val buildMetrics = metrics.get() buildMetrics.addTimeMetric(GradleBuildPerformanceMetric.START_TASK_ACTION_EXECUTION) buildMetrics.measure(GradleBuildTime.OUT_OF_WORKER_TASK_ACTION) { - KotlinBuildStatsService.applyIfInitialised { + buildFusService.orNull?.reportFusMetrics { if (name.contains("Test")) it.report(BooleanMetrics.TESTS_EXECUTED, true) else @@ -289,13 +291,13 @@ abstract class AbstractKotlinCompile @Inject constr } private fun collectCommonCompilerStats() { - KotlinBuildStatsService.getInstance()?.apply { - report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get()) + buildFusService.orNull?.reportFusMetrics { + it.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get()) compilerOptions.apiVersion.orNull?.also { v -> - report(StringMetrics.KOTLIN_API_VERSION, v.version) + it.report(StringMetrics.KOTLIN_API_VERSION, v.version) } compilerOptions.languageVersion.orNull?.also { v -> - report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version) + it.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt index f06c2e26af4..f09d75ab411 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt @@ -31,7 +31,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.Contri import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.create import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion -import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService +import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.gradle.report.BuildReportMode import org.jetbrains.kotlin.gradle.targets.js.internal.LibraryFilterCachingService import org.jetbrains.kotlin.gradle.targets.js.internal.UsesLibraryFilterCachingService @@ -41,7 +41,6 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.PRODUCE_UNZIPPED_KLIB import org.jetbrains.kotlin.gradle.targets.js.ir.PRODUCE_ZIPPED_KLIB import org.jetbrains.kotlin.gradle.tasks.internal.KotlinJsOptionsCompat import org.jetbrains.kotlin.gradle.utils.getFile -import org.jetbrains.kotlin.gradle.utils.existsCompat import org.jetbrains.kotlin.gradle.utils.isParentOf import org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.gradle.utils.toPathsArray @@ -60,6 +59,7 @@ abstract class Kotlin2JsCompile @Inject constructor( ) : AbstractKotlinCompile(objectFactory, workerExecutor), KotlinCompilationTask, UsesLibraryFilterCachingService, + UsesBuildFusService, KotlinJsCompile, K2MultiplatformCompilationTask { @@ -82,14 +82,14 @@ abstract class Kotlin2JsCompile @Inject constructor( PRODUCE_JS in freeArgs -> false PRODUCE_UNZIPPED_KLIB in freeArgs -> { - KotlinBuildStatsService.applyIfInitialised { + buildFusService.orNull?.reportFusMetrics { it.report(BooleanMetrics.JS_KLIB_INCREMENTAL, incrementalJsKlib) } incrementalJsKlib } PRODUCE_ZIPPED_KLIB in freeArgs -> { - KotlinBuildStatsService.applyIfInitialised { + buildFusService.orNull?.reportFusMetrics { it.report(BooleanMetrics.JS_KLIB_INCREMENTAL, incrementalJsKlib) } incrementalJsKlib diff --git a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt index 0c8c6c9edb0..c02037157bb 100644 --- a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt +++ b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/BuildSessionLogger.kt @@ -21,7 +21,7 @@ class BuildSessionLogger( private val maxFileSize: Long = DEFAULT_MAX_PROFILE_FILE_SIZE, private val maxFileAge: Long = DEFAULT_MAX_FILE_AGE, private val forceValuesValidation: Boolean = false, -) : IStatisticsValuesConsumer { +) : StatisticsValuesConsumer { companion object { const val STATISTICS_FOLDER_NAME = "kotlin-profile" diff --git a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/fileloggers/MetricsContainer.kt b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/fileloggers/MetricsContainer.kt index e9eacdb23a0..95a83069527 100644 --- a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/fileloggers/MetricsContainer.kt +++ b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/fileloggers/MetricsContainer.kt @@ -16,7 +16,7 @@ import java.nio.file.Paths import java.nio.file.StandardOpenOption import java.util.* -class MetricsContainer(private val forceValuesValidation: Boolean = false) : IStatisticsValuesConsumer { +class MetricsContainer(private val forceValuesValidation: Boolean = false) : StatisticsValuesConsumer { data class MetricDescriptor(val name: String, val projectHash: String?) : Comparable { override fun compareTo(other: MetricDescriptor): Int { val compareNames = name.compareTo(other.name) diff --git a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/MetricContainers.kt b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/MetricContainers.kt index 7c88f3378ab..4a4eb405131 100644 --- a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/MetricContainers.kt +++ b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/MetricContainers.kt @@ -5,9 +5,10 @@ package org.jetbrains.kotlin.statistics.metrics +import java.io.Serializable import java.util.* -interface IMetricContainer { +interface IMetricContainer : Serializable { fun addValue(t: T, weight: Long? = null) fun toStringRepresentation(): String diff --git a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/StatisticsValues.kt b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/StatisticsValues.kt index 43b142f89a1..2ae074f9aac 100644 --- a/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/StatisticsValues.kt +++ b/libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics/StatisticsValues.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.statistics.metrics -interface IStatisticsValuesConsumer { +interface StatisticsValuesConsumer { fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String? = null, weight: Long? = null): Boolean fun report(metric: NumericalMetrics, value: Long, subprojectName: String? = null, weight: Long? = null): Boolean diff --git a/libraries/tools/kotlin-gradle-statistics/src/test/kotlin/org/jetbrains/kotlin/statistics/ModuleChangesCatchingTest.kt b/libraries/tools/kotlin-gradle-statistics/src/test/kotlin/org/jetbrains/kotlin/statistics/ModuleChangesCatchingTest.kt index c9149a5aef7..b19f3e96f02 100644 --- a/libraries/tools/kotlin-gradle-statistics/src/test/kotlin/org/jetbrains/kotlin/statistics/ModuleChangesCatchingTest.kt +++ b/libraries/tools/kotlin-gradle-statistics/src/test/kotlin/org/jetbrains/kotlin/statistics/ModuleChangesCatchingTest.kt @@ -17,10 +17,10 @@ import kotlin.test.Test import kotlin.test.assertEquals private const val SOURCE_CODE_RELATIVE_PATH = - "libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics" -private const val BOOLEAN_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/metrics/BooleanMetrics.kt" -private const val STRING_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/metrics/StringMetrics.kt" -private const val NUMERICAL_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/metrics/NumericalMetrics.kt" + "libraries/tools/kotlin-gradle-statistics/src/main/kotlin/org/jetbrains/kotlin/statistics/metrics" +private const val BOOLEAN_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/BooleanMetrics.kt" +private const val STRING_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/StringMetrics.kt" +private const val NUMERICAL_METRICS_RELATIVE_PATH = "$SOURCE_CODE_RELATIVE_PATH/NumericalMetrics.kt" private val STRING_METRICS_EXPECTED_VERSION_AND_HASH = Pair(1, "90347332db2ce54b51e7daa64595371e") private val BOOLEAN_METRICS_EXPECTED_VERSION_AND_HASH = Pair(3, "3c8c4ca636adee168e99862244a22520") @@ -30,7 +30,7 @@ private val SOURCE_FOLDER_EXPECTED_VERSION_AND_HASH = STRING_METRICS_EXPECTED_VERSION_AND_HASH.first + BOOLEAN_METRICS_EXPECTED_VERSION_AND_HASH.first + NUMERICAL_METRICS_EXPECTED_VERSION_AND_HASH.first, - "ce47debcab820f23e0ea1333d4124e9e" + "8b845ce616f5bdb9b885ededcdfd812d" ) private const val HASH_ALG = "MD5"