send build stat to ES
This commit is contained in:
@@ -36,6 +36,12 @@ enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess
|
|||||||
KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"),
|
KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"),
|
||||||
COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS("kotlin.daemon.custom.run.files.path.for.tests"),
|
COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS("kotlin.daemon.custom.run.files.path.for.tests"),
|
||||||
KOTLIN_COLORS_ENABLED_PROPERTY("kotlin.colors.enabled"),
|
KOTLIN_COLORS_ENABLED_PROPERTY("kotlin.colors.enabled"),
|
||||||
|
|
||||||
|
KOTLIN_STAT_ENABLED_PROPERTY("kotlin.plugin.stat.enabled"),
|
||||||
|
KOTLIN_STAT_ENDPOINT_PROPERTY("kotlin.plugin.stat.endpoint"),
|
||||||
|
KOTLIN_STAT_USER_PROPERTY("kotlin.plugin.stat.user"),
|
||||||
|
KOTLIN_STAT_PASSWORD_PROPERTY("kotlin.plugin.stat.password"),
|
||||||
|
|
||||||
OS_NAME("os.name", alwaysDirectAccess = true),
|
OS_NAME("os.name", alwaysDirectAccess = true),
|
||||||
TMP_DIR("java.io.tmpdir"),
|
TMP_DIR("java.io.tmpdir"),
|
||||||
USER_HOME("user.home", alwaysDirectAccess = true),
|
USER_HOME("user.home", alwaysDirectAccess = true),
|
||||||
|
|||||||
+6
@@ -13,6 +13,7 @@ import org.gradle.api.logging.Logging
|
|||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||||
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
|
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
|
||||||
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildEsStatListener
|
||||||
import org.jetbrains.kotlin.gradle.report.configureReporting
|
import org.jetbrains.kotlin.gradle.report.configureReporting
|
||||||
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable
|
||||||
|
|
||||||
@@ -64,6 +65,9 @@ internal class KotlinGradleBuildServices private constructor(
|
|||||||
val kotlinGradleListenerProvider: org.gradle.api.provider.Provider<KotlinGradleBuildListener> = project.provider {
|
val kotlinGradleListenerProvider: org.gradle.api.provider.Provider<KotlinGradleBuildListener> = project.provider {
|
||||||
KotlinGradleBuildListener(KotlinGradleFinishBuildHandler())
|
KotlinGradleBuildListener(KotlinGradleFinishBuildHandler())
|
||||||
}
|
}
|
||||||
|
val kotlinGradleEsListenerProvider = project.provider {
|
||||||
|
KotlinBuildEsStatListener(project.name)
|
||||||
|
}
|
||||||
|
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
log.kotlinDebug(ALREADY_INITIALIZED_MESSAGE)
|
log.kotlinDebug(ALREADY_INITIALIZED_MESSAGE)
|
||||||
@@ -74,6 +78,7 @@ internal class KotlinGradleBuildServices private constructor(
|
|||||||
val services = KotlinGradleBuildServices(gradle)
|
val services = KotlinGradleBuildServices(gradle)
|
||||||
if (isConfigurationCacheAvailable(gradle)) {
|
if (isConfigurationCacheAvailable(gradle)) {
|
||||||
listenerRegistryHolder.listenerRegistry!!.onTaskCompletion(kotlinGradleListenerProvider)
|
listenerRegistryHolder.listenerRegistry!!.onTaskCompletion(kotlinGradleListenerProvider)
|
||||||
|
listenerRegistryHolder.listenerRegistry.onTaskCompletion(kotlinGradleEsListenerProvider)
|
||||||
} else {
|
} else {
|
||||||
gradle.addBuildListener(services)
|
gradle.addBuildListener(services)
|
||||||
log.kotlinDebug(INIT_MESSAGE)
|
log.kotlinDebug(INIT_MESSAGE)
|
||||||
@@ -103,6 +108,7 @@ internal class KotlinGradleBuildServices private constructor(
|
|||||||
|
|
||||||
override fun buildFinished(result: BuildResult) {
|
override fun buildFinished(result: BuildResult) {
|
||||||
buildHandler!!.buildFinished(result.gradle!!)
|
buildHandler!!.buildFinished(result.gradle!!)
|
||||||
|
KotlinBuildEsStatListener(result.gradle!!.rootProject.name).onFinish(result)
|
||||||
instance = null
|
instance = null
|
||||||
log.kotlinDebug(DISPOSE_MESSAGE)
|
log.kotlinDebug(DISPOSE_MESSAGE)
|
||||||
}
|
}
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.BuildResult
|
||||||
|
import org.gradle.tooling.events.FinishEvent
|
||||||
|
import org.gradle.tooling.events.OperationCompletionListener
|
||||||
|
import org.gradle.tooling.events.task.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.stat.CompileStatData
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.stat.ReportStatistics
|
||||||
|
|
||||||
|
class KotlinBuildEsStatListener(val projectName: String) : OperationCompletionListener, AutoCloseable {
|
||||||
|
val reportStatistics: ReportStatistics = ReportStatisticsToElasticSearch
|
||||||
|
|
||||||
|
override fun onFinish(event: FinishEvent?) {
|
||||||
|
if (event is TaskFinishEvent) {
|
||||||
|
val result = event.result
|
||||||
|
val taskPath = event.descriptor.taskPath
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildTime.children.forEach()
|
||||||
|
|
||||||
|
val compileStatData = CompileStatData(
|
||||||
|
duration = event.result.endTime - event.result.startTime, taskResult = taskResult,
|
||||||
|
statData = emptyMap(), projectName = projectName, taskName = taskPath
|
||||||
|
)
|
||||||
|
reportStatistics.report(compileStatData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onFinish(result: BuildResult) {
|
||||||
|
// onFinish(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun close() {
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.stat
|
||||||
|
|
||||||
|
data class CompileStatData(
|
||||||
|
val version: Int = 1,
|
||||||
|
val projectName: String?,
|
||||||
|
val taskName: String?,
|
||||||
|
val taskResult: String,
|
||||||
|
val duration: Long,
|
||||||
|
val statData: Map<String, Long>
|
||||||
|
)
|
||||||
|
|
||||||
|
interface ReportStatistics {
|
||||||
|
fun report(data: CompileStatData)
|
||||||
|
}
|
||||||
|
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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 com.google.gson.Gson
|
||||||
|
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
||||||
|
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.stat.ReportStatistics
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.stat.CompileStatData
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
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
|
||||||
|
|
||||||
|
//TODO Do not store password as string
|
||||||
|
val password = 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()
|
||||||
|
.encode("$user:$password".toByteArray()).toString(Charsets.UTF_8)
|
||||||
|
connection.addRequestProperty("Authorization", "Basic $auth")
|
||||||
|
}
|
||||||
|
connection.addRequestProperty("Content-Type", "application/json")
|
||||||
|
connection.requestMethod = "POST"
|
||||||
|
connection.doOutput = true
|
||||||
|
connection.outputStream.use {
|
||||||
|
it.write(Gson().toJson(data).toByteArray())
|
||||||
|
}
|
||||||
|
connection.connect();
|
||||||
|
checkResponseAndLog(connection)
|
||||||
|
connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
|
||||||
|
} finally {
|
||||||
|
connection.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkResponseAndLog(connection: HttpURLConnection) {
|
||||||
|
val isResponseBad = connection.responseCode !in 200..299
|
||||||
|
if (isResponseBad) {
|
||||||
|
throw Exception(
|
||||||
|
"Failed to send statistic to ${connection.url}: ${connection.responseMessage}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user