KT-57371: Add versions for FUS statistic bean
This commit is contained in:
committed by
Space Team
parent
caa7bee917
commit
2c2a01113e
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("Build FUS statistics")
|
||||
class BuildFusStatisticsIT : KGPBaseTest() {
|
||||
@JvmGradlePluginTests
|
||||
@DisplayName("works for project with buildSrc and kotlinDsl plugin")
|
||||
@GradleTest
|
||||
fun testCompatibilityBuildSrcWithKotlinDsl(gradleVersion: GradleVersion) {
|
||||
project(
|
||||
"buildSrcUsingKotlinCompilationAndKotlinPlugin",
|
||||
gradleVersion,
|
||||
buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
|
||||
) {
|
||||
build("assemble") {
|
||||
//register build service for buildSrc.
|
||||
assertOutputContains("Instantiated class org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService: new instance")
|
||||
assertOutputContains("Instantiated class org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService_v2: new instance")
|
||||
//kotlin 1.4 in kotlinDsl does not create jmx service yet
|
||||
assertOutputContains("Register JMX service for backward compatibility")
|
||||
assertOutputDoesNotContain("[org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatHandler] Could not execute")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -358,7 +358,7 @@ fun Project.getKotlinPluginVersion() = getKotlinPluginVersion(project.logger)
|
||||
fun getKotlinPluginVersion(logger: Logger): String {
|
||||
if (!kotlinPluginVersionFromResources.isInitialized()) {
|
||||
logger.kotlinDebug("Loading version information")
|
||||
logger.kotlinDebug("Found project version [${kotlinPluginVersionFromResources.value}")
|
||||
logger.kotlinDebug("Found project version [${kotlinPluginVersionFromResources.value}]")
|
||||
}
|
||||
return kotlinPluginVersionFromResources.value
|
||||
}
|
||||
|
||||
+16
-8
@@ -49,13 +49,24 @@ class KotlinBuildStatHandler {
|
||||
}
|
||||
|
||||
fun buildFinished(
|
||||
beanName: ObjectName,
|
||||
) {
|
||||
runSafe("${KotlinBuildStatHandler::class.java}.buildFinished") {
|
||||
val mbs: MBeanServer = ManagementFactory.getPlatformMBeanServer()
|
||||
if (mbs.isRegistered(beanName)) {
|
||||
mbs.unregisterMBean(beanName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun reportGlobalMetricsAndBuildFinished(
|
||||
gradle: Gradle?,
|
||||
beanName: ObjectName,
|
||||
sessionLogger: BuildSessionLogger,
|
||||
action: String?,
|
||||
failure: Throwable?
|
||||
) {
|
||||
runSafe("${KotlinBuildStatHandler::class.java}.buildFinished") {
|
||||
runSafe("${KotlinBuildStatHandler::class.java}.reportGlobalMetrics") {
|
||||
try {
|
||||
try {
|
||||
if (gradle != null) reportGlobalMetrics(gradle, sessionLogger)
|
||||
@@ -63,10 +74,7 @@ class KotlinBuildStatHandler {
|
||||
sessionLogger.finishBuildSession(action, failure)
|
||||
}
|
||||
} finally {
|
||||
val mbs: MBeanServer = ManagementFactory.getPlatformMBeanServer()
|
||||
if (mbs.isRegistered(beanName)) {
|
||||
mbs.unregisterMBean(beanName)
|
||||
}
|
||||
buildFinished(beanName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +223,7 @@ class KotlinBuildStatHandler {
|
||||
weight: Long? = null
|
||||
) = runSafe("report metric ${metric.name}") {
|
||||
sessionLogger.report(metric, value, subprojectName, weight)
|
||||
} as? Boolean ?: false
|
||||
} ?: false
|
||||
|
||||
internal fun report(
|
||||
sessionLogger: BuildSessionLogger,
|
||||
@@ -224,6 +232,6 @@ class KotlinBuildStatHandler {
|
||||
subprojectName: String?,
|
||||
weight: Long? = null
|
||||
) = runSafe("report metric ${metric.name}") {
|
||||
sessionLogger.report(metric, value, subprojectName, weight)
|
||||
} as? Boolean ?: false
|
||||
sessionLogger.report(metric, value, subprojectName, weight)
|
||||
} ?: false
|
||||
}
|
||||
|
||||
+46
-47
@@ -9,10 +9,13 @@ import org.gradle.BuildAdapter
|
||||
import org.gradle.BuildResult
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.initialization.BuildRequestMetaData
|
||||
import org.gradle.invocation.DefaultGradle
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatHandler.Companion.runSafe
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.old.Pre232IdeaKotlinBuildStatsMXBean
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.old.Pre232IdeaKotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||
import org.jetbrains.kotlin.statistics.BuildSessionLogger
|
||||
import org.jetbrains.kotlin.statistics.BuildSessionLogger.Companion.STATISTICS_FOLDER_NAME
|
||||
@@ -32,27 +35,25 @@ import kotlin.system.measureTimeMillis
|
||||
* JMX could be used for reporting both from other JVMs, other versions
|
||||
* of Kotlin Plugin and other classloaders
|
||||
*/
|
||||
|
||||
interface KotlinBuildStatsMXBean {
|
||||
fun reportBoolean(name: String, value: Boolean, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
fun reportNumber(name: String, value: Long, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
fun reportString(name: String, value: String, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
//support Idea up to 2023.1 version, before KT-57371 fix
|
||||
|
||||
fun reportBoolean(name: String, value: Boolean, subprojectName: String?): Boolean
|
||||
|
||||
fun reportNumber(name: String, value: Long, subprojectName: String?): Boolean
|
||||
|
||||
fun reportString(name: String, value: String, subprojectName: String?): Boolean
|
||||
}
|
||||
|
||||
|
||||
internal abstract class KotlinBuildStatsService internal constructor() : BuildAdapter(), IStatisticsValuesConsumer {
|
||||
companion object {
|
||||
// Do not rename this bean otherwise compatibility with the older Kotlin Gradle Plugins would be lost
|
||||
const val JMX_BEAN_NAME = "org.jetbrains.kotlin.gradle.plugin.statistics:type=StatsService"
|
||||
private const val JMX_BEAN_NAME_BEFORE_232_IDEA = "org.jetbrains.kotlin.gradle.plugin.statistics:type=StatsService"
|
||||
|
||||
//update name when API changed
|
||||
private const val SERVICE_NAME = "v2"
|
||||
const val JMX_BEAN_NAME = "org.jetbrains.kotlin.gradle.plugin.statistics:type=StatsService,name=$SERVICE_NAME"
|
||||
|
||||
|
||||
// Property name for disabling saving statistical information
|
||||
const val ENABLE_STATISTICS_PROPERTY_NAME = "enable_kotlin_performance_profile"
|
||||
@@ -80,6 +81,8 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
|
||||
return instance
|
||||
}
|
||||
|
||||
private fun getServiceName(): String = "${KotlinBuildStatsService::class.java}_$SERVICE_NAME"
|
||||
|
||||
/**
|
||||
* Method for creating new instance of IStatisticsValuesConsumer
|
||||
* It could be invoked only when applying Kotlin gradle plugin.
|
||||
@@ -106,21 +109,23 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
|
||||
val log = getLogger()
|
||||
|
||||
if (instance != null) {
|
||||
log.debug("${KotlinBuildStatsService::class.java} is already instantiated. Current instance is $instance")
|
||||
log.debug("${getServiceName()} is already instantiated. Current instance is $instance")
|
||||
} else {
|
||||
val beanName = ObjectName(JMX_BEAN_NAME)
|
||||
val mbs: MBeanServer = ManagementFactory.getPlatformMBeanServer()
|
||||
if (mbs.isRegistered(beanName)) {
|
||||
log.debug(
|
||||
"${KotlinBuildStatsService::class.java} is already instantiated in another classpath. Creating JMX-wrapper"
|
||||
"${getServiceName()} is already instantiated in another classpath. Creating JMX-wrapper"
|
||||
)
|
||||
instance = JMXKotlinBuildStatsService(mbs, beanName)
|
||||
} else {
|
||||
val newInstance = DefaultKotlinBuildStatsService(gradle, beanName)
|
||||
|
||||
instance = newInstance
|
||||
log.debug("Instantiated ${KotlinBuildStatsService::class.java}: new instance $instance")
|
||||
log.debug("Instantiated ${getServiceName()}: new instance $instance")
|
||||
mbs.registerMBean(StandardMBean(newInstance, KotlinBuildStatsMXBean::class.java), beanName)
|
||||
|
||||
registerPre232IdeaStatsBean(mbs, gradle, log)
|
||||
}
|
||||
|
||||
if (!isConfigurationCacheAvailable(gradle)) {
|
||||
@@ -132,6 +137,17 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
|
||||
}
|
||||
}
|
||||
|
||||
//To support backward compatibility with Idea before 232 version
|
||||
private fun registerPre232IdeaStatsBean(mbs: MBeanServer, gradle: Gradle, log: Logger) {
|
||||
val beanName = ObjectName(JMX_BEAN_NAME_BEFORE_232_IDEA)
|
||||
if (!mbs.isRegistered(beanName)) {
|
||||
val newInstance = Pre232IdeaKotlinBuildStatsService(gradle, beanName)
|
||||
mbs.registerMBean(StandardMBean(newInstance, Pre232IdeaKotlinBuildStatsMXBean::class.java), beanName)
|
||||
log.debug("Register JMX service for backward compatibility")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invokes provided collector if the reporting service is initialised.
|
||||
* The duration of collector's wall time is reported into overall overhead metric.
|
||||
@@ -173,7 +189,7 @@ internal abstract class KotlinBuildStatsService internal constructor() : BuildAd
|
||||
internal class JMXKotlinBuildStatsService(private val mbs: MBeanServer, private val beanName: ObjectName) :
|
||||
KotlinBuildStatsService() {
|
||||
|
||||
private fun callJmx_v2(method: String, type: String, metricName: String, value: Any, subprojectName: String?, weight: Long): Any? {
|
||||
private fun callJmx(method: String, type: String, metricName: String, value: Any, subprojectName: String?, weight: Long?): Any? {
|
||||
return mbs.invoke(
|
||||
beanName,
|
||||
method,
|
||||
@@ -182,24 +198,6 @@ internal class JMXKotlinBuildStatsService(private val mbs: MBeanServer, private
|
||||
)
|
||||
}
|
||||
|
||||
private fun callJmx_v1(method: String, type: String, metricName: String, value: Any, subprojectName: String?): Any? {
|
||||
return mbs.invoke(
|
||||
beanName,
|
||||
method,
|
||||
arrayOf(metricName, value, subprojectName),
|
||||
arrayOf("java.lang.String", type, "java.lang.String")
|
||||
)
|
||||
}
|
||||
|
||||
//Temporary solution before KT-57371
|
||||
private fun callJmx(method: String, type: String, metricName: String, value: Any, subprojectName: String?, weight: Long?): Any? {
|
||||
return if (weight == null) {
|
||||
callJmx_v1(method, type, metricName, value, subprojectName)
|
||||
} else {
|
||||
callJmx_v2(method, type, metricName, value, subprojectName, weight)
|
||||
}
|
||||
}
|
||||
|
||||
override fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String?, weight: Long?) =
|
||||
runSafe("report metric ${metric.name}") {
|
||||
callJmx("reportBoolean", "boolean", metric.name, value, subprojectName, weight)
|
||||
@@ -220,16 +218,16 @@ internal class JMXKotlinBuildStatsService(private val mbs: MBeanServer, private
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultKotlinBuildStatsService internal constructor(
|
||||
internal abstract class AbstractKotlinBuildStatsService(
|
||||
gradle: Gradle,
|
||||
val beanName: ObjectName
|
||||
) : KotlinBuildStatsService(), KotlinBuildStatsMXBean {
|
||||
protected val beanName: ObjectName
|
||||
) : KotlinBuildStatsService() {
|
||||
private val forcePropertiesValidation = if (gradle.rootProject.hasProperty(FORCE_VALUES_VALIDATION)) {
|
||||
gradle.rootProject.property(FORCE_VALUES_VALIDATION).toString().toBoolean()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
private val sessionLogger = BuildSessionLogger(gradle.gradleUserHomeDir, forceValuesValidation = forcePropertiesValidation)
|
||||
protected val sessionLogger = BuildSessionLogger(gradle.gradleUserHomeDir, forceValuesValidation = forcePropertiesValidation)
|
||||
|
||||
private fun gradleBuildStartTime(gradle: Gradle): Long? {
|
||||
return (gradle as? DefaultGradle)?.services?.get(BuildRequestMetaData::class.java)?.startTime
|
||||
@@ -248,9 +246,15 @@ internal class DefaultKotlinBuildStatsService internal constructor(
|
||||
|
||||
@Synchronized
|
||||
override fun buildFinished(result: BuildResult) {
|
||||
KotlinBuildStatHandler().buildFinished(result.gradle, beanName, sessionLogger, result.action, result.failure)
|
||||
KotlinBuildStatHandler().buildFinished(beanName)
|
||||
instance = null
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultKotlinBuildStatsService internal constructor(
|
||||
gradle: Gradle,
|
||||
beanName: ObjectName
|
||||
) : AbstractKotlinBuildStatsService(gradle, beanName), KotlinBuildStatsMXBean {
|
||||
|
||||
override fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String?, weight: Long?): Boolean =
|
||||
KotlinBuildStatHandler().report(sessionLogger, metric, value, subprojectName, weight)
|
||||
@@ -270,15 +274,10 @@ internal class DefaultKotlinBuildStatsService internal constructor(
|
||||
override fun reportString(name: String, value: String, subprojectName: String?, weight: Long?): Boolean =
|
||||
report(StringMetrics.valueOf(name), value, subprojectName, weight)
|
||||
|
||||
override fun reportBoolean(name: String, value: Boolean, subprojectName: String?): Boolean =
|
||||
report(BooleanMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
|
||||
override fun reportNumber(name: String, value: Long, subprojectName: String?): Boolean =
|
||||
report(NumericalMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
|
||||
override fun reportString(name: String, value: String, subprojectName: String?): Boolean =
|
||||
report(StringMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
//only one jmx bean service should report global metrics
|
||||
@Synchronized
|
||||
override fun buildFinished(result: BuildResult) {
|
||||
KotlinBuildStatHandler().reportGlobalMetricsAndBuildFinished(result.gradle, beanName, sessionLogger, result.action, result.failure)
|
||||
instance = null
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.old
|
||||
|
||||
internal interface Pre232IdeaKotlinBuildStatsMXBean {
|
||||
fun reportBoolean(name: String, value: Boolean, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
fun reportNumber(name: String, value: Long, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
fun reportString(name: String, value: String, subprojectName: String?, weight: Long?): Boolean
|
||||
|
||||
fun reportBoolean(name: String, value: Boolean, subprojectName: String?): Boolean
|
||||
|
||||
fun reportNumber(name: String, value: Long, subprojectName: String?): Boolean
|
||||
|
||||
fun reportString(name: String, value: String, subprojectName: String?): Boolean
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.old
|
||||
|
||||
import org.gradle.api.invocation.Gradle
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.AbstractKotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatHandler
|
||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||
import org.jetbrains.kotlin.statistics.metrics.NumericalMetrics
|
||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||
import javax.management.ObjectName
|
||||
|
||||
internal class Pre232IdeaKotlinBuildStatsService internal constructor(
|
||||
gradle: Gradle,
|
||||
beanName: ObjectName
|
||||
) : AbstractKotlinBuildStatsService(gradle, beanName), Pre232IdeaKotlinBuildStatsMXBean {
|
||||
|
||||
override fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String?, weight: Long?): Boolean =
|
||||
KotlinBuildStatHandler().report(sessionLogger, metric, value, subprojectName, weight)
|
||||
|
||||
override fun report(metric: NumericalMetrics, value: Long, subprojectName: String?, weight: Long?): Boolean =
|
||||
KotlinBuildStatHandler().report(sessionLogger, metric, value, subprojectName, weight)
|
||||
|
||||
override fun report(metric: StringMetrics, value: String, subprojectName: String?, weight: Long?): Boolean =
|
||||
KotlinBuildStatHandler().report(sessionLogger, metric, value, subprojectName, weight)
|
||||
|
||||
override fun reportBoolean(name: String, value: Boolean, subprojectName: String?, weight: Long?): Boolean =
|
||||
report(BooleanMetrics.valueOf(name), value, subprojectName, weight)
|
||||
|
||||
override fun reportNumber(name: String, value: Long, subprojectName: String?, weight: Long?): Boolean =
|
||||
report(NumericalMetrics.valueOf(name), value, subprojectName, weight)
|
||||
|
||||
override fun reportString(name: String, value: String, subprojectName: String?, weight: Long?): Boolean =
|
||||
report(StringMetrics.valueOf(name), value, subprojectName, weight)
|
||||
|
||||
override fun reportBoolean(name: String, value: Boolean, subprojectName: String?): Boolean =
|
||||
report(BooleanMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
|
||||
override fun reportNumber(name: String, value: Long, subprojectName: String?): Boolean =
|
||||
report(NumericalMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
|
||||
override fun reportString(name: String, value: String, subprojectName: String?): Boolean =
|
||||
report(StringMetrics.valueOf(name), value, subprojectName, null)
|
||||
|
||||
}
|
||||
-15
@@ -50,21 +50,6 @@ class BuildStatServiceTest {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun reportBoolean(name: String, value: Boolean, subprojectName: String?): Boolean {
|
||||
callsCount.incrementAndGet()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun reportNumber(name: String, value: Long, subprojectName: String?): Boolean {
|
||||
callsCount.incrementAndGet()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun reportString(name: String, value: String, subprojectName: String?): Boolean {
|
||||
callsCount.incrementAndGet()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val beanName = ObjectName(KotlinBuildStatsService.JMX_BEAN_NAME)
|
||||
|
||||
-12
@@ -5,18 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.statistics.metrics
|
||||
|
||||
interface ReportStatisticsValue<T> {
|
||||
val name: String
|
||||
val value: T
|
||||
}
|
||||
|
||||
class ReportOnceStatisticsValue<T>(override val name: String, override val value: T) :
|
||||
ReportStatisticsValue<T>
|
||||
|
||||
interface AdditiveStatisticsValue<T> : ReportStatisticsValue<T> {
|
||||
fun addValue(t: T)
|
||||
}
|
||||
|
||||
interface IStatisticsValuesConsumer {
|
||||
fun report(metric: BooleanMetrics, value: Boolean, subprojectName: String? = null, weight: Long? = null): Boolean
|
||||
|
||||
|
||||
Reference in New Issue
Block a user