diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/CrashHandler.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/CrashHandler.kt
new file mode 100644
index 000000000..1583606dd
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/CrashHandler.kt
@@ -0,0 +1,134 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.engine.logging
+
+import de.staropensource.engine.logging.implementable.Adapter
+import de.staropensource.engine.logging.implementable.CrashCategory
+import de.staropensource.engine.logging.implementable.Formatter
+import de.staropensource.engine.logging.implementation.KotlinShutdownHandler
+import de.staropensource.engine.logging.type.Call
+import de.staropensource.engine.logging.type.ChannelSettings
+
+/**
+ * Handles crashes.
+ *
+ * @since v1-alpha10
+ */
+class CrashHandler private constructor() {
+ /**
+ * Companion object of [CrashHandler].
+ *
+ * @since v1-alpha10
+ */
+ companion object {
+ /**
+ * Handles crashes.
+ *
+ * @param call [Call] metadata
+ * @param throwable the [Throwable] which caused the crash
+ * @param fatal terminates the engine and application if `true`
+ * @since v1-alpha10
+ */
+ internal fun handle(call: Call, throwable: Throwable? = null, fatal: Boolean = true) {
+ val format: StringBuilder = StringBuilder()
+ var formatFinalized: String? = null
+ val channelconf: ChannelSettings? = LoggerConfiguration.channelSettings[call.channel]
+
+ if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean)
+ format.append("")
+
+ format
+ .append("--------------------\nOh no! ")
+ .append(ChannelSettings.getSetting(channelconf, "applicationName"))
+ .append(" crashed!\nIf you're a user of this application, then please report this crash to the developer.")
+
+ for (category: CrashCategory in LoggerConfiguration.crashCategories)
+ if (category.check())
+ format
+ .append("\n\n${category.getName()}")
+ .append(compileCategory(category.execute(call, channelconf, throwable, fatal)))
+
+ format
+ .append("\n\n... ")
+ .append(ChannelSettings.getSetting(channelconf, "applicationName"))
+ .append(" unfortunately crashed.\nIf you're a user of this application, then please ")
+ .append("report this crash to the developer.\n--------------------")
+
+ // Format format
+ formatFinalized = if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean)
+ (ChannelSettings.getSetting(channelconf, "formatter") as Formatter).formatString(format.toString())
+ else
+ format.toString()
+
+ // Pass format to adapter
+ (ChannelSettings.getSetting(channelconf, "adapter") as Adapter).handle(call, formatFinalized)
+
+ if (fatal)
+ (LoggerConfiguration.shutdownHandler ?: KotlinShutdownHandler.instance).exit(exitcode = 69)
+ }
+
+ /**
+ * Compiles a [CrashCategory].
+ *
+ * @param category [CrashCategory] to compile
+ * @return compiled output
+ * @since v1-alpha10
+ */
+ private fun compileCategory(map: LinkedHashMap<*, *>, indent: Int = 1): String {
+ val builder: StringBuilder = StringBuilder()
+ var entryString: String? = null
+
+ // Iterate over all entries
+ for (entry in map.keys) {
+ // Check if key is a string
+ if (entry !is String)
+ continue
+
+ builder.append("\n${" ".repeat(indent)}-> ${entry}")
+
+ if (map[entry] is LinkedHashMap<*, *>) // Value is a map
+ builder.append(
+ compileCategory(
+ map[entry] as LinkedHashMap<*, *>,
+ indent = indent + 3 // increase the 2nd addend to change the indent size during recursion
+ )
+ )
+ else {
+ entryString = map[entry].toString()
+
+ // Put on separate line if contains newline
+ if (entryString.contains("\n"))
+ builder
+ .append("\n${entryString}"
+ .replace(
+ "\n",
+ "\n ${" ".repeat(indent)}"
+ )
+ )
+ else
+ builder.append(": ${entryString}")
+ }
+ }
+
+ return builder.toString()
+ }
+ }
+}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/Logger.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/Logger.kt
index f32ae51cf..c1e5173e5 100644
--- a/logging/src/main/kotlin/de/staropensource/engine/logging/Logger.kt
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/Logger.kt
@@ -61,6 +61,7 @@ class Logger {
* @since v1-alpha10
*/
@JvmStatic
+ @Suppress("unused")
val instance = Logger()
}
@@ -90,34 +91,41 @@ class Logger {
/**
* Logs a message.
*
- * @param level level to use
- * @param message message to log
- * @param stackTraceDistance determines which [StackTraceElement] will
- * be used as the call's origin. Just fiddle
- * with this number until it's correct.
+ * Using this method is highly discouraged as it is
+ * considered internal and should only be accessed
+ * if necessary. It provides direct access to the
+ * internal logging facility and can cause breakage
+ * if used improperly.
+ *
+ * @param level level to use
+ * @param message message to log
+ * @param levelData data specific to a [Level]
+ * @param stackTraceDistance determines which [StackTraceElement] will be used as the call's origin. Just fiddle with this number until it's correct.
* @since v1-alpha10
*/
- @Suppress("JoinDeclarationAndAssignment")
- fun log(level: Level, message: String, stackTraceDistance: Int = 0) {
+ fun log(level: Level, message: String, levelData: Map = emptyMap(), stackTraceDistance: Int = 0) {
val origin: StackTraceElement
- var call: Call
// Set 'origin'
try {
origin = Throwable().stackTrace[1 + stackTraceDistance]
- } catch (exception: IndexOutOfBoundsException) {
+ } catch (_: IndexOutOfBoundsException) {
return
}
- // Set 'call'
- call = Call(origin, level, message, channel)
+ // Create 'Call' instance
+ var call: Call = Call(origin, level, message, channel)
// Run processing
- if (Processor.check(call))
- return
+ if (level == Level.CRASH)
+ CrashHandler.handle(call, levelData["throwable"] as Throwable?, levelData.getOrDefault("fatal", true) as Boolean)
+ else {
+ if (Processor.check(call))
+ return
- if (LoggerConfiguration.threadingHandler?.queue(call) == null)
- Processor.process(call)
+ if (LoggerConfiguration.threadingHandler?.queue(call) == null)
+ Processor.process(call)
+ }
}
/**
@@ -127,7 +135,7 @@ class Logger {
* @since v1-alpha10
*/
fun diag(message: String) {
- log(Level.DIAGNOSTIC, message, 1)
+ log(Level.DIAGNOSTIC, message, stackTraceDistance = 1)
}
/**
@@ -137,7 +145,7 @@ class Logger {
* @since v1-alpha10
*/
fun verb(message: String) {
- log(Level.VERBOSE, message, 1)
+ log(Level.VERBOSE, message, stackTraceDistance = 1)
}
/**
@@ -147,7 +155,7 @@ class Logger {
* @since v1-alpha10
*/
fun sarn(message: String) {
- log(Level.SILENT_WARNING, message, 1)
+ log(Level.SILENT_WARNING, message, stackTraceDistance = 1)
}
/**
@@ -157,7 +165,7 @@ class Logger {
* @since v1-alpha10
*/
fun info(message: String) {
- log(Level.INFORMATIONAL, message, 1)
+ log(Level.INFORMATIONAL, message, stackTraceDistance = 1)
}
/**
@@ -167,7 +175,7 @@ class Logger {
* @since v1-alpha10
*/
fun warn(message: String) {
- log(Level.WARNING, message, 1)
+ log(Level.WARNING, message, stackTraceDistance = 1)
}
/**
@@ -177,17 +185,22 @@ class Logger {
* @since v1-alpha10
*/
fun error(message: String) {
- log(Level.ERROR, message, 1)
+ log(Level.ERROR, message, stackTraceDistance = 1)
}
/**
* Logs a fatal error.
*
- * @param message message
+ * @param error the error which caused the crash
+ * @param throwable the [Throwable] which caused the crash
+ * @param fatal terminates the engine and application if `true`
* @since v1-alpha10
*/
- fun crash(message: String) {
- log(Level.CRASH, message, 1)
+ fun crash(error: String, throwable: Throwable? = null, fatal: Boolean = true) {
+ log(Level.CRASH, error, levelData = mapOf(
+ Pair("throwable", throwable as Object?),
+ Pair("fatal", fatal as Object?)
+ ), stackTraceDistance = 1)
}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/LoggerConfiguration.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/LoggerConfiguration.kt
index 92216a920..be5fe375f 100644
--- a/logging/src/main/kotlin/de/staropensource/engine/logging/LoggerConfiguration.kt
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/LoggerConfiguration.kt
@@ -20,10 +20,13 @@
package de.staropensource.engine.logging
+import de.staropensource.engine.logging.implementable.CrashCategory
import de.staropensource.engine.logging.implementation.SOSLSv2FormatBuilder
import de.staropensource.engine.logging.type.ChannelSettings
import de.staropensource.engine.logging.type.Feature
import de.staropensource.engine.logging.implementable.FormatBuilder
+import de.staropensource.engine.logging.implementable.ShutdownHandler
+import de.staropensource.engine.logging.implementation.crashcategory.InfoCrashCategory
import de.staropensource.engine.logging.type.Level
import de.staropensource.engine.logging.type.OperationMode
import kotlinx.datetime.TimeZone
@@ -79,32 +82,6 @@ class LoggerConfiguration private constructor() {
Feature.LINE_NUMBER,
)
- /**
- * Controls the [ThreadingHandler] to use.
- *
- * This determines how multithreading
- * shall be performed. Set to `null` for
- * a single-threaded logger.
- *
- * @see ThreadingHandler
- * @since v1-alpha10
- */
- @JvmStatic
- val threadingHandler: ThreadingHandler? = null
-
- /**
- * Controls the [FormatBuilder] to use.
- *
- * This determines how formats are built
- * and how the final log output looks like.
- * Set to `null` to default to [SOSLSv2FormatBuilder].
- *
- * @see FormatBuilder
- * @since v1-alpha10
- */
- @JvmStatic
- val formatBuilder: KClass? = null
-
/**
* Controls how fast the logging thread
* shall wait until processing the log
@@ -125,7 +102,57 @@ class LoggerConfiguration private constructor() {
*
* @since v1-alpha10
*/
- val channelSettings: MutableMap = mutableMapOf()
+ @JvmStatic
+ var channelSettings: MutableMap = mutableMapOf()
+
+ /**
+ * Contains all registered [CrashCategory]s.
+ *
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ var crashCategories: LinkedHashSet = linkedSetOf(
+ InfoCrashCategory.instance
+ )
+
+ /**
+ * Controls the [ThreadingHandler] to use.
+ *
+ * This determines how multithreading
+ * shall be performed. Set to `null` for
+ * a single-threaded logger.
+ *
+ * @see ThreadingHandler
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ var threadingHandler: ThreadingHandler? = null
+
+ /**
+ * Controls the [FormatBuilder] to use.
+ *
+ * This determines how formats are built
+ * and how the final log output looks like.
+ * Set to `null` to default to [SOSLSv2FormatBuilder].
+ *
+ * @see FormatBuilder
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ var formatBuilder: KClass? = null
+
+ /**
+ * Controls the [ShutdownHandler] to use.
+ *
+ * This determines how the
+ * application is shut down
+ * after crashing fatally.
+ *
+ * @see ShutdownHandler
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ var shutdownHandler: ShutdownHandler? = null
// -----> Feature settings
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/Processor.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/Processor.kt
index 4c6f0b6a0..584fa1bf9 100644
--- a/logging/src/main/kotlin/de/staropensource/engine/logging/Processor.kt
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/Processor.kt
@@ -20,13 +20,13 @@
package de.staropensource.engine.logging
-import de.staropensource.engine.logging.implementation.NoOperationFormatter
-import de.staropensource.engine.logging.implementation.PrintlnAdapter
+import de.staropensource.engine.logging.implementable.Adapter
+import de.staropensource.engine.logging.implementable.FormatBuilder
+import de.staropensource.engine.logging.implementable.Formatter
import de.staropensource.engine.logging.implementation.SOSLSv2FormatBuilder
import de.staropensource.engine.logging.type.Call
import de.staropensource.engine.logging.type.ChannelSettings
import de.staropensource.engine.logging.type.Feature
-import de.staropensource.engine.logging.implementable.FormatBuilder
import de.staropensource.engine.logging.type.OperationMode
import kotlin.reflect.full.primaryConstructor
@@ -51,6 +51,7 @@ class Processor private constructor() {
*
* Invoked by [Logger.log].
*
+ * @param call [Call] metadata
* @return terminate processing?
* @since v1-alpha10
*/
@@ -81,6 +82,7 @@ class Processor private constructor() {
* Invoked by the configured
* [ThreadingHandler].
*
+ * @param call [Call] metadata
* @see LoggerConfiguration.threadingHandler
* @see ChannelSettings.formatter
* @see ChannelSettings.adapter
@@ -91,7 +93,7 @@ class Processor private constructor() {
fun process(call: Call) {
val format: FormatBuilder
var formatFinalized: String = ""
- val channelconf: ChannelSettings = LoggerConfiguration.channelSettings[call.channel] ?: ChannelSettings.global
+ val channelconf: ChannelSettings? = LoggerConfiguration.channelSettings[call.channel]
var message: String = call.message
// Set 'format'
@@ -103,7 +105,7 @@ class Processor private constructor() {
}
// Stop if channel does not permit execution
- if ((channelconf.enable ?: ChannelSettings.global.enable) == false)
+ if (!(ChannelSettings.getSetting(channelconf, "enable") as Boolean))
return
// Build format
@@ -113,11 +115,11 @@ class Processor private constructor() {
// Update message
if (
- (channelconf.sanitizeMessage ?: ChannelSettings.global.sanitizeMessage) != false
- && (channelconf.permitFormatting ?: ChannelSettings.global.permitFormatting) != false
+ ChannelSettings.getSetting(channelconf, "sanitizeMessage") as Boolean
+ && ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean
) message = message.replace("<", "\\<")
if (
- ((channelconf.permitFormatting ?: ChannelSettings.global.permitFormatting) != false)
+ ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean
&& LoggerConfiguration.features.contains(Feature.FORMATTING)
) format.addFeature(Feature.FORMATTING)
@@ -125,13 +127,13 @@ class Processor private constructor() {
format.message = message
// Format format
- formatFinalized = if ((channelconf.permitFormatting ?: ChannelSettings.global.permitFormatting) != false)
- (channelconf.formatter ?: ChannelSettings.global.formatter ?: NoOperationFormatter.instance).formatString(format.toString())
+ formatFinalized = if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean)
+ (ChannelSettings.getSetting(channelconf, "formatter") as Formatter).formatString(format.toString())
else
format.toString()
// Pass format to adapter
- (channelconf.adapter ?: ChannelSettings.global.adapter ?: PrintlnAdapter.instance).handle(call, formatFinalized)
+ (ChannelSettings.getSetting(channelconf, "adapter") as Adapter).handle(call, formatFinalized)
}
}
}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/CrashCategory.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/CrashCategory.kt
new file mode 100644
index 000000000..cd7b8e368
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/CrashCategory.kt
@@ -0,0 +1,72 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.engine.logging.implementable
+
+import de.staropensource.engine.logging.CrashHandler
+import de.staropensource.engine.logging.type.Call
+import de.staropensource.engine.logging.type.ChannelSettings
+
+/**
+ * Used by the [CrashHandler] to
+ * print useful information.
+ *
+ * @since v1-alpha10
+ */
+interface CrashCategory {
+ /**
+ * Checks if this category
+ * shall be executed.
+ *
+ * @return execute?
+ * @since v1-alpha10
+ */
+ fun check(): Boolean
+
+ /**
+ * Returns the name of this crash category.
+ *
+ * @return category name
+ * @since v1-alpha10
+ */
+ fun getName(): String
+
+ /**
+ * Executes this crash category.
+ *
+ * The value of this map can either
+ * be a [String] or recurse downwards
+ * with `Map`. Any other
+ * values will be ignored.
+ *
+ * @param call [Call] metadata
+ * @param channelconf [ChannelSettings] instance or `null`. Use this to access [ChannelSettings.getSetting]
+ * @param throwable the [Throwable] which caused the crash
+ * @param fatal terminates the engine and application if `true`
+ * @return crash category items
+ * @since v1-alpha10
+ */
+ fun execute(
+ call: Call,
+ channelconf: ChannelSettings?,
+ throwable: Throwable?,
+ fatal: Boolean,
+ ): LinkedHashMap
+}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/ShutdownHandler.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/ShutdownHandler.kt
new file mode 100644
index 000000000..8d1ff288f
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/implementable/ShutdownHandler.kt
@@ -0,0 +1,36 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.engine.logging.implementable
+
+/**
+ * Handles shutdowns.
+ *
+ * @since v1-alpha10
+ */
+interface ShutdownHandler {
+ /**
+ * Shuts everything down.
+ *
+ * @param exitcode the code to exit with
+ * @since v1-alpha10
+ */
+ fun exit(exitcode: Byte = 0)
+}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/KotlinShutdownHandler.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/KotlinShutdownHandler.kt
new file mode 100644
index 000000000..992f416d6
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/KotlinShutdownHandler.kt
@@ -0,0 +1,51 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.engine.logging.implementation
+
+import de.staropensource.engine.logging.implementable.ShutdownHandler
+import kotlin.system.exitProcess
+
+/**
+ * [ShutdownHandler] implementation using
+ * Kotlin's [kotlin.system.exitProcess] method.
+ *
+ * @since v1-alpha10
+ */
+class KotlinShutdownHandler private constructor() : ShutdownHandler {
+ /**
+ * Companion object of [KotlinShutdownHandler].
+ *
+ * @since v1-alpha10
+ */
+ companion object {
+ /**
+ * Global instance of [KotlinShutdownHandler].
+ *
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ val instance: KotlinShutdownHandler = KotlinShutdownHandler()
+ }
+
+ override fun exit(exitcode: Byte) {
+ exitProcess(exitcode.toInt())
+ }
+}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/InfoCrashCategory.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/InfoCrashCategory.kt
new file mode 100644
index 000000000..5a79930ab
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/InfoCrashCategory.kt
@@ -0,0 +1,76 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.staropensource.engine.logging.implementation.crashcategory
+
+import de.staropensource.engine.logging.implementable.CrashCategory
+import de.staropensource.engine.logging.type.Call
+import de.staropensource.engine.logging.type.ChannelSettings
+
+/**
+ * [CrashCategory] implementation
+ * providing insight into a crash.
+ *
+ * @since v1-alpha10
+ */
+class InfoCrashCategory private constructor() : CrashCategory {
+ /**
+ * Companion object of [InfoCrashCategory].
+ *
+ * @since v1-alpha10
+ */
+ companion object {
+ /**
+ * Global instance of [InfoCrashCategory].
+ *
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ val instance: InfoCrashCategory = InfoCrashCategory()
+ }
+
+ override fun check(): Boolean {
+ return true
+ }
+
+ override fun getName(): String {
+ return "Crash"
+ }
+
+ override fun execute(
+ call: Call,
+ channelconf: ChannelSettings?,
+ throwable: Throwable?,
+ fatal: Boolean,
+ ): LinkedHashMap {
+ return linkedMapOf(
+ Pair("Origin", linkedMapOf(
+ Pair("Class", call.origin.className),
+ Pair("Method", call.origin.methodName),
+ Pair("Line", call.origin.lineNumber),
+ Pair("Native", if (call.origin.isNativeMethod) "yes" else "false")
+ )),
+ Pair("Channel", call.channel),
+ Pair("Fatal", if (fatal) "yes" else "no"),
+ Pair("Message", call.message),
+ Pair("Stacktrace", throwable?.toString() ?: "Not available."), // TODO report correct stacktrace
+ )
+ }
+}
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/package-info.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/package-info.kt
new file mode 100644
index 000000000..57d2b4c8b
--- /dev/null
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/implementation/crashcategory/package-info.kt
@@ -0,0 +1,28 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Authors
+ * Licensed under the GNU Affero General Public License v3
+ * with an exception allowing classpath linking.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * Implementations of the [CrashCategory] interface.
+ *
+ * @since v1-alpha10
+ */
+package de.staropensource.engine.logging.implementation.crashcategory
+
+import de.staropensource.engine.logging.implementable.CrashCategory
diff --git a/logging/src/main/kotlin/de/staropensource/engine/logging/type/ChannelSettings.kt b/logging/src/main/kotlin/de/staropensource/engine/logging/type/ChannelSettings.kt
index 469cbd981..73c3b620b 100644
--- a/logging/src/main/kotlin/de/staropensource/engine/logging/type/ChannelSettings.kt
+++ b/logging/src/main/kotlin/de/staropensource/engine/logging/type/ChannelSettings.kt
@@ -12,16 +12,18 @@ import de.staropensource.engine.logging.implementation.PrintlnAdapter
* @param enable enables or disables all log messages utilising this channel. Defaults to the global value or `true` if set to `null`
* @param sanitizeMessage if message sanitization (escaping `<`) should be performed. Defaults to the global value or `true` if set to `null`
* @param permitFormatting if formatting shall be permitted for the entire format. For disallowing formatting for the message only, see [sanitizeMessage]. Defaults to the global value or `true` if set to `null`
+ * @param applicationName name of the application. Used in crash reports. Defaults to the global value or `"This application"` if `null`
* @param formatter determines how messages are formatted and stylized. Defaults to the global value or [NoOperationFormatter] if set to `null`
* @param adapter used for printing the finalized log format somewhere. Defaults to the global value [PrintlnAdapter] if set to `null`
* @since v1-alpha10
*/
data class ChannelSettings(
- val enable: Boolean? = null,
- val sanitizeMessage: Boolean? = null,
- val permitFormatting: Boolean? = null,
- val formatter: Formatter? = null,
- val adapter: Adapter? = null,
+ private val enable: Boolean? = null,
+ private val sanitizeMessage: Boolean? = null,
+ private val permitFormatting: Boolean? = null,
+ private val applicationName: String? = null,
+ private val formatter: Formatter? = null,
+ private val adapter: Adapter? = null,
) {
/**
* Companion object of [ChannelSettings].
@@ -47,11 +49,34 @@ data class ChannelSettings(
*/
@JvmStatic
val global: ChannelSettings = ChannelSettings(
- true,
- true,
- true,
- null,
- null
+ enable = null,
+ sanitizeMessage = null,
+ permitFormatting = null,
+ applicationName = null,
+ formatter = null,
+ adapter = null,
)
+
+ /**
+ * Returns a setting's value.
+ *
+ * @param settings [ChannelSettings] instance to access. Set to `null` to only access the global settings
+ * @param setting setting to get
+ * @return setting value or `null`
+ * @since v1-alpha10
+ */
+ @JvmStatic
+ @Suppress("CyclomaticComplexMethod")
+ fun getSetting(settings: ChannelSettings?, setting: String): Any? {
+ return when (setting) {
+ "enable" -> (settings?.enable ?: global.enable) != false
+ "sanitizeMessage" -> (settings?.sanitizeMessage ?: global.sanitizeMessage) != false
+ "permitFormatting" -> (settings?.permitFormatting ?: global.permitFormatting) != false
+ "applicationName" -> settings?.applicationName ?: global.applicationName ?: "This application"
+ "formatter" -> settings?.formatter ?: global.formatter ?: NoOperationFormatter.instance
+ "adapter" -> settings?.adapter ?: global.adapter ?: PrintlnAdapter.instance
+ else -> null
+ }
+ }
}
}