Report FUS metrics only from FusMetrics.kt

#KT-65213 Fixed
This commit is contained in:
Nataliya.Valtman
2024-01-22 17:18:59 +01:00
committed by Space Team
parent 3da1efc94a
commit 6000596673
12 changed files with 309 additions and 205 deletions
@@ -37,14 +37,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.CompilerArgumentMetrics
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
import java.util.concurrent.locks.ReentrantReadWriteLock
@@ -170,46 +169,7 @@ internal open class GradleCompilerRunner(
}
val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray()
// 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
fusMetricsConsumer?.let { metricsConsumer ->
when (compilerArgs) {
is K2JVMCompilerArguments -> {
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()) }) {
metricsConsumer.report(pluginPattern.first, true)
}
}
}
}
is K2JSCompilerArguments -> {
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())
}
}
}
}
fusMetricsConsumer?.let { metricsConsumer -> CompilerArgumentMetrics.collectMetrics(compilerArgs, argsArray, metricsConsumer) }
val incrementalCompilationEnvironment = environment.incrementalCompilationEnvironment
val modulesInfo = incrementalCompilationEnvironment?.let { incrementalModuleInfoProvider.orNull?.info }
@@ -14,13 +14,11 @@ import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.api.tasks.Internal
import org.gradle.tooling.events.FailureResult
import org.gradle.tooling.events.FinishEvent
import org.gradle.tooling.events.OperationCompletionListener
import org.gradle.tooling.events.task.TaskFailureResult
import org.gradle.tooling.events.task.TaskFinishEvent
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.BuildEventsListenerRegistryHolder
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
@@ -28,7 +26,6 @@ import org.jetbrains.kotlin.gradle.plugin.StatisticsBuildFlowManager
import org.jetbrains.kotlin.gradle.plugin.internal.isConfigurationCacheRequested
import org.jetbrains.kotlin.gradle.plugin.internal.isProjectIsolationEnabled
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
import org.jetbrains.kotlin.gradle.report.reportingSettings
import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.SingleActionPerProject
@@ -96,7 +93,7 @@ abstract class BuildFusService : BuildService<BuildFusService.Parameters>, AutoC
project.gradle.sharedServices.registrations.findByName(serviceName)?.let {
(it.parameters as Parameters).configurationMetrics.add(
project.provider {
collectProjectConfigurationTimeMetrics(project)
KotlinProjectConfigurationMetrics.collectMetrics(project)
}
)
@@ -159,11 +156,9 @@ abstract class BuildFusService : BuildService<BuildFusService.Parameters>, AutoC
}
val taskExecutionResult = TaskExecutionResults[event.descriptor.taskPath]
taskExecutionResult?.also { reportTaskMetrics(it, event) }
}
event?.descriptor?.name?.also {
getMetricToReport(it)?.also { fusMetricsConsumer.report(it, true) }
taskExecutionResult?.also { KotlinTaskExecutionMetrics.collectMetrics(it, event, fusMetricsConsumer) }
}
ExecutedTaskMetrics.collectMetrics(event, fusMetricsConsumer)
}
override fun close() {
@@ -174,9 +169,8 @@ abstract class BuildFusService : BuildService<BuildFusService.Parameters>, AutoC
}
internal fun recordBuildFinished(buildFailed: Boolean) {
reportGlobalMetrics(log, fusMetricsConsumer)
BuildFinishMetrics.collectMetrics(log, buildFailed, buildStartTime, projectEvaluatedTime, fusMetricsConsumer)
parameters.configurationMetrics.orElse(emptyList()).get().forEach { it.addToConsumer(fusMetricsConsumer) }
reportBuildFinished(log, buildFailed, buildStartTime, projectEvaluatedTime, fusMetricsConsumer)
parameters.buildStatisticsConfiguration.orNull?.also {
val loggerService = KotlinBuildStatsLoggerService(it)
loggerService.initSessionLogger(buildId)
@@ -184,32 +178,6 @@ abstract class BuildFusService : BuildService<BuildFusService.Parameters>, AutoC
}
KotlinBuildStatsBeanService.closeServices()
}
private fun reportTaskMetrics(taskExecutionResult: TaskExecutionResult, event: TaskFinishEvent) {
val totalTimeMs = event.result.endTime - event.result.startTime
val buildMetrics = taskExecutionResult.buildMetrics
fusMetricsConsumer.report(NumericalMetrics.COMPILATION_DURATION, totalTimeMs)
fusMetricsConsumer.report(BooleanMetrics.KOTLIN_COMPILATION_FAILED, event.result is FailureResult)
fusMetricsConsumer.report(NumericalMetrics.COMPILATIONS_COUNT, 1)
val metricsMap = buildMetrics.buildPerformanceMetrics.asMap()
val linesOfCode = metricsMap[GradleBuildPerformanceMetric.ANALYZED_LINES_NUMBER]
if (linesOfCode != null && linesOfCode > 0 && totalTimeMs > 0) {
fusMetricsConsumer.report(NumericalMetrics.COMPILED_LINES_OF_CODE, linesOfCode)
fusMetricsConsumer.report(NumericalMetrics.COMPILATION_LINES_PER_SECOND, linesOfCode * 1000 / totalTimeMs, null, linesOfCode)
metricsMap[GradleBuildPerformanceMetric.ANALYSIS_LPS]?.also { value ->
fusMetricsConsumer.report(NumericalMetrics.ANALYSIS_LINES_PER_SECOND, value, null, linesOfCode)
}
metricsMap[GradleBuildPerformanceMetric.CODE_GENERATION_LPS]?.also { value ->
fusMetricsConsumer.report(NumericalMetrics.CODE_GENERATION_LINES_PER_SECOND, value, null, linesOfCode)
}
}
fusMetricsConsumer.report(
NumericalMetrics.INCREMENTAL_COMPILATIONS_COUNT,
if (taskExecutionResult.buildMetrics.buildAttributes.asMap().isEmpty()) 1 else 0
)
}
}
class MetricContainer : Serializable {
@@ -0,0 +1,274 @@
/*
* Copyright 2010-2024 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.gradle.api.Project
import org.gradle.api.logging.Logger
import org.gradle.tooling.events.FailureResult
import org.gradle.tooling.events.FinishEvent
import org.gradle.tooling.events.task.TaskFinishEvent
import org.jetbrains.kotlin.build.report.metrics.GradleBuildPerformanceMetric
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.report.TaskExecutionResult
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrOutputGranularity
import org.jetbrains.kotlin.gradle.utils.addConfigurationMetrics
import org.jetbrains.kotlin.gradle.utils.runMetricMethodSafely
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal sealed interface FusMetrics
internal object ExecutedTaskMetrics : FusMetrics {
private fun getMetricToReport(task: String) = when (task.substringAfterLast(":")) {
"dokkaHtml" -> BooleanMetrics.ENABLED_DOKKA_HTML
"dokkaGfm" -> BooleanMetrics.ENABLED_DOKKA_GFM
"dokkaJavadoc" -> BooleanMetrics.ENABLED_DOKKA_JAVADOC
"dokkaJekyll" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL
"dokkaHtmlMultiModule" -> BooleanMetrics.ENABLED_DOKKA_HTML_MULTI_MODULE
"dokkaGfmMultiModule" -> BooleanMetrics.ENABLED_DOKKA_GFM_MULTI_MODULE
"dokkaJekyllMultiModule" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL_MULTI_MODULE
"dokkaHtmlCollector" -> BooleanMetrics.ENABLED_DOKKA_HTML_COLLECTOR
"dokkaGfmCollector" -> BooleanMetrics.ENABLED_DOKKA_GFM_COLLECTOR
"dokkaJavadocCollector" -> BooleanMetrics.ENABLED_DOKKA_JAVADOC_COLLECTOR
"dokkaJekyllCollector" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL_COLLECTOR
else -> null
}
internal fun collectMetrics(event: FinishEvent?, metricConsumer: StatisticsValuesConsumer) {
event?.descriptor?.name?.also {
getMetricToReport(it)?.also { metricConsumer.report(it, true) }
}
}
}
internal object CompilerArgumentMetrics : FusMetrics {
// 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
internal fun collectMetrics(
compilerArgs: CommonCompilerArguments?,
argsArray: Array<String>,
metricsConsumer: StatisticsValuesConsumer,
) {
when (compilerArgs) {
is K2JVMCompilerArguments -> {
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()) }) {
metricsConsumer.report(pluginPattern.first, true)
}
}
}
}
is K2JSCompilerArguments -> {
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())
}
}
}
}
}
internal object NativeCompilerOptionMetrics : FusMetrics {
fun collectMetrics(compilerOptions: KotlinNativeCompilerOptions, metricsConsumer: StatisticsValuesConsumer) {
metricsConsumer.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get())
compilerOptions.apiVersion.orNull?.also { v ->
metricsConsumer.report(StringMetrics.KOTLIN_API_VERSION, v.version)
}
compilerOptions.languageVersion.orNull?.also { v ->
metricsConsumer.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version)
}
}
}
internal object KotlinTaskExecutionMetrics : FusMetrics {
fun collectMetrics(taskExecutionResult: TaskExecutionResult, event: TaskFinishEvent, metricsConsumer: StatisticsValuesConsumer) {
val totalTimeMs = event.result.endTime - event.result.startTime
val buildMetrics = taskExecutionResult.buildMetrics
metricsConsumer.report(NumericalMetrics.COMPILATION_DURATION, totalTimeMs)
metricsConsumer.report(BooleanMetrics.KOTLIN_COMPILATION_FAILED, event.result is FailureResult)
metricsConsumer.report(NumericalMetrics.COMPILATIONS_COUNT, 1)
val metricsMap = buildMetrics.buildPerformanceMetrics.asMap()
val linesOfCode = metricsMap[GradleBuildPerformanceMetric.ANALYZED_LINES_NUMBER]
if (linesOfCode != null && linesOfCode > 0 && totalTimeMs > 0) {
metricsConsumer.report(NumericalMetrics.COMPILED_LINES_OF_CODE, linesOfCode)
metricsConsumer.report(NumericalMetrics.COMPILATION_LINES_PER_SECOND, linesOfCode * 1000 / totalTimeMs, null, linesOfCode)
metricsMap[GradleBuildPerformanceMetric.ANALYSIS_LPS]?.also { value ->
metricsConsumer.report(NumericalMetrics.ANALYSIS_LINES_PER_SECOND, value, null, linesOfCode)
}
metricsMap[GradleBuildPerformanceMetric.CODE_GENERATION_LPS]?.also { value ->
metricsConsumer.report(NumericalMetrics.CODE_GENERATION_LINES_PER_SECOND, value, null, linesOfCode)
}
}
metricsConsumer.report(
NumericalMetrics.INCREMENTAL_COMPILATIONS_COUNT,
if (taskExecutionResult.buildMetrics.buildAttributes.asMap().isEmpty()) 1 else 0
)
}
}
internal object BuildFinishMetrics : FusMetrics {
fun collectMetrics(
logger: Logger,
buildFailed: Boolean,
buildStartTime: Long?,
projectEvaluatedTime: Long?,
metricsConsumer: StatisticsValuesConsumer,
) {
reportGlobalMetrics(logger, metricsConsumer)
reportBuildFinished(logger, buildFailed, buildStartTime, projectEvaluatedTime, metricsConsumer)
}
private fun reportGlobalMetrics(logger: Logger, metricConsumer: StatisticsValuesConsumer) {
runMetricMethodSafely(logger, "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())
metricConsumer.report(NumericalMetrics.GRADLE_BUILD_NUMBER_IN_CURRENT_DAEMON, DaemonReuseCounter.incrementAndGetOrdinal())
}
}
private fun reportBuildFinished(
logger: Logger,
buildFailed: Boolean,
buildStartedTime: Long?,
projectEvaluatedTime: Long?,
metricsContainer: StatisticsValuesConsumer,
) {
runMetricMethodSafely(logger, "reportBuildFinish") {
val finishTime = System.currentTimeMillis()
if (buildStartedTime != null) {
metricsContainer.report(NumericalMetrics.GRADLE_BUILD_DURATION, finishTime - buildStartedTime)
}
if (projectEvaluatedTime != null) {
metricsContainer.report(NumericalMetrics.GRADLE_EXECUTION_DURATION, finishTime - projectEvaluatedTime)
}
metricsContainer.report(NumericalMetrics.BUILD_FINISH_TIME, finishTime)
metricsContainer.report(BooleanMetrics.BUILD_FAILED, buildFailed)
}
}
}
internal object CompileKotlinTaskMetrics : FusMetrics {
internal fun collectMetrics(
name: String,
compilerOptions: KotlinCommonCompilerOptions,
metricsContainer: StatisticsValuesConsumer
) {
metricsContainer.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get())
compilerOptions.apiVersion.orNull?.also { v ->
metricsContainer.report(StringMetrics.KOTLIN_API_VERSION, v.version)
}
compilerOptions.languageVersion.orNull?.also { v ->
metricsContainer.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version)
}
if (name.contains("Test"))
metricsContainer.report(BooleanMetrics.TESTS_EXECUTED, true)
else
metricsContainer.report(BooleanMetrics.COMPILATION_STARTED, true)
}
}
internal object CompileKotlinJsTaskMetrics : FusMetrics {
internal fun collectMetrics(incrementalCompilation: Boolean, metricsContainer: StatisticsValuesConsumer) {
metricsContainer.report(BooleanMetrics.JS_KLIB_INCREMENTAL, incrementalCompilation)
}
}
internal object CompileKotlinJsIrLinkMetrics : FusMetrics {
internal fun collectMetrics(
compilerArgs: K2JSCompilerArguments,
incrementalJsIr: Boolean,
metricsConsumer: StatisticsValuesConsumer,
) {
metricsConsumer.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
val newArgs = K2JSCompilerArguments()
parseCommandLineArguments(ArgumentUtils.convertArgumentsToStringList(compilerArgs), newArgs)
metricsConsumer.report(
StringMetrics.JS_OUTPUT_GRANULARITY,
if (newArgs.irPerModule)
KotlinJsIrOutputGranularity.PER_MODULE.name.toLowerCaseAsciiOnly()
else
KotlinJsIrOutputGranularity.WHOLE_PROGRAM.name.toLowerCaseAsciiOnly()
)
}
}
internal object KotlinMetadataConfigurationMetrics : FusMetrics {
internal fun collectMetrics(metricContainer: MetricContainer) {
metricContainer.put(BooleanMetrics.ENABLED_HMPP, true)
}
}
internal object KotlinProjectConfigurationMetrics : FusMetrics {
internal fun collectMetrics(project: Project) = collectProjectConfigurationTimeMetrics(project)
}
internal object UrlRepoConfigurationMetrics : FusMetrics {
internal fun collectMetrics(
length: Long,
downloadDuration: Long,
metricsConsumer: StatisticsValuesConsumer
) {
metricsConsumer.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, length * 1000 / downloadDuration)
}
}
internal object KotlinJsIrTargetMetrics : FusMetrics {
internal fun collectMetrics(isBrowserConfigured: Boolean, isNodejsConfigured: Boolean, project: Project) {
project.addConfigurationMetrics { metricContainer ->
when {
isBrowserConfigured && isNodejsConfigured -> metricContainer.put(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> metricContainer.put(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> metricContainer.put(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> metricContainer.put(StringMetrics.JS_TARGET_MODE, "none")
}
}
}
}
internal object MultiplatformTargetMetrics : FusMetrics {
internal fun collectMetrics(target: KotlinTarget, project: Project) {
/* Report the platform to tbe build stats service */
val targetName = if (target is KotlinNativeTarget) target.konanTarget.name
else target.platformType.name
project.addConfigurationMetrics {
it.put(StringMetrics.MPP_PLATFORMS, targetName)
}
}
}
@@ -7,17 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.statistics
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.utils.addConfigurationMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
internal val MultiplatformBuildStatsReportSetupAction = KotlinProjectSetupAction {
multiplatformExtension.targets.all { target ->
/* Report the platform to tbe build stats service */
val targetName = if (target is KotlinNativeTarget) target.konanTarget.name
else target.platformType.name
project.addConfigurationMetrics {
it.put(StringMetrics.MPP_PLATFORMS, targetName)
}
}
multiplatformExtension.targets.all { target -> MultiplatformTargetMetrics.collectMetrics(target, project) }
}
@@ -9,13 +9,11 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySet
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.gradle.plugin.statistics.plugins.ObservablePlugins
import org.jetbrains.kotlin.gradle.report.BuildReportType
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
import org.jetbrains.kotlin.statistics.metrics.StatisticsValuesConsumer
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import kotlin.system.measureTimeMillis
@@ -220,47 +218,3 @@ private fun reportLibrariesVersions(
}
}
internal fun reportGlobalMetrics(logger: Logger, metricConsumer: StatisticsValuesConsumer) {
runMetricMethodSafely(logger, "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())
metricConsumer.report(NumericalMetrics.GRADLE_BUILD_NUMBER_IN_CURRENT_DAEMON, DaemonReuseCounter.incrementAndGetOrdinal())
}
}
internal fun reportBuildFinished(
logger: Logger,
buildFailed: Boolean,
buildStartedTime: Long?,
projectEvaluatedTime: Long?,
metricsContainer: NonSynchronizedMetricsContainer,
) {
runMetricMethodSafely(logger, "reportBuildFinish") {
val finishTime = System.currentTimeMillis()
if (buildStartedTime != null) {
metricsContainer.report(NumericalMetrics.GRADLE_BUILD_DURATION, finishTime - buildStartedTime)
}
if (projectEvaluatedTime != null) {
metricsContainer.report(NumericalMetrics.GRADLE_EXECUTION_DURATION, finishTime - projectEvaluatedTime)
}
metricsContainer.report(NumericalMetrics.BUILD_FINISH_TIME, finishTime)
metricsContainer.report(BooleanMetrics.BUILD_FAILED, buildFailed)
}
}
internal fun getMetricToReport(task: String) = when (task.substringAfterLast(":")) {
"dokkaHtml" -> BooleanMetrics.ENABLED_DOKKA_HTML
"dokkaGfm" -> BooleanMetrics.ENABLED_DOKKA_GFM
"dokkaJavadoc" -> BooleanMetrics.ENABLED_DOKKA_JAVADOC
"dokkaJekyll" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL
"dokkaHtmlMultiModule" -> BooleanMetrics.ENABLED_DOKKA_HTML_MULTI_MODULE
"dokkaGfmMultiModule" -> BooleanMetrics.ENABLED_DOKKA_GFM_MULTI_MODULE
"dokkaJekyllMultiModule" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL_MULTI_MODULE
"dokkaHtmlCollector" -> BooleanMetrics.ENABLED_DOKKA_HTML_COLLECTOR
"dokkaGfmCollector" -> BooleanMetrics.ENABLED_DOKKA_GFM_COLLECTOR
"dokkaJavadocCollector" -> BooleanMetrics.ENABLED_DOKKA_JAVADOC_COLLECTOR
"dokkaJekyllCollector" -> BooleanMetrics.ENABLED_DOKKA_JEKYLL_COLLECTOR
else -> null
}
@@ -10,8 +10,8 @@ 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.UrlRepoConfigurationMetrics
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
@@ -78,7 +78,7 @@ abstract class AbstractSetupTask<Env : AbstractEnv, Settings : AbstractSettings<
val downloadDuration = System.currentTimeMillis() - startDownloadTime
if (downloadDuration > 0) {
buildFusService.orNull?.reportFusMetrics { metricsConsumer ->
metricsConsumer.report(NumericalMetrics.ARTIFACTS_DOWNLOAD_SPEED, it.length() * 1000 / downloadDuration)
UrlRepoConfigurationMetrics.collectMetrics(it.length(), downloadDuration, metricsConsumer)
}
}
}
@@ -14,19 +14,15 @@ import org.gradle.api.tasks.*
import org.gradle.work.NormalizeLineEndings
import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptionsDefault
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.ContributeCompilerArgumentsContext
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.statistics.CompileKotlinJsIrLinkMetrics
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
import org.jetbrains.kotlin.gradle.utils.configureExperimentalTryNext
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import javax.inject.Inject
@CacheableTask
@@ -120,16 +116,7 @@ abstract class KotlinJsIrLink @Inject constructor(
override fun processArgsBeforeCompile(args: K2JSCompilerArguments) {
buildFusService.orNull?.reportFusMetrics {
it.report(BooleanMetrics.JS_IR_INCREMENTAL, incrementalJsIr)
val newArgs = K2JSCompilerArguments()
parseCommandLineArguments(ArgumentUtils.convertArgumentsToStringList(args), newArgs)
it.report(
StringMetrics.JS_OUTPUT_GRANULARITY,
if (newArgs.irPerModule)
KotlinJsIrOutputGranularity.PER_MODULE.name.toLowerCaseAsciiOnly()
else
KotlinJsIrOutputGranularity.WHOLE_PROGRAM.name.toLowerCaseAsciiOnly()
)
CompileKotlinJsIrLinkMetrics.collectMetrics(args, incrementalJsIr, it)
}
}
@@ -7,15 +7,14 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.DeprecatedTargetPresetApi
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
import org.jetbrains.kotlin.gradle.plugin.AbstractKotlinTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.KotlinOnlyTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCompilationFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinOnlyTargetPreset
import org.jetbrains.kotlin.gradle.utils.addConfigurationMetrics
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinJsIrTargetMetrics
@DeprecatedTargetPresetApi
open class KotlinJsIrTargetPreset(
@@ -32,15 +31,11 @@ open class KotlinJsIrTargetPreset(
return project.objects.newInstance(KotlinJsIrTarget::class.java, project, platformType).apply {
this.isMpp = this@KotlinJsIrTargetPreset.isMpp
project.runProjectConfigurationHealthCheckWhenEvaluated {
project.addConfigurationMetrics {
when {
isBrowserConfigured && isNodejsConfigured -> it.put(StringMetrics.JS_TARGET_MODE, "both")
isBrowserConfigured -> it.put(StringMetrics.JS_TARGET_MODE, "browser")
isNodejsConfigured -> it.put(StringMetrics.JS_TARGET_MODE, "nodejs")
!isBrowserConfigured && !isNodejsConfigured -> it.put(StringMetrics.JS_TARGET_MODE, "none")
}
}
KotlinJsIrTargetMetrics.collectMetrics(
isBrowserConfigured = isBrowserConfigured,
isNodejsConfigured = isNodejsConfigured,
project
)
}
}
}
@@ -17,11 +17,11 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.sources.*
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinMetadataConfigurationMetrics
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadataDependencyClasspath
import org.jetbrains.kotlin.gradle.targets.native.internal.sharedCommonizerTarget
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
@@ -55,7 +55,7 @@ class KotlinMetadataTargetConfigurator :
if (target.project.isKotlinGranularMetadataEnabled) {
target.project.addConfigurationMetrics {
it.put(BooleanMetrics.ENABLED_HMPP, true)
KotlinMetadataConfigurationMetrics.collectMetrics(it)
}
target.compilations.withType(KotlinCommonCompilation::class.java).getByName(KotlinCompilation.MAIN_COMPILATION_NAME).run {
@@ -37,6 +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.NativeCompilerOptionMetrics
import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService
import org.jetbrains.kotlin.gradle.report.*
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
@@ -54,8 +55,6 @@ import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.project.model.LanguageSettings
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import java.io.File
import java.nio.file.Files
@@ -555,7 +554,12 @@ internal constructor(
val output = outputFile.get()
output.parentFile.mkdirs()
collectCommonCompilerStats()
buildFusService.orNull?.use {
it.reportFusMetrics {
NativeCompilerOptionMetrics.collectMetrics(compilerOptions, it)
}
}
ArgumentUtils.convertArgumentsToStringList(arguments)
}
@@ -571,17 +575,6 @@ internal constructor(
private fun resolveLanguageVersion() =
compilerOptions.languageVersion.orNull?.version?.let { v -> KotlinVersion.fromVersion(v) }
private fun collectCommonCompilerStats() {
buildFusService.orNull?.reportFusMetrics {
it.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get())
compilerOptions.apiVersion.orNull?.also { v ->
it.report(StringMetrics.KOTLIN_API_VERSION, v.version)
}
compilerOptions.languageVersion.orNull?.also { v ->
it.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version)
}
}
}
}
internal class ExternalDependenciesBuilder(
@@ -34,12 +34,11 @@ 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.CompileKotlinTaskMetrics
import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService
import org.jetbrains.kotlin.gradle.report.*
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
import java.io.File
import javax.inject.Inject
import org.jetbrains.kotlin.gradle.tasks.cleanOutputsAndLocalState as cleanOutputsAndLocalStateUtil
@@ -232,13 +231,9 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
buildMetrics.addTimeMetric(GradleBuildPerformanceMetric.START_TASK_ACTION_EXECUTION)
buildMetrics.measure(GradleBuildTime.OUT_OF_WORKER_TASK_ACTION) {
buildFusService.orNull?.reportFusMetrics {
if (name.contains("Test"))
it.report(BooleanMetrics.TESTS_EXECUTED, true)
else
it.report(BooleanMetrics.COMPILATION_STARTED, true)
CompileKotlinTaskMetrics.collectMetrics(name, compilerOptions, it)
}
validateCompilerClasspath()
collectCommonCompilerStats()
systemPropertiesService.get().startIntercept()
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
@@ -272,18 +267,6 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments> @Inject constr
buildMetricsService.orNull?.also { it.addTask(path, this.javaClass, buildMetrics) }
}
private fun collectCommonCompilerStats() {
buildFusService.orNull?.reportFusMetrics {
it.report(BooleanMetrics.KOTLIN_PROGRESSIVE_MODE, compilerOptions.progressiveMode.get())
compilerOptions.apiVersion.orNull?.also { v ->
it.report(StringMetrics.KOTLIN_API_VERSION, v.version)
}
compilerOptions.languageVersion.orNull?.also { v ->
it.report(StringMetrics.KOTLIN_LANGUAGE_VERSION, v.version)
}
}
}
protected open fun cleanOutputsAndLocalState(reason: String?) {
cleanOutputsAndLocalStateUtil(reason)
}
@@ -30,6 +30,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.CompileKotlinJsTaskMetrics
import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService
import org.jetbrains.kotlin.gradle.report.BuildReportMode
import org.jetbrains.kotlin.gradle.targets.js.internal.LibraryFilterCachingService
@@ -40,7 +41,6 @@ import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import org.jetbrains.kotlin.incremental.ClasspathChanges
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import java.io.File
import javax.inject.Inject
@@ -70,11 +70,7 @@ abstract class Kotlin2JsCompile @Inject constructor(
internal var incrementalJsKlib: Boolean = true
override fun isIncrementalCompilationEnabled(): Boolean {
val result = incrementalJsKlib || incremental
buildFusService.orNull?.reportFusMetrics {
it.report(BooleanMetrics.JS_KLIB_INCREMENTAL, result)
}
return result
return incrementalJsKlib || incremental
}
// Workaround to be able to use default value and change it later based on external input
@@ -271,6 +267,10 @@ abstract class Kotlin2JsCompile @Inject constructor(
)
} else null
buildFusService.orNull?.reportFusMetrics {
CompileKotlinJsTaskMetrics.collectMetrics(icEnv != null, it)
}
val environment = GradleCompilerEnvironment(
defaultCompilerClasspath, gradleMessageCollector, outputItemCollector,
outputFiles = allOutputFiles(),