[BT] Add debug logging for compilation iterations

This commit is contained in:
Alexander.Likhachev
2023-10-18 00:28:20 +02:00
committed by Space Team
parent ad4f4cbd28
commit 3eaaed8e7f
7 changed files with 102 additions and 26 deletions
@@ -0,0 +1,32 @@
/*
* 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.buildtools.internal
import org.jetbrains.kotlin.build.report.ICReporter
import org.jetbrains.kotlin.build.report.ICReporterBase
import org.jetbrains.kotlin.buildtools.api.KotlinLogger
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.daemon.common.CompileIterationResult
import java.io.File
internal class BuildToolsApiBuildICReporter(
private val kotlinLogger: KotlinLogger,
private val rootProjectDir: File?,
) : ICReporterBase() {
override fun report(message: () -> String, severity: ICReporter.ReportSeverity) {
when (severity) {
ICReporter.ReportSeverity.DEBUG -> if (kotlinLogger.isDebugEnabled) {
kotlinLogger.debug(message())
}
ICReporter.ReportSeverity.INFO -> kotlinLogger.info(message())
ICReporter.ReportSeverity.WARNING -> kotlinLogger.warn(message())
}
}
override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode) {
kotlinLogger.debug(CompileIterationResult(sourceFiles, exitCode.toString()), rootProjectDir)
}
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.buildtools.internal
import com.intellij.openapi.vfs.impl.ZipHandler import com.intellij.openapi.vfs.impl.ZipHandler
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.report.DoNothingBuildReporter import org.jetbrains.kotlin.build.report.BuildReporter
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
import org.jetbrains.kotlin.buildtools.api.* import org.jetbrains.kotlin.buildtools.api.*
import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity
@@ -139,9 +139,13 @@ internal object CompilationServiceImpl : CompilationService {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val classpathChanges = val classpathChanges =
(aggregatedIcConfiguration as AggregatedIcConfiguration<ClasspathSnapshotBasedIncrementalCompilationApproachParameters>).classpathChanges (aggregatedIcConfiguration as AggregatedIcConfiguration<ClasspathSnapshotBasedIncrementalCompilationApproachParameters>).classpathChanges
val buildReporter = BuildReporter(
icReporter = BuildToolsApiBuildICReporter(loggerAdapter.kotlinLogger, options.rootProjectDir),
buildMetricsReporter = DoNothingBuildMetricsReporter
)
val incrementalCompiler = IncrementalJvmCompilerRunner( val incrementalCompiler = IncrementalJvmCompilerRunner(
aggregatedIcConfiguration.workingDir, aggregatedIcConfiguration.workingDir,
DoNothingBuildReporter, buildReporter,
buildHistoryFile = null, buildHistoryFile = null,
modulesApiHistory = EmptyModulesApiHistory, modulesApiHistory = EmptyModulesApiHistory,
usePreciseJavaTracking = options.preciseJavaTrackingEnabled, usePreciseJavaTracking = options.preciseJavaTrackingEnabled,
@@ -208,7 +212,10 @@ internal object CompilationServiceImpl : CompilationService {
arguments.toTypedArray() + sources.map { it.absolutePath }, // TODO: pass the sources explicitly KT-62759 arguments.toTypedArray() + sources.map { it.absolutePath }, // TODO: pass the sources explicitly KT-62759
daemonCompileOptions, daemonCompileOptions,
BasicCompilerServicesWithResultsFacadeServer(loggerAdapter), BasicCompilerServicesWithResultsFacadeServer(loggerAdapter),
DaemonCompilationResults() DaemonCompilationResults(
loggerAdapter.kotlinLogger,
compilationConfiguration.aggregatedIcConfiguration?.options?.rootProjectDir
)
).get() ).get()
return (ExitCode.entries.find { it.code == exitCode } ?: if (exitCode == 0) { return (ExitCode.entries.find { it.code == exitCode } ?: if (exitCode == 0) {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
internal class KotlinLoggerMessageCollectorAdapter(private val kotlinLogger: KotlinLogger) : MessageCollector { internal class KotlinLoggerMessageCollectorAdapter(internal val kotlinLogger: KotlinLogger) : MessageCollector {
private val messageRenderer = MessageRenderer.GRADLE_STYLE private val messageRenderer = MessageRenderer.GRADLE_STYLE
override fun clear() {} override fun clear() {}
@@ -6,12 +6,12 @@
package org.jetbrains.kotlin.buildtools.internal package org.jetbrains.kotlin.buildtools.internal
import org.jetbrains.kotlin.build.report.metrics.BuildMetrics import org.jetbrains.kotlin.build.report.metrics.BuildMetrics
import org.jetbrains.kotlin.buildtools.api.KotlinLogger
import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.buildtools.api.SourcesChanges
import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalCompilationApproachParameters import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalCompilationApproachParameters
import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration
import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.incremental.ClasspathChanges import java.io.File
import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles
import java.io.Serializable import java.io.Serializable
import java.rmi.server.UnicastRemoteObject import java.rmi.server.UnicastRemoteObject
@@ -19,12 +19,18 @@ internal val JvmCompilationConfigurationImpl.asDaemonCompilationOptions: Compila
get() { get() {
val ktsExtensionsAsArray = if (kotlinScriptFilenameExtensions.isEmpty()) null else kotlinScriptFilenameExtensions.toTypedArray() val ktsExtensionsAsArray = if (kotlinScriptFilenameExtensions.isEmpty()) null else kotlinScriptFilenameExtensions.toTypedArray()
val reportCategories = arrayOf(ReportCategory.COMPILER_MESSAGE.code, ReportCategory.IC_MESSAGE.code) // TODO: automagically compute the value, related to BasicCompilerServicesWithResultsFacadeServer val reportCategories = arrayOf(ReportCategory.COMPILER_MESSAGE.code, ReportCategory.IC_MESSAGE.code) // TODO: automagically compute the value, related to BasicCompilerServicesWithResultsFacadeServer
val reportSeverity = ReportSeverity.INFO.code // TODO: automagically compute the value, related to BasicCompilerServicesWithResultsFacadeServer val reportSeverity = if (logger.isDebugEnabled) {
val requestedCompilationResults = emptyArray<Int>() // TODO: automagically compute the value, related to DaemonCompilationResults ReportSeverity.DEBUG.code
} else {
ReportSeverity.INFO.code
}
val aggregatedIcConfiguration = aggregatedIcConfiguration val aggregatedIcConfiguration = aggregatedIcConfiguration
return when (val options = aggregatedIcConfiguration?.options) { return when (val options = aggregatedIcConfiguration?.options) {
is ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration -> { is ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration -> {
val sourcesChanges = aggregatedIcConfiguration.sourcesChanges val sourcesChanges = aggregatedIcConfiguration.sourcesChanges
val requestedCompilationResults = arrayOf(
CompilationResultCategory.IC_COMPILE_ITERATION.code,
)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val classpathChanges = val classpathChanges =
@@ -57,13 +63,13 @@ internal val JvmCompilationConfigurationImpl.asDaemonCompilationOptions: Compila
targetPlatform = CompileService.TargetPlatform.JVM, targetPlatform = CompileService.TargetPlatform.JVM,
reportCategories = reportCategories, reportCategories = reportCategories,
reportSeverity = reportSeverity, reportSeverity = reportSeverity,
requestedCompilationResults = requestedCompilationResults, requestedCompilationResults = emptyArray(),
kotlinScriptExtensions = ktsExtensionsAsArray, kotlinScriptExtensions = ktsExtensionsAsArray,
) )
} }
} }
internal class DaemonCompilationResults : CompilationResults, internal class DaemonCompilationResults(private val kotlinLogger: KotlinLogger, private val rootProjectDir: File?) : CompilationResults,
UnicastRemoteObject( UnicastRemoteObject(
SOCKET_ANY_FREE_PORT, SOCKET_ANY_FREE_PORT,
LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.clientLoopbackSocketFactory,
@@ -78,7 +84,10 @@ internal class DaemonCompilationResults : CompilationResults,
**/ **/
override fun add(compilationResultCategory: Int, value: Serializable) { override fun add(compilationResultCategory: Int, value: Serializable) {
// TODO propagate the values to the caller via callbacks, requires to make metrics a part of the API // TODO propagate the values to the caller via callbacks, requires to make metrics a part of the API
println("Result category=$compilationResultCategory value=$value") when (compilationResultCategory) {
CompilationResultCategory.IC_COMPILE_ITERATION.code -> kotlinLogger.debug(value as? CompileIterationResult, rootProjectDir)
else -> kotlinLogger.debug("Result category=$compilationResultCategory value=$value")
}
} }
} }
@@ -86,4 +95,20 @@ internal val clientIsAliveFile by lazy {
makeAutodeletingFlagFile() makeAutodeletingFlagFile()
} }
internal fun KotlinLogger.debug(compileIterationResult: CompileIterationResult?, rootProjectDir: File?) {
if (compileIterationResult != null && isDebugEnabled) {
if (compileIterationResult.sourceFiles.any()) {
val sourceFiles = compileIterationResult.sourceFiles
.let { files ->
files.map {
val relativePath = if (rootProjectDir != null) it.relativeToOrNull(rootProjectDir)?.path else null
return@map relativePath ?: it.normalize().absolutePath
}
}
debug("compile iteration: ${sourceFiles.joinToString()}")
}
debug("compiler exit code: ${compileIterationResult.exitCode}")
}
}
internal fun createSessionIsAliveFlagFile() = makeAutodeletingFlagFile(keyword = "compilation-session") internal fun createSessionIsAliveFlagFile() = makeAutodeletingFlagFile(keyword = "compilation-session")
@@ -37,6 +37,8 @@ import java.io.File
import java.rmi.RemoteException import java.rmi.RemoteException
import javax.inject.Inject import javax.inject.Inject
private const val LOGGER_PREFIX = "[KOTLIN] "
internal abstract class BuildToolsApiCompilationWork @Inject constructor( internal abstract class BuildToolsApiCompilationWork @Inject constructor(
private val fileSystemOperations: FileSystemOperations, private val fileSystemOperations: FileSystemOperations,
) : ) :
@@ -59,12 +61,12 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor(
get() = workArguments.taskPath get() = workArguments.taskPath
private val log: KotlinLogger by lazy(LazyThreadSafetyMode.NONE) { private val log: KotlinLogger by lazy(LazyThreadSafetyMode.NONE) {
TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it).apply { debug("Using '$taskPath' logger") } } TaskLoggers.get(taskPath)?.let { GradleKotlinLogger(it, LOGGER_PREFIX).apply { debug("Using '$taskPath' logger") } }
?: run { ?: run {
val logger = LoggerFactory.getLogger("GradleKotlinCompilerWork") val logger = LoggerFactory.getLogger("GradleKotlinCompilerWork")
val kotlinLogger = if (logger is org.gradle.api.logging.Logger) { val kotlinLogger = if (logger is org.gradle.api.logging.Logger) {
GradleKotlinLogger(logger) GradleKotlinLogger(logger, LOGGER_PREFIX)
} else SL4JKotlinLogger(logger) } else SL4JKotlinLogger(logger, LOGGER_PREFIX)
kotlinLogger.apply { kotlinLogger.apply {
debug("Could not get logger for '$taskPath'. Falling back to sl4j logger") debug("Could not get logger for '$taskPath'. Falling back to sl4j logger")
@@ -8,25 +8,30 @@ package org.jetbrains.kotlin.gradle.logging
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.buildtools.api.KotlinLogger import org.jetbrains.kotlin.buildtools.api.KotlinLogger
internal class GradleKotlinLogger(private val log: Logger) : KotlinLogger { internal class GradleKotlinLogger(private val log: Logger, private val prefix: String? = null) : KotlinLogger {
private fun transformMessage(msg: String): String {
if (prefix.isNullOrBlank()) return msg
return prefix + msg
}
override fun debug(msg: String) { override fun debug(msg: String) {
log.debug(msg) log.debug(transformMessage(msg))
} }
override fun error(msg: String, throwable: Throwable?) { override fun error(msg: String, throwable: Throwable?) {
log.error(msg, throwable) log.error(transformMessage(msg), throwable)
} }
override fun info(msg: String) { override fun info(msg: String) {
log.info(msg) log.info(transformMessage(msg))
} }
override fun warn(msg: String) { override fun warn(msg: String) {
log.warn(msg) log.warn(transformMessage(msg))
} }
override fun lifecycle(msg: String) { override fun lifecycle(msg: String) {
log.lifecycle(msg) log.lifecycle(transformMessage(msg))
} }
override val isDebugEnabled: Boolean override val isDebugEnabled: Boolean
@@ -8,25 +8,30 @@ package org.jetbrains.kotlin.gradle.logging
import org.jetbrains.kotlin.buildtools.api.KotlinLogger import org.jetbrains.kotlin.buildtools.api.KotlinLogger
import org.slf4j.Logger import org.slf4j.Logger
internal class SL4JKotlinLogger(private val log: Logger) : KotlinLogger { internal class SL4JKotlinLogger(private val log: Logger, private val prefix: String? = null) : KotlinLogger {
private fun transformMessage(msg: String): String {
if (prefix.isNullOrBlank()) return msg
return prefix + msg
}
override fun debug(msg: String) { override fun debug(msg: String) {
log.debug(msg) log.debug(transformMessage(msg))
} }
override fun lifecycle(msg: String) { override fun lifecycle(msg: String) {
log.info(msg) log.info(transformMessage(msg))
} }
override fun error(msg: String, throwable: Throwable?) { override fun error(msg: String, throwable: Throwable?) {
log.error(msg, throwable) log.error(transformMessage(msg), throwable)
} }
override fun info(msg: String) { override fun info(msg: String) {
log.info(msg) log.info(transformMessage(msg))
} }
override fun warn(msg: String) { override fun warn(msg: String) {
log.warn(msg) log.warn(transformMessage(msg))
} }
override val isDebugEnabled: Boolean override val isDebugEnabled: Boolean