mirror of
https://github.com/corda/corda.git
synced 2025-06-17 22:58:19 +00:00
[CORDA-1996]: Apply error code to exceptions that do not propagate to NodeStartup. (#3964)
This commit is contained in:
committed by
GitHub
parent
4fd8a8fb29
commit
19b8f70117
@ -8,7 +8,6 @@ import net.corda.core.flows.InitiatingFlow
|
|||||||
import net.corda.core.flows.StartableByRPC
|
import net.corda.core.flows.StartableByRPC
|
||||||
import net.corda.core.identity.Party
|
import net.corda.core.identity.Party
|
||||||
import net.corda.core.internal.concurrent.map
|
import net.corda.core.internal.concurrent.map
|
||||||
import net.corda.core.messaging.CordaRPCOps
|
|
||||||
import net.corda.core.messaging.startFlow
|
import net.corda.core.messaging.startFlow
|
||||||
import net.corda.core.utilities.contextLogger
|
import net.corda.core.utilities.contextLogger
|
||||||
import net.corda.core.utilities.getOrThrow
|
import net.corda.core.utilities.getOrThrow
|
||||||
@ -28,7 +27,6 @@ import org.assertj.core.api.AssertionsForInterfaceTypes.assertThat
|
|||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import rx.Observable
|
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
|
@ -154,9 +154,9 @@ open class NodeStartup : CordaCliWrapper("corda", "Runs a Corda Node") {
|
|||||||
|
|
||||||
private val startNodeExpectedErrors = setOf(MultipleCordappsForFlowException::class, CheckpointIncompatibleException::class, AddressBindingException::class, NetworkParametersReader::class, DatabaseIncompatibleException::class)
|
private val startNodeExpectedErrors = setOf(MultipleCordappsForFlowException::class, CheckpointIncompatibleException::class, AddressBindingException::class, NetworkParametersReader::class, DatabaseIncompatibleException::class)
|
||||||
|
|
||||||
private fun Exception.logAsExpected(message: String? = this.message, print: (String?) -> Unit = logger::error) = print("$message [errorCode=${errorCode()}]")
|
private fun Exception.logAsExpected(message: String? = this.message, print: (String?) -> Unit = logger::error) = print(message)
|
||||||
|
|
||||||
private fun Exception.logAsUnexpected(message: String? = this.message, error: Exception = this, print: (String?, Throwable) -> Unit = logger::error) = print("$message${this.message?.let { ": $it" } ?: ""} [errorCode=${errorCode()}]", error)
|
private fun Exception.logAsUnexpected(message: String? = this.message, error: Exception = this, print: (String?, Throwable) -> Unit = logger::error) = print("$message${this.message?.let { ": $it" } ?: ""}", error)
|
||||||
|
|
||||||
private fun Exception.isOpenJdkKnownIssue() = message?.startsWith("Unknown named curve:") == true
|
private fun Exception.isOpenJdkKnownIssue() = message?.startsWith("Unknown named curve:") == true
|
||||||
|
|
||||||
|
@ -735,9 +735,11 @@ class DriverDSLImpl(
|
|||||||
|
|
||||||
val systemProperties = mutableMapOf(
|
val systemProperties = mutableMapOf(
|
||||||
"name" to config.corda.myLegalName,
|
"name" to config.corda.myLegalName,
|
||||||
"visualvm.display.name" to "corda-${config.corda.myLegalName}",
|
"visualvm.display.name" to "corda-${config.corda.myLegalName}"
|
||||||
"log4j2.debug" to if (debugPort != null) "true" else "false"
|
|
||||||
)
|
)
|
||||||
|
debugPort?.let {
|
||||||
|
systemProperties += "log4j2.debug" to "true"
|
||||||
|
}
|
||||||
|
|
||||||
systemProperties += inheritFromParentProcess()
|
systemProperties += inheritFromParentProcess()
|
||||||
systemProperties += overriddenSystemProperties
|
systemProperties += overriddenSystemProperties
|
||||||
|
@ -11,6 +11,7 @@ dependencies {
|
|||||||
compile "info.picocli:picocli:$picocli_version"
|
compile "info.picocli:picocli:$picocli_version"
|
||||||
compile "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
compile "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
|
||||||
compile "org.slf4j:slf4j-api:$slf4j_version"
|
compile "org.slf4j:slf4j-api:$slf4j_version"
|
||||||
|
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
||||||
|
|
||||||
// JAnsi: for drawing things to the terminal in nicely coloured ways.
|
// JAnsi: for drawing things to the terminal in nicely coloured ways.
|
||||||
compile "org.fusesource.jansi:jansi:$jansi_version"
|
compile "org.fusesource.jansi:jansi:$jansi_version"
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package net.corda.cliutils
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.core.LoggerContext
|
||||||
|
import org.apache.logging.log4j.core.config.Configuration
|
||||||
|
import org.apache.logging.log4j.core.config.ConfigurationFactory
|
||||||
|
import org.apache.logging.log4j.core.config.ConfigurationSource
|
||||||
|
import org.apache.logging.log4j.core.config.Order
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.Plugin
|
||||||
|
import org.apache.logging.log4j.core.config.xml.XmlConfiguration
|
||||||
|
import org.apache.logging.log4j.core.impl.LogEventFactory
|
||||||
|
|
||||||
|
@Plugin(name = "CordaLog4j2ConfigFactory", category = "ConfigurationFactory")
|
||||||
|
@Order(10)
|
||||||
|
class CordaLog4j2ConfigFactory : ConfigurationFactory() {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val SUPPORTED_TYPES = arrayOf(".xml", "*")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getConfiguration(loggerContext: LoggerContext, source: ConfigurationSource): Configuration = ErrorCodeAppendingConfiguration(loggerContext, source)
|
||||||
|
|
||||||
|
override fun getSupportedTypes() = SUPPORTED_TYPES
|
||||||
|
|
||||||
|
private class ErrorCodeAppendingConfiguration(loggerContext: LoggerContext, source: ConfigurationSource) : XmlConfiguration(loggerContext, source) {
|
||||||
|
|
||||||
|
override fun doConfigure() {
|
||||||
|
|
||||||
|
super.doConfigure()
|
||||||
|
loggers.values.forEach {
|
||||||
|
val existingFactory = it.logEventFactory
|
||||||
|
it.logEventFactory = LogEventFactory { loggerName, marker, fqcn, level, message, properties, error -> existingFactory.createEvent(loggerName, marker, fqcn, level, message?.withErrorCodeFor(error, level), properties, error) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,26 @@
|
|||||||
package net.corda.node.internal
|
package net.corda.cliutils
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level
|
||||||
|
import org.apache.logging.log4j.message.Message
|
||||||
|
import org.apache.logging.log4j.message.SimpleMessage
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun Exception.errorCode(hashedFields: (Throwable) -> Array<out Any?> = Throwable::defaultHashedFields): String {
|
internal fun Message.withErrorCodeFor(error: Throwable?, level: Level): Message {
|
||||||
|
|
||||||
|
return when {
|
||||||
|
error != null && level.isInRange(Level.FATAL, Level.WARN) -> CompositeMessage("$formattedMessage [errorCode=${error.errorCode()}]", format, parameters, throwable)
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Throwable.errorCode(hashedFields: (Throwable) -> Array<out Any?> = Throwable::defaultHashedFields): String {
|
||||||
|
|
||||||
val hash = staticLocationBasedHash(hashedFields)
|
val hash = staticLocationBasedHash(hashedFields)
|
||||||
return hash.toBase(36)
|
return hash.toBase(36)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Throwable.staticLocationBasedHash(hashedFields: (Throwable) -> Array<out Any?>, visited: Set<Throwable> = setOf(this)): Int {
|
private fun Throwable.staticLocationBasedHash(hashedFields: (Throwable) -> Array<out Any?>, visited: Set<Throwable> = setOf(this)): Int {
|
||||||
|
|
||||||
val cause = this.cause
|
val cause = this.cause
|
||||||
val fields = hashedFields.invoke(this)
|
val fields = hashedFields.invoke(this)
|
||||||
return when {
|
return when {
|
||||||
@ -36,4 +49,13 @@ private fun Throwable.defaultHashedFields(): Array<out Any?> {
|
|||||||
private fun StackTraceElement.defaultHashedFields(): Array<out Any?> {
|
private fun StackTraceElement.defaultHashedFields(): Array<out Any?> {
|
||||||
|
|
||||||
return arrayOf(className, methodName)
|
return arrayOf(className, methodName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CompositeMessage(message: String?, private val formatArg: String?, private val parameters: Array<out Any?>?, private val error: Throwable?) : SimpleMessage(message) {
|
||||||
|
|
||||||
|
override fun getThrowable(): Throwable? = error
|
||||||
|
|
||||||
|
override fun getParameters(): Array<out Any?>? = parameters
|
||||||
|
|
||||||
|
override fun getFormat(): String? = formatArg
|
||||||
}
|
}
|
@ -0,0 +1 @@
|
|||||||
|
log4j.configurationFactory=net.corda.cliutils.CordaLog4j2ConfigFactory
|
Reference in New Issue
Block a user