send build stat to ES

This commit is contained in:
nataliya.valtman
2021-05-25 13:09:00 +03:00
parent 14a7e90c69
commit 117c99aee6
5 changed files with 136 additions and 0 deletions
@@ -36,6 +36,12 @@ enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess
KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"),
COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS("kotlin.daemon.custom.run.files.path.for.tests"),
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),
TMP_DIR("java.io.tmpdir"),
USER_HOME("user.home", alwaysDirectAccess = true),
@@ -13,6 +13,7 @@ import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults
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.utils.isConfigurationCacheAvailable
@@ -64,6 +65,9 @@ internal class KotlinGradleBuildServices private constructor(
val kotlinGradleListenerProvider: org.gradle.api.provider.Provider<KotlinGradleBuildListener> = project.provider {
KotlinGradleBuildListener(KotlinGradleFinishBuildHandler())
}
val kotlinGradleEsListenerProvider = project.provider {
KotlinBuildEsStatListener(project.name)
}
if (instance != null) {
log.kotlinDebug(ALREADY_INITIALIZED_MESSAGE)
@@ -74,6 +78,7 @@ internal class KotlinGradleBuildServices private constructor(
val services = KotlinGradleBuildServices(gradle)
if (isConfigurationCacheAvailable(gradle)) {
listenerRegistryHolder.listenerRegistry!!.onTaskCompletion(kotlinGradleListenerProvider)
listenerRegistryHolder.listenerRegistry.onTaskCompletion(kotlinGradleEsListenerProvider)
} else {
gradle.addBuildListener(services)
log.kotlinDebug(INIT_MESSAGE)
@@ -103,6 +108,7 @@ 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)
}
@@ -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() {
}
}
@@ -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)
}
@@ -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}"
)
}
}
}