diff --git a/base/src/main/kotlin/de/staropensource/engine/base/implementable/logging/FormatBuilder.kt b/base/src/main/kotlin/de/staropensource/engine/base/implementable/logging/FormatBuilder.kt index 0dab2f6..884dac5 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/implementable/logging/FormatBuilder.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/implementable/logging/FormatBuilder.kt @@ -20,15 +20,17 @@ package de.staropensource.engine.base.implementable.logging import de.staropensource.engine.base.type.logging.Call +import de.staropensource.engine.base.type.logging.ChannelSettings import de.staropensource.engine.base.type.logging.Feature /** * Builds log formats. * - * @param call [Call] to build a format for + * @param call [Call] to build a format for + * @param channelSettings appropriate [ChannelSettings] instance * @since v1-alpha10 */ -abstract class FormatBuilder(protected val call: Call) { +abstract class FormatBuilder(protected val call: Call, protected val channelSettings: ChannelSettings?) { /** * Contains all enabled features. * diff --git a/base/src/main/kotlin/de/staropensource/engine/base/implementation/logging/formatbuilder/SOSLSv2FormatBuilder.kt b/base/src/main/kotlin/de/staropensource/engine/base/implementation/logging/formatbuilder/SOSLSv2FormatBuilder.kt index 19145ed..4cab8e1 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/implementation/logging/formatbuilder/SOSLSv2FormatBuilder.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/implementation/logging/formatbuilder/SOSLSv2FormatBuilder.kt @@ -23,11 +23,13 @@ import de.staropensource.engine.base.EngineConfiguration import de.staropensource.engine.base.logging.Logger import de.staropensource.engine.base.implementable.logging.FormatBuilder import de.staropensource.engine.base.type.logging.Call +import de.staropensource.engine.base.type.logging.ChannelSettings import de.staropensource.engine.base.type.logging.Feature import de.staropensource.engine.base.type.logging.Level import kotlinx.datetime.Clock import kotlinx.datetime.LocalDateTime import kotlinx.datetime.toLocalDateTime +import kotlin.time.Duration /** * Builds the format as specified in the @@ -39,42 +41,64 @@ import kotlinx.datetime.toLocalDateTime * [505ms] [03.10.1990 23:23:23] [INFO de.staropensource.engine.testapp.Main#sayHi~42] Hello World! * ``` * - * @param call [Call] to build a format for + * @param call [Call] to build a format for + * @param channelSettings appropriate [ChannelSettings] instance * @since v1-alpha10 */ -open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { +open class SOSLSv2FormatBuilder(call: Call, channelSettings: ChannelSettings?) : FormatBuilder(call, channelSettings) { override fun toString(): String { - return format(message = true) + return format(message = true, allowFormatting = true) } override fun toStringShadow(): Int { - return format(message = false).length + return format(message = false, allowFormatting = false).length } /** * Runs the actual formatting step. * - * @param message add the message to the finalized format? + * @param message if to add the [message] to the finalized format + * @param allowFormatting if to allow formatting (see [Feature.FORMATTING]) * @return finalized format * @since v1-alpha10 */ - fun format(message: Boolean): String = buildString { - addRuntime(this) - addDateTime(this) + fun format(message: Boolean, allowFormatting: Boolean): String = buildString { + val enabledFeatures: MutableSet = this@SOSLSv2FormatBuilder.enabledFeatures.toMutableSet() + + if (!allowFormatting) + enabledFeatures.remove(Feature.FORMATTING) + + addRuntime(this, enabledFeatures) + addDateTime(this, enabledFeatures) // Add level, origin & other metadata if (enabledFeatures.contains(Feature.LEVEL) || enabledFeatures.contains(Feature.ORIGIN)) { - append("[") - addLevel(this) + if (enabledFeatures.contains(Feature.FORMATTING)) + append("[") + else + append("[") + addLevel(this, enabledFeatures) if (enabledFeatures.contains(Feature.LEVEL) && enabledFeatures.contains(Feature.ORIGIN)) append(" ") - addOriginAndMetadata(this) - append("] ") + addOriginAndMetadata(this, enabledFeatures) + if (enabledFeatures.contains(Feature.FORMATTING)) + append("] ") + else + append("] ") } // Message - if (message) - append(this@SOSLSv2FormatBuilder.message) + if (message) { + var messageFormat: String = this@SOSLSv2FormatBuilder.message + + if (ChannelSettings.getSetting(channelSettings, "sanitizeMessage") == false) + messageFormat = messageFormat.replace("\n", "\n") + + if (enabledFeatures.contains(Feature.FORMATTING)) + append("${messageFormat}") + else + append(messageFormat) + } } /** @@ -83,13 +107,21 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { * @param format [StringBuilder] to operate on * @since v1-alpha10 */ - protected fun addRuntime(format: StringBuilder) { - if (enabledFeatures.contains(Feature.RUNTIME)) - format - .append("[") - .append(Logger.Companion.initializationTime) - .append("ms") - .append("] ") + protected fun addRuntime(format: StringBuilder, enabledFeatures: MutableSet) { + if (enabledFeatures.contains(Feature.RUNTIME)) { + if (enabledFeatures.contains(Feature.FORMATTING)) + format.append("[") + else + format.append("[") + + val differenceTime: Duration = Clock.System.now().minus(Logger.Companion.initializationTime) + format.append("${differenceTime.inWholeSeconds}.${differenceTime.inWholeMilliseconds.minus(differenceTime.inWholeSeconds.times(1000))}s") + + if (enabledFeatures.contains(Feature.FORMATTING)) + format.append("") + + format.append("] ") + } } /** @@ -98,20 +130,27 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { * @param format [StringBuilder] to operate on * @since v1-alpha10 */ - protected fun addDateTime(format: StringBuilder) { + protected fun addDateTime(format: StringBuilder, enabledFeatures: MutableSet) { val datetime: LocalDateTime = Clock.System.now().toLocalDateTime(EngineConfiguration.timezone) - if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME)) - format.append("[") + if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME)) { + if (enabledFeatures.contains(Feature.FORMATTING)) + format.append("[") + else + format.append("[") + } + if (enabledFeatures.contains(Feature.DATE)) format - .append("%02d".format(datetime.dayOfMonth.toString())) + .append("%02d".format(datetime.dayOfMonth)) .append(".") .append("%02d".format(datetime.monthNumber)) .append(".") .append("%04d".format(datetime.year)) + if (enabledFeatures.contains(Feature.DATE) && enabledFeatures.contains(Feature.TIME)) format.append(" ") + if (enabledFeatures.contains(Feature.TIME)) format .append("%02d".format(datetime.hour)) @@ -119,8 +158,13 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { .append("%02d".format(datetime.minute)) .append(":") .append("%02d".format(datetime.second)) - if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME)) - format.append("] ") + + if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME)) { + if (enabledFeatures.contains(Feature.FORMATTING)) + format.append("] ") + else + format.append("] ") + } } /** @@ -129,8 +173,20 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { * @param format [StringBuilder] to operate on * @since v1-alpha10 */ - protected fun addLevel(format: StringBuilder) { - if (enabledFeatures.contains(Feature.LEVEL)) + @Suppress("CyclomaticComplexMethod") + protected fun addLevel(format: StringBuilder, enabledFeatures: MutableSet) { + if (enabledFeatures.contains(Feature.LEVEL)) { + if (enabledFeatures.contains(Feature.FORMATTING)) + format.append(when (call.level) { + Level.DIAGNOSTIC -> "" + Level.VERBOSE -> "" + Level.SILENT_WARNING -> "" + Level.INFORMATIONAL -> "" + Level.WARNING -> "" + Level.ERROR -> "" + Level.CRASH -> "" + }) + format.append( when (call.level) { Level.DIAGNOSTIC -> "DIAG" @@ -142,6 +198,10 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { Level.CRASH -> "CRSH" } ) + + if (enabledFeatures.contains(Feature.FORMATTING) && call.level == Level.CRASH) + format.append("") + } } /** @@ -152,7 +212,7 @@ open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { * @param format [StringBuilder] to operate on * @since v1-alpha10 */ - protected fun addOriginAndMetadata(format: StringBuilder) { + protected fun addOriginAndMetadata(format: StringBuilder, enabledFeatures: MutableSet) { if (enabledFeatures.contains(Feature.ORIGIN)) { format.append("${call.origin.packageName}.${call.origin.className}") diff --git a/base/src/main/kotlin/de/staropensource/engine/base/logging/Processor.kt b/base/src/main/kotlin/de/staropensource/engine/base/logging/Processor.kt index 0b1f9be..02cc2c8 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/logging/Processor.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/logging/Processor.kt @@ -94,19 +94,19 @@ class Processor private constructor() { fun process(call: Call) { val format: FormatBuilder var formatFinalized: String = "" - val channelconf: ChannelSettings? = EngineConfiguration.logChannelSettings[call.channel] + val channelSettings: ChannelSettings? = EngineConfiguration.logChannelSettings[call.channel] var message: String = call.message // Set 'format' try { - format = (EngineConfiguration.logFormatBuilder).primaryConstructor!!.call(call) + format = (EngineConfiguration.logFormatBuilder).primaryConstructor!!.call(call, channelSettings) } catch (throwable: Throwable) { - println("Logger system failure: Configured FormatBuilder implementation '" + ((EngineConfiguration.logFormatBuilder).qualifiedName ?: "") + "' does not have a primary 'constructor(call: Call)'. Log messages cannot be processed.\n${StackTraceUtils.stacktraceRecursive(throwable)}") + println("Logger system failure: Configured FormatBuilder implementation '" + ((EngineConfiguration.logFormatBuilder).qualifiedName ?: "") + "' does not have a primary 'constructor(Call, ChannelSettings?)'. Log messages cannot be processed.\n${StackTraceUtils.stacktraceRecursive(throwable)}") return } // Stop if channel does not permit execution - if (!(ChannelSettings.getSetting(channelconf, "enable") as Boolean)) + if (!(ChannelSettings.getSetting(channelSettings, "enable") as Boolean)) return // Build format @@ -116,11 +116,11 @@ class Processor private constructor() { // Update message if ( - ChannelSettings.getSetting(channelconf, "sanitizeMessage") as Boolean - && ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean + ChannelSettings.getSetting(channelSettings, "sanitizeMessage") as Boolean + && ChannelSettings.getSetting(channelSettings, "permitFormatting") as Boolean ) message = message.replace("<", "\\<") if ( - ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean + ChannelSettings.getSetting(channelSettings, "permitFormatting") as Boolean && EngineConfiguration.logFeatures.contains(Feature.FORMATTING) ) format.addFeature(Feature.FORMATTING) @@ -131,14 +131,14 @@ class Processor private constructor() { format.message = message // Format format - formatFinalized = if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean) - (ChannelSettings.getSetting(channelconf, "formatter") as Formatter).formatString(format.toString()) + formatFinalized = if (ChannelSettings.getSetting(channelSettings, "permitFormatting") as Boolean) + (ChannelSettings.getSetting(channelSettings, "formatter") as Formatter).formatString(format.toString()) else format.toString() // Pass format to adapters @Suppress("UNCHECKED_CAST") - for (adapter: Adapter in ChannelSettings.getSetting(channelconf, "adapters") as Set) + for (adapter: Adapter in ChannelSettings.getSetting(channelSettings, "adapters") as Set) adapter.handle(call, formatFinalized) } }