Skip to content

Commit 39354b1

Browse files
authored
Concrete executor rd logs (#902)
[concrete-executor-rd-logs] 1. fix #870 2. fix #848 changed concrete executor process logs: removed kotlin.logs, moved to rd logging system, overloaded them to write to system.err, adjusted log level of some messages to clarify log, removed useless schedulers and some useless code N.B.: log system will be redesigned with upcoming utbot test generator process separation! Changes will be reflected on UtBotJava rd wiki page.
1 parent 7677d10 commit 39354b1

File tree

7 files changed

+67
-74
lines changed

7 files changed

+67
-74
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/concrete/UtExecutionInstrumentation.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ class UtConcreteExecutionResult(
105105
val modelsToAssembleModels = AssembleModelGenerator(packageName).createAssembleModels(allModels)
106106
return updateWithAssembleModels(modelsToAssembleModels)
107107
}
108+
109+
override fun toString(): String = buildString {
110+
appendLine("UtConcreteExecutionResult(")
111+
appendLine("stateAfter=$stateAfter")
112+
appendLine("result=$result")
113+
appendLine("coverage=$coverage)")
114+
}
108115
}
109116

110117
object UtExecutionInstrumentation : Instrumentation<UtConcreteExecutionResult> {

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/ConcreteExecutor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import org.utbot.framework.plugin.api.util.signature
1616
import org.utbot.instrumentation.instrumentation.Instrumentation
1717
import org.utbot.instrumentation.process.ChildProcessRunner
1818
import org.utbot.instrumentation.rd.UtInstrumentationProcess
19-
import org.utbot.rd.UtRdLoggerFactory
19+
import org.utbot.rd.UtRdKLoggerFactory
2020
import org.utbot.instrumentation.rd.generated.InvokeMethodCommandParams
2121
import org.utbot.instrumentation.util.ChildProcessError
2222
import java.io.Closeable
@@ -123,7 +123,7 @@ class ConcreteExecutor<TIResult, TInstrumentation : Instrumentation<TIResult>> p
123123
var defaultPathsToDependencyClasses = ""
124124

125125
init {
126-
Logger.set(Lifetime.Eternal, UtRdLoggerFactory)
126+
Logger.set(Lifetime.Eternal, UtRdKLoggerFactory)
127127
Runtime.getRuntime().addShutdownHook(thread(start = false) { defaultPool.close() })
128128
}
129129

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/process/ChildProcess.kt

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ package org.utbot.instrumentation.process
22

33
import com.jetbrains.rd.framework.*
44
import com.jetbrains.rd.framework.impl.RdCall
5-
import com.jetbrains.rd.framework.util.launchChild
65
import com.jetbrains.rd.util.ILoggerFactory
76
import com.jetbrains.rd.util.LogLevel
87
import com.jetbrains.rd.util.Logger
98
import com.jetbrains.rd.util.defaultLogFormat
109
import com.jetbrains.rd.util.lifetime.Lifetime
1110
import com.jetbrains.rd.util.lifetime.LifetimeDefinition
1211
import com.jetbrains.rd.util.lifetime.plusAssign
13-
import com.jetbrains.rd.util.threading.SingleThreadScheduler
14-
import kotlinx.coroutines.*
12+
import kotlinx.coroutines.CompletableDeferred
1513
import kotlinx.coroutines.channels.Channel
14+
import kotlinx.coroutines.launch
15+
import kotlinx.coroutines.runBlocking
16+
import kotlinx.coroutines.withTimeoutOrNull
1617
import org.utbot.common.*
1718
import org.utbot.framework.plugin.api.util.UtContext
1819
import org.utbot.instrumentation.agent.Agent
@@ -26,7 +27,7 @@ import org.utbot.instrumentation.rd.obtainClientIO
2627
import org.utbot.instrumentation.rd.processSyncDirectory
2728
import org.utbot.instrumentation.rd.signalChildReady
2829
import org.utbot.instrumentation.util.KryoHelper
29-
import org.utbot.rd.UtSingleThreadScheduler
30+
import org.utbot.rd.UtRdCoroutineScope
3031
import org.utbot.rd.adviseForConditionAsync
3132
import java.io.File
3233
import java.io.OutputStream
@@ -35,7 +36,6 @@ import java.net.URLClassLoader
3536
import java.security.AllPermission
3637
import java.time.LocalDateTime
3738
import java.time.format.DateTimeFormatter
38-
import java.util.concurrent.ArrayBlockingQueue
3939
import java.util.concurrent.TimeUnit
4040
import kotlin.system.measureTimeMillis
4141

@@ -63,7 +63,6 @@ private object HandlerClassesLoader : URLClassLoader(emptyArray()) {
6363
}
6464

6565
private typealias ChildProcessLogLevel = LogLevel
66-
6766
private val logLevel = ChildProcessLogLevel.Info
6867

6968
// Logging
@@ -75,14 +74,28 @@ private fun log(level: ChildProcessLogLevel, any: () -> Any?) {
7574
System.err.println(LocalDateTime.now().format(dateFormatter) + " | ${any()}")
7675
}
7776

77+
// errors that must be address
7878
private fun logError(any: () -> Any?) {
7979
log(ChildProcessLogLevel.Error, any)
8080
}
8181

82+
private fun logException(e: Throwable) {
83+
log(ChildProcessLogLevel.Error) { "$e |> ${e.stackTraceToString()}" }
84+
}
85+
86+
// default log level for irregular useful messages that does not pollute log
8287
private fun logInfo(any: () -> Any?) {
8388
log(ChildProcessLogLevel.Info, any)
8489
}
8590

91+
// log level for frequent messages useful for debugging
92+
private fun logDebug(any: () -> Any?) {
93+
log(ChildProcessLogLevel.Debug, any)
94+
}
95+
96+
// log level for internal rd logs and frequent messages
97+
// heavily pollutes log, useful only when debugging rpc
98+
// probably contains no info about utbot
8699
private fun logTrace(any: () -> Any?) {
87100
log(ChildProcessLogLevel.Trace, any)
88101
}
@@ -119,9 +132,7 @@ suspend fun main(args: Array<String>) = runBlocking {
119132
val pid = currentProcessPid.toInt()
120133
val def = LifetimeDefinition()
121134

122-
SingleThreadScheduler(Lifetime.Eternal, "")
123-
124-
launchChild(Lifetime.Eternal) {
135+
launch {
125136
var lastState = State.STARTED
126137
while (true) {
127138
val current: State? =
@@ -177,20 +188,27 @@ private fun <T, R> RdCall<T, R>.measureExecutionForTermination(block: (T) -> R)
177188
this.set { it ->
178189
runBlocking {
179190
measureExecutionForTermination<R> {
180-
block(it)
191+
try {
192+
block(it)
193+
} catch (e: Throwable) {
194+
logException(e)
195+
throw e
196+
}
181197
}
182198
}
183199
}
184200
}
185201

186202
private suspend fun ProtocolModel.setup(kryoHelper: KryoHelper, onStop: () -> Unit) {
187203
warmup.measureExecutionForTermination {
204+
logDebug { "received warmup request" }
188205
val time = measureTimeMillis {
189206
HandlerClassesLoader.scanForClasses("").toList() // here we transform classes
190207
}
191-
logInfo { "warmup finished in $time ms" }
208+
logDebug { "warmup finished in $time ms" }
192209
}
193210
invokeMethodCommand.measureExecutionForTermination { params ->
211+
logDebug { "received invokeMethod request: ${params.classname}, ${params.signature}" }
194212
val clazz = HandlerClassesLoader.loadClass(params.classname)
195213
val res = instrumentation.invoke(
196214
clazz,
@@ -199,31 +217,36 @@ private suspend fun ProtocolModel.setup(kryoHelper: KryoHelper, onStop: () -> Un
199217
kryoHelper.readObject(params.parameters)
200218
)
201219

202-
logInfo { "sent cmd: $res" }
220+
logDebug { "invokeMethod result: $res" }
203221
InvokeMethodCommandResult(kryoHelper.writeObject(res))
204222
}
205223
setInstrumentation.measureExecutionForTermination { params ->
224+
logDebug { "setInstrumentation request" }
206225
instrumentation = kryoHelper.readObject(params.instrumentation)
226+
logTrace { "instrumentation - ${instrumentation.javaClass.name} " }
207227
Agent.dynamicClassTransformer.transformer = instrumentation // classTransformer is set
208228
Agent.dynamicClassTransformer.addUserPaths(pathsToUserClasses)
209229
instrumentation.init(pathsToUserClasses)
210230
}
211231
addPaths.measureExecutionForTermination { params ->
232+
logDebug { "addPaths request" }
233+
logTrace { "path to userClasses - ${params.pathsToUserClasses}"}
234+
logTrace { "path to dependencyClasses - ${params.pathsToDependencyClasses}"}
212235
pathsToUserClasses = params.pathsToUserClasses.split(File.pathSeparatorChar).toSet()
213236
pathsToDependencyClasses = params.pathsToDependencyClasses.split(File.pathSeparatorChar).toSet()
214237
HandlerClassesLoader.addUrls(pathsToUserClasses)
215238
HandlerClassesLoader.addUrls(pathsToDependencyClasses)
216239
kryoHelper.setKryoClassLoader(HandlerClassesLoader) // Now kryo will use our classloader when it encounters unregistered class.
217-
218-
logTrace { "User classes:" + pathsToUserClasses.joinToString() }
219-
220240
UtContext.setUtContext(UtContext(HandlerClassesLoader))
221241
}
222242
stopProcess.measureExecutionForTermination {
243+
logDebug { "stop request" }
223244
onStop()
224245
}
225246
collectCoverage.measureExecutionForTermination { params ->
247+
logDebug { "collect coverage request" }
226248
val anyClass: Class<*> = kryoHelper.readObject(params.clazz)
249+
logTrace { "class - ${anyClass.name}" }
227250
val result = (instrumentation as CoverageInstrumentation).collectCoverageInfo(anyClass)
228251
CollectCoverageResult(kryoHelper.writeObject(result))
229252
}
@@ -256,13 +279,12 @@ private suspend fun initiate(lifetime: Lifetime, port: Int, pid: Int) {
256279
val kryoHelper = KryoHelper(lifetime)
257280
logInfo { "kryo created" }
258281

259-
val scheduler = UtSingleThreadScheduler { logInfo(it) }
260282
val clientProtocol = Protocol(
261283
"ChildProcess",
262284
Serializers(),
263285
Identities(IdKind.Client),
264-
scheduler,
265-
SocketWire.Client(lifetime, scheduler, port),
286+
UtRdCoroutineScope.scheduler,
287+
SocketWire.Client(lifetime, UtRdCoroutineScope.scheduler, port),
266288
lifetime
267289
)
268290
val (sync, protocolModel) = obtainClientIO(lifetime, clientProtocol)
@@ -290,6 +312,7 @@ private suspend fun initiate(lifetime: Lifetime, port: Int, pid: Int) {
290312
logInfo { "starting instrumenting" }
291313
deferred.await()
292314
} catch (e: Throwable) {
293-
logError { "Terminating process because exception occurred: ${e.stackTraceToString()}" }
315+
logError { "Terminating process because exception occurred" }
316+
logException(e)
294317
}
295318
}

utbot-rd/src/main/kotlin/org/utbot/rd/UtRdCoroutineScope.kt

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,16 @@ package org.utbot.rd
33
import com.jetbrains.rd.framework.util.RdCoroutineScope
44
import com.jetbrains.rd.framework.util.asCoroutineDispatcher
55
import com.jetbrains.rd.util.lifetime.Lifetime
6-
import kotlinx.coroutines.CancellationException
7-
import kotlinx.coroutines.Job
8-
import kotlinx.coroutines.cancelAndJoin
9-
import kotlinx.coroutines.runBlocking
10-
import mu.KotlinLogging
11-
12-
private val logger = KotlinLogging.logger("UtRdCoroutineScope")
136

147
class UtRdCoroutineScope(lifetime: Lifetime) : RdCoroutineScope(lifetime) {
158
companion object {
16-
private val dispatcher =
17-
UtSingleThreadScheduler("UtRdCoroutineScope dispatcher") { logger.info(it) }.asCoroutineDispatcher
9+
val scheduler = UtSingleThreadScheduler("UtRdCoroutineScope")
1810
val current = UtRdCoroutineScope(Lifetime.Eternal)
1911
}
2012

2113
init {
22-
lifetime.bracketIfAlive({
23-
override(lifetime, this)
24-
logger.info { "UtRdCoroutineScope overridden" }
25-
}, {
26-
logger.info { "UtRdCoroutineScope has been reset" }
27-
})
28-
lifetime.onTermination {
29-
logger.info("UtRdCoroutineScope disposed")
30-
}
14+
override(lifetime, this)
3115
}
3216

33-
override val defaultDispatcher = dispatcher
34-
35-
override fun shutdown() {
36-
try {
37-
runBlocking {
38-
coroutineContext[Job]!!.cancelAndJoin()
39-
}
40-
} catch (e: CancellationException) {
41-
// nothing
42-
} catch (e: Throwable) {
43-
logger.error { "error during shutdown: $e" }
44-
}
45-
}
46-
47-
override fun onException(throwable: Throwable) {
48-
if (throwable !is CancellationException) {
49-
logger.error("Unhandled coroutine throwable: $throwable\n stacktrace: ${throwable.stackTraceToString()}")
50-
}
51-
}
17+
override val defaultDispatcher = scheduler.asCoroutineDispatcher
5218
}

utbot-rd/src/main/kotlin/org/utbot/rd/UtRdLogger.kt renamed to utbot-rd/src/main/kotlin/org/utbot/rd/UtRdKLogger.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@ import com.jetbrains.rd.util.ILoggerFactory
44
import com.jetbrains.rd.util.LogLevel
55
import com.jetbrains.rd.util.Logger
66
import com.jetbrains.rd.util.defaultLogFormat
7+
import mu.KLogger
78
import mu.KotlinLogging
89

9-
private val logger = KotlinLogging.logger {}
10-
11-
object UtRdLoggerFactory : ILoggerFactory {
10+
object UtRdKLoggerFactory : ILoggerFactory {
1211
override fun getLogger(category: String): Logger {
13-
logger.trace { "getting logger for category: $category" }
14-
return UtRdLogger(category)
12+
return UtRdKLogger(KotlinLogging.logger(category), category)
1513
}
1614
}
1715

18-
class UtRdLogger(private val category: String) : Logger {
16+
class UtRdKLogger(private val logger: KLogger, private val category: String) : Logger {
1917
override fun isEnabled(level: LogLevel): Boolean {
2018
return when (level) {
2119
LogLevel.Trace -> logger.isTraceEnabled

utbot-rd/src/main/kotlin/org/utbot/rd/UtRdUtil.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ import com.jetbrains.rd.util.reactive.IScheduler
99
import com.jetbrains.rd.util.reactive.ISource
1010
import kotlinx.coroutines.CompletableDeferred
1111
import kotlinx.coroutines.Deferred
12-
import mu.KotlinLogging
13-
14-
private val logger = KotlinLogging.logger {}
15-
private val serverScheduler = UtSingleThreadScheduler { logger.info(it) }
1612

1713
inline fun <T> LifetimeDefinition.terminateOnException(block: (Lifetime) -> T): T {
1814
try {
@@ -54,7 +50,7 @@ suspend fun <T> ISource<T>.adviseForConditionAsync(lifetime: Lifetime, condition
5450
}
5551

5652
suspend fun ISource<Boolean>.adviseForConditionAsync(lifetime: Lifetime): Deferred<Unit> {
57-
return this.adviseForConditionAsync(lifetime) {it}
53+
return this.adviseForConditionAsync(lifetime) { it }
5854
}
5955

6056
/**
@@ -73,8 +69,8 @@ suspend fun startUtProcessWithRdServer(
7369
"Server",
7470
Serializers(),
7571
Identities(IdKind.Server),
76-
serverScheduler,
77-
SocketWire.Server(it, serverScheduler, port, "ServerSocket"),
72+
UtRdCoroutineScope.scheduler,
73+
SocketWire.Server(it, UtRdCoroutineScope.scheduler, port, "ServerSocket"),
7874
it
7975
)
8076
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package org.utbot.rd
22

3+
import com.jetbrains.rd.util.error
4+
import com.jetbrains.rd.util.getLogger
35
import com.jetbrains.rd.util.threading.SingleThreadSchedulerBase
46

5-
class UtSingleThreadScheduler(name: String = "UtRdScheduler", private val log: (() -> String) -> Unit) :
6-
SingleThreadSchedulerBase(name) {
7+
private val logger = getLogger<UtSingleThreadScheduler>()
8+
9+
class UtSingleThreadScheduler(name: String) : SingleThreadSchedulerBase(name) {
710
override fun onException(ex: Throwable) {
8-
log { ex.toString() }
11+
logger.error { "exception on scheduler $name: $ex |> ${ex.stackTraceToString()}" }
912
}
1013
}

0 commit comments

Comments
 (0)