diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt index 987a897933c..3dece2fbed8 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt @@ -41,6 +41,7 @@ enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess KOTLIN_STAT_ENDPOINT_PROPERTY("kotlin.plugin.stat.endpoint"), KOTLIN_STAT_USER_PROPERTY("kotlin.plugin.stat.user"), KOTLIN_STAT_PASSWORD_PROPERTY("kotlin.plugin.stat.password"), + KOTLIN_STAT_LABEl_PROPERTY("kotlin.plugin.stat.label"), OS_NAME("os.name", alwaysDirectAccess = true), TMP_DIR("java.io.tmpdir"), diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt index f855f14b76b..c9485806c39 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleBuildServices.kt @@ -66,7 +66,7 @@ internal class KotlinGradleBuildServices private constructor( KotlinGradleBuildListener(KotlinGradleFinishBuildHandler()) } val kotlinGradleEsListenerProvider = project.provider { - KotlinBuildEsStatListener(project.name) + KotlinBuildEsStatListener(project.rootProject.name) } if (instance != null) { @@ -81,6 +81,7 @@ internal class KotlinGradleBuildServices private constructor( listenerRegistryHolder.listenerRegistry.onTaskCompletion(kotlinGradleEsListenerProvider) } else { gradle.addBuildListener(services) + gradle.taskGraph.addTaskExecutionListener(kotlinGradleEsListenerProvider.get()) log.kotlinDebug(INIT_MESSAGE) } instance = services @@ -108,7 +109,6 @@ internal class KotlinGradleBuildServices private constructor( override fun buildFinished(result: BuildResult) { buildHandler!!.buildFinished(result.gradle!!) - KotlinBuildEsStatListener(result.gradle!!.rootProject.name).onFinish(result) instance = null log.kotlinDebug(DISPOSE_MESSAGE) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildEsStatListener.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildEsStatListener.kt index a404310ee9a..5d3eb5d9f32 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildEsStatListener.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/KotlinBuildEsStatListener.kt @@ -5,42 +5,80 @@ package org.jetbrains.kotlin.gradle.plugin.statistics -import org.gradle.BuildResult +import org.gradle.api.Task +import org.gradle.api.execution.TaskExecutionListener +import org.gradle.api.tasks.TaskState import org.gradle.tooling.events.FinishEvent import org.gradle.tooling.events.OperationCompletionListener import org.gradle.tooling.events.task.* +import org.jetbrains.kotlin.cli.common.CompilerSystemProperties +import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults import org.jetbrains.kotlin.gradle.plugin.stat.CompileStatData import org.jetbrains.kotlin.gradle.plugin.stat.ReportStatistics -class KotlinBuildEsStatListener(val projectName: String) : OperationCompletionListener, AutoCloseable { +enum class TaskExecutionState { + SKIPPED, + FAILED, + UNKNOWN, + SUCCESS, + FROM_CACHE, + UP_TO_DATE + ; +} + +class KotlinBuildEsStatListener(val projectName: String) : OperationCompletionListener, AutoCloseable, TaskExecutionListener { val reportStatistics: ReportStatistics = ReportStatisticsToElasticSearch + val label by lazy { CompilerSystemProperties.KOTLIN_STAT_LABEl_PROPERTY.value } + override fun onFinish(event: FinishEvent?) { if (event is TaskFinishEvent) { val result = event.result val taskPath = event.descriptor.taskPath + val duration = event.result.endTime - event.result.startTime val taskResult = when (result) { - is TaskSuccessResult -> if (result.isFromCache) "FROM CACHE" else if (result.isUpToDate) "UP TO DATE" else "SUCCESS" - is TaskSkippedResult -> "SKIPPED" - is TaskFailureResult -> "FAILED" - else -> "UNKNOWN" + is TaskSuccessResult -> if (result.isFromCache) TaskExecutionState.FROM_CACHE + else if (result.isUpToDate) TaskExecutionState.UP_TO_DATE + else TaskExecutionState.SUCCESS + + is TaskSkippedResult -> TaskExecutionState.SKIPPED + is TaskFailureResult -> TaskExecutionState.FAILED + else -> TaskExecutionState.UNKNOWN } -// BuildTime.children.forEach() - - val compileStatData = CompileStatData( - duration = event.result.endTime - event.result.startTime, taskResult = taskResult, - statData = emptyMap(), projectName = projectName, taskName = taskPath - ) - reportStatistics.report(compileStatData) + reportData(taskPath, duration, taskResult) } } - fun onFinish(result: BuildResult) { -// onFinish(result) + private fun reportData(taskPath: String, duration: Long, taskResult: TaskExecutionState) { + val statData = TaskExecutionResults[taskPath]?.buildMetrics?.buildTimes?.asMap()?.mapKeys { (key, _) -> key.name } ?: emptyMap() + + val compileStatData = CompileStatData( + duration = duration, taskResult = taskResult.name, label = label, + statData = statData, projectName = projectName, taskName = taskPath + ) + reportStatistics.report(compileStatData) } + override fun afterExecute(task: Task, taskState: TaskState) { + val taskResult = when { + taskState.skipped -> TaskExecutionState.SKIPPED + taskState.failure != null -> TaskExecutionState.FAILED + taskState.upToDate -> TaskExecutionState.UP_TO_DATE + taskState.didWork -> TaskExecutionState.SUCCESS + taskState.executed -> TaskExecutionState.FROM_CACHE + else -> TaskExecutionState.UNKNOWN + } + val taskPath = task.path + reportData(taskPath, 0L, taskResult) + } override fun close() { } -} \ No newline at end of file + + override fun beforeExecute(p0: Task) { + //Do nothing + } + +} + diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt index 290ed05e027..498d3485fb6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatistics.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.stat data class CompileStatData( val version: Int = 1, val projectName: String?, + val label: String?, val taskName: String?, val taskResult: String, val duration: Long, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToElasticSearch.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToElasticSearch.kt index b696c8dea84..51af1ecd9c0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToElasticSearch.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/statistics/ReportStatisticsToElasticSearch.kt @@ -15,18 +15,20 @@ import java.net.URL import java.util.* object ReportStatisticsToElasticSearch : ReportStatistics { - val url = CompilerSystemProperties.KOTLIN_STAT_ENDPOINT_PROPERTY.value - val user = CompilerSystemProperties.KOTLIN_STAT_USER_PROPERTY.value - val enable: Boolean = CompilerSystemProperties.KOTLIN_STAT_ENABLED_PROPERTY.value?.toBooleanLenient() ?: false + val url by lazy { CompilerSystemProperties.KOTLIN_STAT_ENDPOINT_PROPERTY.value } + val user by lazy { CompilerSystemProperties.KOTLIN_STAT_USER_PROPERTY.value } + val enable: Boolean by lazy { CompilerSystemProperties.KOTLIN_STAT_ENABLED_PROPERTY.value?.toBooleanLenient() ?: false } //TODO Do not store password as string - val password = CompilerSystemProperties.KOTLIN_STAT_PASSWORD_PROPERTY.value + val password by lazy { CompilerSystemProperties.KOTLIN_STAT_PASSWORD_PROPERTY.value } override fun report(data: CompileStatData) { if (!enable) { return; } + val connection = URL(url).openConnection() as HttpURLConnection + try { if (user != null && password != null) { val auth = Base64.getEncoder() @@ -39,9 +41,11 @@ object ReportStatisticsToElasticSearch : ReportStatistics { connection.outputStream.use { it.write(Gson().toJson(data).toByteArray()) } - connection.connect(); + connection.connect() checkResponseAndLog(connection) connection.inputStream.use { it.reader().use { reader -> reader.readText() } } + } catch (e: Exception) { + checkResponseAndLog(connection) } finally { connection.disconnect() }