do many fun things (see commit desc)
All checks were successful
PRs & Pushes / build-apidoc (push) Successful in 2m29s
PRs & Pushes / build (push) Successful in 2m32s

This commit adds a few shutdown methods, the EngineConfiguration class (pretty much the LoggingConfiguration class with properties renamed and one added), a new adapter, support for multiple adapters per channel and better communication between the logging system and the engine.
This commit is contained in:
JeremyStar™ 2024-12-15 20:11:26 +01:00
parent 353e9527c2
commit 6b201fd0e0
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
37 changed files with 480 additions and 312 deletions

View file

@ -23,7 +23,7 @@ package de.staropensource.engine.base
import de.staropensource.engine.base.exception.EngineInitializationFailureException import de.staropensource.engine.base.exception.EngineInitializationFailureException
import de.staropensource.engine.base.utility.Environment import de.staropensource.engine.base.utility.Environment
import de.staropensource.engine.base.utility.FileAccess import de.staropensource.engine.base.utility.FileAccess
import de.staropensource.engine.logging.Logger import de.staropensource.engine.base.logging.Logger
/** /**
* Primary class of the engine. * Primary class of the engine.
@ -53,7 +53,7 @@ class Engine private constructor() {
* @since v1-alpha10 * @since v1-alpha10
*/ */
var state: State = State.UNINITIALIZED var state: State = State.UNINITIALIZED
private set internal set
/** /**
* Contains if the engine is currently * Contains if the engine is currently
@ -143,24 +143,77 @@ class Engine private constructor() {
/** /**
* Shuts the engine down. * Shuts the engine down.
* *
* @throws Throwable on shutdown error
* @since v1-alpha10 * @since v1-alpha10
*/ */
@JvmStatic @JvmStatic
@Throws(Throwable::class)
fun shutdown() { fun shutdown() {
// Abort if not initialized // Abort if not initialized
if (state != State.INITIALIZED) if (state != State.INITIALIZED)
return return
state = State.SHUTTING_DOWN
logger.info("Shutting down") logger.info("Shutting down")
// Perform shutdown
performShutdown()
state = State.SHUT_DOWN
}
/**
* Shuts the engine down and
* terminates the application.
*
* @since v1-alpha10
*/
@JvmStatic
fun shutdownFinal(exitcode: UByte = 0u) {
// Abort if not initialized
if (state != State.INITIALIZED)
return
logger.info("Shutting down for good")
// Perform shutdown
performShutdown()
state = State.SHUT_DOWN
// Quit application
EngineConfiguration.shutdownHandler.exit(exitcode)
}
/**
* Shuts the engine down after
* it having crashed fatally.
*
* @since v1-alpha10
*/
@JvmStatic
internal fun shutdownAfterCrash() {
logger.info("Shutting down after having crashed fatally")
// Perform shutdown
performShutdown(crashed = true)
state = State.CRASHED
// Quit application
EngineConfiguration.shutdownHandler.exit(exitcode = 69u)
}
/**
* Shuts the engine down.
*
* This performs the actual shutdown,
* just without the bloat.
*
* @param crashed enables super careful mode to prevent further breakage
* @since v1-alpha10
*/
@JvmStatic
private fun performShutdown(crashed: Boolean = false) {
state = State.SHUTTING_DOWN
// Run shutdown code // Run shutdown code
Environment.unset() Environment.unset()
FileAccess.unsetDefaultPaths() FileAccess.unsetDefaultPaths()
state = State.SHUT_DOWN
} }
} }

View file

@ -0,0 +1,175 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base
import de.staropensource.engine.base.implementable.ShutdownHandler
import de.staropensource.engine.base.implementable.logging.CrashCategory
import de.staropensource.engine.base.implementable.logging.FormatBuilder
import de.staropensource.engine.base.implementation.logging.KotlinShutdownHandler
import de.staropensource.engine.base.implementation.logging.crashcategory.InfoCrashCategory
import de.staropensource.engine.base.implementation.logging.formatbuilder.SOSLSv2FormatBuilder
import de.staropensource.engine.base.logging.Logger
import de.staropensource.engine.base.logging.LoggerThreadingHandler
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 de.staropensource.engine.base.type.logging.OperationMode
import kotlinx.datetime.TimeZone
import kotlin.reflect.KClass
/**
* Provides the engine configuration.
*
* @since v1-alpha10
*/
class EngineConfiguration private constructor() {
/**
* Companion object of [EngineConfiguration].
*
* @since v1-alpha10
*/
companion object {
// -----> Core engine
/**
* Controls which [TimeZone] to use
* for date and time synchronization.
*
* @since v1-alpha10
*/
val timezone: TimeZone = TimeZone.UTC
/**
* Controls how the engine should shut down.
*
* @since v1-alpha10
*/
@JvmStatic
var shutdownHandler: ShutdownHandler = KotlinShutdownHandler.instance
// -----> Logging system
/**
* Controls how [Logger]
* instances should function.
*
* @since v1-alpha10
*/
@JvmStatic
var logMode: OperationMode = OperationMode.NORMAL
/**
* Determines which levels are
* allowed to be processed by
* the logging system.
*
* @since v1-alpha10
*/
@JvmStatic
var logLevels: MutableSet<Level> = mutableSetOf(
Level.INFORMATIONAL,
Level.WARNING,
Level.ERROR,
Level.CRASH
)
/**
* Determines which enabled log
* features shall be displayed
* in the final log output.
*
* @since v1-alpha10
*/
@JvmStatic
var logFeatures: MutableSet<Feature> = mutableSetOf(
Feature.FORMATTING,
Feature.TIME,
Feature.LEVEL,
Feature.ORIGIN,
Feature.LINE_NUMBER,
)
/**
* Controls how fast the [LoggerThreadingHandler]
* shall wait until processing the log queue after
* it has been processed minus the processing time.
*
* This only takes effect if [logThreadingHandler]
* is not set to `null`.
*
* @since v1-alpha10
*/
@JvmStatic
var logThreadingPollDelay: Int = 5
/**
* Holds log channel settings.
*
* These control how different
* log channels behave.
*
* @since v1-alpha10
*/
@JvmStatic
var logChannelSettings: MutableMap<String, ChannelSettings> = mutableMapOf()
/**
* Holds all registered [CrashCategory]s
* used by the logging system.
*
* These are used to build crash reports
* and supply information about a crash.
*
* @since v1-alpha10
*/
@JvmStatic
var logCrashCategories: LinkedHashSet<CrashCategory> = linkedSetOf(
InfoCrashCategory.instance
)
/**
* Controls the [LoggerThreadingHandler]
* to use for logging.
*
* This determines how multithreading is
* handled in the logging system. Set to
* `null` for a single-threaded logger.
*
* @see LoggerThreadingHandler
* @since v1-alpha10
*/
@JvmStatic
var logThreadingHandler: LoggerThreadingHandler? = null
/**
* Controls the [FormatBuilder] to use.
*
* These design the log output and
* will determine how the final
* log output will look like.
*
* @see FormatBuilder
* @since v1-alpha10
*/
@JvmStatic
@Suppress("UNCHECKED_CAST")
var logFormatBuilder: KClass<FormatBuilder> = SOSLSv2FormatBuilder::class as KClass<FormatBuilder>
}
}

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable
/** /**
* Handles shutdowns. * Handles shutdowns.
@ -32,5 +32,5 @@ interface ShutdownHandler {
* @param exitcode the code to exit with * @param exitcode the code to exit with
* @since v1-alpha10 * @since v1-alpha10
*/ */
fun exit(exitcode: Byte = 0) fun exit(exitcode: UByte = 0u)
} }

View file

@ -18,9 +18,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
/** /**
* Handles processed log calls. * Handles processed log calls.

View file

@ -18,11 +18,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
import de.staropensource.engine.logging.CrashHandler import de.staropensource.engine.base.logging.CrashHandler
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.logging.type.ChannelSettings import de.staropensource.engine.base.type.logging.ChannelSettings
/** /**
* Used by the [CrashHandler] to * Used by the [CrashHandler] to

View file

@ -18,9 +18,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
/** /**
* Provides methods for filtering log calls. * Provides methods for filtering log calls.

View file

@ -18,10 +18,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.logging.type.Feature import de.staropensource.engine.base.type.logging.Feature
/** /**
* Builds log formats. * Builds log formats.

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
/** /**
* Provides log format formatting. * Provides log format formatting.

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
/** /**
* Performs message formatting in one cycle. * Performs message formatting in one cycle.

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.implementable.logging
/** /**
* Performs message formatting in two cycles. * Performs message formatting in two cycles.

View file

@ -18,9 +18,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation package de.staropensource.engine.base.implementable.logging
import de.staropensource.engine.logging.implementable.TwoCycleFormatter import kotlin.text.iterator
/** /**
* A [TwoCycleFormatter] implementation providing * A [TwoCycleFormatter] implementation providing

View file

@ -19,9 +19,9 @@
*/ */
/** /**
* Implementations of various * Interfaces and abstract classes
* interfaces and abstract classes. * used by the logging system.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
package de.staropensource.engine.logging.implementation; package de.staropensource.engine.base.implementable.logging

View file

@ -18,14 +18,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation package de.staropensource.engine.base.implementation.logging
import de.staropensource.engine.logging.implementable.ShutdownHandler import de.staropensource.engine.base.implementable.ShutdownHandler
import kotlin.system.exitProcess import kotlin.system.exitProcess
/** /**
* [ShutdownHandler] implementation using * [ShutdownHandler] implementation using
* Kotlin's [kotlin.system.exitProcess] method. * Kotlin's [exitProcess] method.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
@ -45,7 +45,7 @@ class KotlinShutdownHandler private constructor() : ShutdownHandler {
val instance: KotlinShutdownHandler = KotlinShutdownHandler() val instance: KotlinShutdownHandler = KotlinShutdownHandler()
} }
override fun exit(exitcode: Byte) { override fun exit(exitcode: UByte) {
exitProcess(exitcode.toInt()) exitProcess(exitcode.toInt())
} }
} }

View file

@ -18,9 +18,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation package de.staropensource.engine.base.implementation.logging
import de.staropensource.engine.logging.implementable.OneCycleFormatter import de.staropensource.engine.base.implementable.logging.OneCycleFormatter
import kotlin.text.iterator
/** /**
* Swallows all formatting tags * Swallows all formatting tags

View file

@ -0,0 +1,38 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.base.implementation.logging.adapter
import de.staropensource.engine.base.implementable.logging.Adapter
import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.base.utility.FileAccess
/**
* [Adapter] for writing log
* output to the specific file.
*
* @see Adapter
* @since v1-alpha10
*/
open class FileWriteAdapter(var location: FileAccess): Adapter {
override fun handle(call: Call, format: String) {
location.appendString("\n${format}")
}
}

View file

@ -18,14 +18,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation package de.staropensource.engine.base.implementation.logging.adapter
import de.staropensource.engine.logging.implementable.Adapter import de.staropensource.engine.base.implementable.logging.Adapter
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
/** /**
* Uses Kotlin's [println] * [Adapter] for printing messages
* method to print log messages. * using Kotlin's [println] method.
* *
* @see Adapter * @see Adapter
* @since v1-alpha10 * @since v1-alpha10

View file

@ -19,8 +19,10 @@
*/ */
/** /**
* StarOpenSource's logging system. * Implementations of the [Adapter] interface.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
package de.staropensource.engine.logging; package de.staropensource.engine.base.implementation.logging.adapter
import de.staropensource.engine.base.implementable.logging.Adapter

View file

@ -18,11 +18,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation.crashcategory package de.staropensource.engine.base.implementation.logging.crashcategory
import de.staropensource.engine.logging.implementable.CrashCategory import de.staropensource.engine.base.implementable.logging.CrashCategory
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.logging.type.ChannelSettings import de.staropensource.engine.base.type.logging.ChannelSettings
/** /**
* [CrashCategory] implementation * [CrashCategory] implementation

View file

@ -23,6 +23,6 @@
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
package de.staropensource.engine.logging.implementation.crashcategory package de.staropensource.engine.base.implementation.logging.crashcategory
import de.staropensource.engine.logging.implementable.CrashCategory import de.staropensource.engine.base.implementable.logging.CrashCategory

View file

@ -18,14 +18,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.implementation package de.staropensource.engine.base.implementation.logging.formatbuilder
import de.staropensource.engine.logging.Logger import de.staropensource.engine.base.EngineConfiguration
import de.staropensource.engine.logging.LoggerConfiguration import de.staropensource.engine.base.logging.Logger
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.implementable.logging.FormatBuilder
import de.staropensource.engine.logging.type.Feature import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.logging.implementable.FormatBuilder import de.staropensource.engine.base.type.logging.Feature
import de.staropensource.engine.logging.type.Level import de.staropensource.engine.base.type.logging.Level
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
@ -40,7 +40,7 @@ import kotlinx.datetime.toLocalDateTime
* @param call [Call] to build a format for * @param call [Call] to build a format for
* @since v1-alpha10 * @since v1-alpha10
*/ */
class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) { open class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) {
override fun toString(): String { override fun toString(): String {
val format: StringBuilder = StringBuilder() val format: StringBuilder = StringBuilder()
@ -69,11 +69,11 @@ class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) {
* @param format [StringBuilder] to operate on * @param format [StringBuilder] to operate on
* @since v1-alpha10 * @since v1-alpha10
*/ */
private fun addRuntime(format: StringBuilder) { protected fun addRuntime(format: StringBuilder) {
if (enabledFeatures.contains(Feature.RUNTIME)) if (enabledFeatures.contains(Feature.RUNTIME))
format format
.append("[") .append("[")
.append(Logger.initializationTime) .append(Logger.Companion.initializationTime)
.append("ms") .append("ms")
.append("] ") .append("] ")
} }
@ -84,8 +84,8 @@ class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) {
* @param format [StringBuilder] to operate on * @param format [StringBuilder] to operate on
* @since v1-alpha10 * @since v1-alpha10
*/ */
private fun addDateTime(format: StringBuilder) { protected fun addDateTime(format: StringBuilder) {
val datetime: LocalDateTime = Clock.System.now().toLocalDateTime(LoggerConfiguration.featureDateTimeTZ) val datetime: LocalDateTime = Clock.System.now().toLocalDateTime(EngineConfiguration.timezone)
if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME)) if (enabledFeatures.contains(Feature.DATE) || enabledFeatures.contains(Feature.TIME))
format.append("[") format.append("[")
@ -115,7 +115,7 @@ class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) {
* @param format [StringBuilder] to operate on * @param format [StringBuilder] to operate on
* @since v1-alpha10 * @since v1-alpha10
*/ */
private fun addLevel(format: StringBuilder) { protected fun addLevel(format: StringBuilder) {
if (enabledFeatures.contains(Feature.LEVEL)) if (enabledFeatures.contains(Feature.LEVEL))
format.append( format.append(
when (call.level) { when (call.level) {
@ -138,7 +138,7 @@ class SOSLSv2FormatBuilder(call: Call) : FormatBuilder(call) {
* @param format [StringBuilder] to operate on * @param format [StringBuilder] to operate on
* @since v1-alpha10 * @since v1-alpha10
*/ */
private fun addOriginAndMetadata(format: StringBuilder) { protected fun addOriginAndMetadata(format: StringBuilder) {
if (enabledFeatures.contains(Feature.ORIGIN)) { if (enabledFeatures.contains(Feature.ORIGIN)) {
format.append(call.origin) format.append(call.origin)

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
/**
* Implementations of the [FormatBuilder] abstract class.
*
* @since v1-alpha10
*/
package de.staropensource.engine.base.implementation.logging.formatbuilder
import de.staropensource.engine.base.implementable.logging.FormatBuilder

View file

@ -0,0 +1,29 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
/**
* Implementations of various
* interfaces and abstract classes
* found in the [de.staropensource.engine.base.implementable.logging]
* package of the logging system.
*
* @since v1-alpha10
*/
package de.staropensource.engine.base.implementation.logging

View file

@ -18,14 +18,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging package de.staropensource.engine.base.logging
import de.staropensource.engine.logging.implementable.Adapter import de.staropensource.engine.base.Engine
import de.staropensource.engine.logging.implementable.CrashCategory import de.staropensource.engine.base.EngineConfiguration
import de.staropensource.engine.logging.implementable.Formatter import de.staropensource.engine.base.implementable.logging.Adapter
import de.staropensource.engine.logging.implementation.KotlinShutdownHandler import de.staropensource.engine.base.implementable.logging.CrashCategory
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.implementable.logging.Formatter
import de.staropensource.engine.logging.type.ChannelSettings import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.base.type.logging.ChannelSettings
/** /**
* Handles crashes. * Handles crashes.
@ -50,7 +51,9 @@ class CrashHandler private constructor() {
internal fun handle(call: Call, throwable: Throwable? = null, fatal: Boolean = true) { internal fun handle(call: Call, throwable: Throwable? = null, fatal: Boolean = true) {
val format: StringBuilder = StringBuilder() val format: StringBuilder = StringBuilder()
var formatFinalized: String? = null var formatFinalized: String? = null
val channelconf: ChannelSettings? = LoggerConfiguration.channelSettings[call.channel] val channelconf: ChannelSettings? = EngineConfiguration.logChannelSettings[call.channel]
Engine.state = Engine.State.CRASHED
if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean) if (ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean)
format.append("<red>") format.append("<red>")
@ -60,7 +63,7 @@ class CrashHandler private constructor() {
.append(ChannelSettings.getSetting(channelconf, "applicationName")) .append(ChannelSettings.getSetting(channelconf, "applicationName"))
.append(" crashed!\nIf you're a user of this application, then please report this crash to the developer.") .append(" crashed!\nIf you're a user of this application, then please report this crash to the developer.")
for (category: CrashCategory in LoggerConfiguration.crashCategories) for (category: CrashCategory in EngineConfiguration.logCrashCategories)
if (category.check()) if (category.check())
format format
.append("\n\n${category.getName()}") .append("\n\n${category.getName()}")
@ -78,11 +81,13 @@ class CrashHandler private constructor() {
else else
format.toString() format.toString()
// Pass format to adapter // Pass format to adapters
(ChannelSettings.getSetting(channelconf, "adapter") as Adapter).handle(call, formatFinalized) @Suppress("UNCHECKED_CAST")
for (adapter: Adapter in ChannelSettings.getSetting(channelconf, "adapters") as Set<Adapter>)
adapter.handle(call, formatFinalized)
if (fatal) if (fatal)
(LoggerConfiguration.shutdownHandler ?: KotlinShutdownHandler.instance).exit(exitcode = 69) Engine.shutdownAfterCrash()
} }
/** /**

View file

@ -18,10 +18,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging package de.staropensource.engine.base.logging
import de.staropensource.engine.logging.implementable.Filter import de.staropensource.engine.base.implementable.logging.Filter
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
/** /**
* Handles call filtering. * Handles call filtering.

View file

@ -18,10 +18,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging package de.staropensource.engine.base.logging
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.EngineConfiguration
import de.staropensource.engine.logging.type.Level import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.base.type.logging.Level
import kotlinx.datetime.Clock import kotlinx.datetime.Clock
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
@ -130,7 +131,7 @@ class Logger {
if (Processor.check(call)) if (Processor.check(call))
return return
if (LoggerConfiguration.threadingHandler?.queue(call) == null) if (EngineConfiguration.logThreadingHandler?.queue(call) == null)
Processor.process(call) Processor.process(call)
} }
} }
@ -215,7 +216,7 @@ class Logger {
/** /**
* Flushes all log messages. * Flushes all log messages.
* *
* Tells the configured [ThreadingHandler] * Tells the configured [LoggerThreadingHandler]
* to flush all log messages to output * to flush all log messages to output
* immediately. * immediately.
* *
@ -225,6 +226,6 @@ class Logger {
* @since v1-alpha10 * @since v1-alpha10
*/ */
fun flush() { fun flush() {
LoggerConfiguration.threadingHandler?.flush() EngineConfiguration.logThreadingHandler?.flush()
} }
} }

View file

@ -18,9 +18,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging package de.staropensource.engine.base.logging
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
/** /**
* Handles multithreading. * Handles multithreading.
@ -31,7 +31,7 @@ import de.staropensource.engine.logging.type.Call
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
interface ThreadingHandler { interface LoggerThreadingHandler {
// -----> Threading management // -----> Threading management
/** /**
* Starts this threading handler. * Starts this threading handler.

View file

@ -18,16 +18,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging package de.staropensource.engine.base.logging
import de.staropensource.engine.logging.implementable.Adapter import de.staropensource.engine.base.EngineConfiguration
import de.staropensource.engine.logging.implementable.FormatBuilder import de.staropensource.engine.base.implementable.logging.Adapter
import de.staropensource.engine.logging.implementable.Formatter import de.staropensource.engine.base.implementable.logging.FormatBuilder
import de.staropensource.engine.logging.implementation.SOSLSv2FormatBuilder import de.staropensource.engine.base.implementable.logging.Formatter
import de.staropensource.engine.logging.type.Call import de.staropensource.engine.base.type.logging.Call
import de.staropensource.engine.logging.type.ChannelSettings import de.staropensource.engine.base.type.logging.ChannelSettings
import de.staropensource.engine.logging.type.Feature import de.staropensource.engine.base.type.logging.Feature
import de.staropensource.engine.logging.type.OperationMode import de.staropensource.engine.base.type.logging.OperationMode
import kotlin.reflect.full.primaryConstructor import kotlin.reflect.full.primaryConstructor
/** /**
@ -59,10 +59,10 @@ class Processor private constructor() {
fun check(call: Call): Boolean { fun check(call: Call): Boolean {
return ( return (
// Check logger mode // Check logger mode
LoggerConfiguration.mode == OperationMode.NOOP EngineConfiguration.logMode == OperationMode.NOOP
// Check if level is allowed // Check if level is allowed
|| !LoggerConfiguration.levels.contains(call.level) || !EngineConfiguration.logLevels.contains(call.level)
// Run against filters // Run against filters
|| Filterer.run(call) || Filterer.run(call)
@ -80,10 +80,10 @@ class Processor private constructor() {
* 4. pass the finalized format to the configured [de.staropensource.engine.logging.implementable.Adapter]. * 4. pass the finalized format to the configured [de.staropensource.engine.logging.implementable.Adapter].
* *
* Invoked by the configured * Invoked by the configured
* [ThreadingHandler]. * [LoggerThreadingHandler].
* *
* @param call [Call] metadata * @param call [Call] metadata
* @see LoggerConfiguration.threadingHandler * @see EngineConfiguration.logThreadingHandler
* @see ChannelSettings.formatter * @see ChannelSettings.formatter
* @see ChannelSettings.adapter * @see ChannelSettings.adapter
* @since v1-alpha10 * @since v1-alpha10
@ -93,14 +93,15 @@ class Processor private constructor() {
fun process(call: Call) { fun process(call: Call) {
val format: FormatBuilder val format: FormatBuilder
var formatFinalized: String = "" var formatFinalized: String = ""
val channelconf: ChannelSettings? = LoggerConfiguration.channelSettings[call.channel] val channelconf: ChannelSettings? = EngineConfiguration.logChannelSettings[call.channel]
var message: String = call.message var message: String = call.message
// Set 'format' // Set 'format'
try { try {
format = (LoggerConfiguration.formatBuilder ?: SOSLSv2FormatBuilder::class).primaryConstructor!!.call(call) format = (EngineConfiguration.logFormatBuilder).primaryConstructor!!.call(call)
} catch (throwable: Throwable) { } catch (throwable: Throwable) {
println("Logger system failure: Configured FormatBuilder implementation '" + ((LoggerConfiguration.formatBuilder ?: SOSLSv2FormatBuilder::class).qualifiedName ?: "<anonymous>") + "' does not have a primary 'constructor(call: Call)'. Log messages cannot be processed.") println("Logger system failure: Configured FormatBuilder implementation '" + ((EngineConfiguration.logFormatBuilder).qualifiedName ?: "<anonymous>") + "' does not have a primary 'constructor(call: Call)'. Log messages cannot be processed.")
// TODO print exception?
return return
} }
@ -109,7 +110,7 @@ class Processor private constructor() {
return return
// Build format // Build format
for (feature: Feature in LoggerConfiguration.features) for (feature: Feature in EngineConfiguration.logFeatures.toSet())
if (feature != Feature.FORMATTING) if (feature != Feature.FORMATTING)
format.addFeature(feature) format.addFeature(feature)
@ -120,7 +121,7 @@ class Processor private constructor() {
) message = message.replace("<", "\\<") ) message = message.replace("<", "\\<")
if ( if (
ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean ChannelSettings.getSetting(channelconf, "permitFormatting") as Boolean
&& LoggerConfiguration.features.contains(Feature.FORMATTING) && EngineConfiguration.logFeatures.contains(Feature.FORMATTING)
) format.addFeature(Feature.FORMATTING) ) format.addFeature(Feature.FORMATTING)
// Set message // Set message
@ -132,8 +133,10 @@ class Processor private constructor() {
else else
format.toString() format.toString()
// Pass format to adapter // Pass format to adapters
(ChannelSettings.getSetting(channelconf, "adapter") as Adapter).handle(call, formatFinalized) @Suppress("UNCHECKED_CAST")
for (adapter: Adapter in ChannelSettings.getSetting(channelconf, "adapters") as Set<Adapter>)
adapter.handle(call, formatFinalized)
} }
} }
} }

View file

@ -19,8 +19,8 @@
*/ */
/** /**
* Various data types. * sos!engine's logging system.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
package de.staropensource.engine.logging.type; package de.staropensource.engine.base.logging

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.type package de.staropensource.engine.base.type.logging
/** /**
* Holds information about log calls. * Holds information about log calls.

View file

@ -1,9 +1,29 @@
package de.staropensource.engine.logging.type /*
* 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 <https://www.gnu.org/licenses/>.
*/
import de.staropensource.engine.logging.implementable.Adapter package de.staropensource.engine.base.type.logging
import de.staropensource.engine.logging.implementable.Formatter
import de.staropensource.engine.logging.implementation.NoOperationFormatter import de.staropensource.engine.base.implementable.logging.Adapter
import de.staropensource.engine.logging.implementation.PrintlnAdapter import de.staropensource.engine.base.implementable.logging.Formatter
import de.staropensource.engine.base.implementation.logging.NoOperationFormatter
import de.staropensource.engine.base.implementation.logging.adapter.PrintlnAdapter
/** /**
* Holds the configuration of one * Holds the configuration of one
@ -23,7 +43,7 @@ data class ChannelSettings(
private val permitFormatting: Boolean? = null, private val permitFormatting: Boolean? = null,
private val applicationName: String? = null, private val applicationName: String? = null,
private val formatter: Formatter? = null, private val formatter: Formatter? = null,
private val adapter: Adapter? = null, private val adapters: Set<Adapter>? = null,
) { ) {
/** /**
* Companion object of [ChannelSettings]. * Companion object of [ChannelSettings].
@ -54,7 +74,7 @@ data class ChannelSettings(
permitFormatting = null, permitFormatting = null,
applicationName = null, applicationName = null,
formatter = null, formatter = null,
adapter = null, adapters = null,
) )
/** /**
@ -74,7 +94,7 @@ data class ChannelSettings(
"permitFormatting" -> (settings?.permitFormatting ?: global.permitFormatting) != false "permitFormatting" -> (settings?.permitFormatting ?: global.permitFormatting) != false
"applicationName" -> settings?.applicationName ?: global.applicationName ?: "This application" "applicationName" -> settings?.applicationName ?: global.applicationName ?: "This application"
"formatter" -> settings?.formatter ?: global.formatter ?: NoOperationFormatter.instance "formatter" -> settings?.formatter ?: global.formatter ?: NoOperationFormatter.instance
"adapter" -> settings?.adapter ?: global.adapter ?: PrintlnAdapter.instance "adapters" -> settings?.adapters ?: global.adapters ?: setOf(PrintlnAdapter.instance)
else -> null else -> null
} }
} }

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.type package de.staropensource.engine.base.type.logging
/** /**
* Represents log formatting enabledFeatures. * Represents log formatting enabledFeatures.

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.type package de.staropensource.engine.base.type.logging
/** /**
* Represents log call priorities. * Represents log call priorities.

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.staropensource.engine.logging.type package de.staropensource.engine.base.type.logging
/** /**
* Represents how the logger functions. * Represents how the logger functions.

View file

@ -19,8 +19,8 @@
*/ */
/** /**
* Interfaces and abstract classes. * Data types used by the logging system.
* *
* @since v1-alpha10 * @since v1-alpha10
*/ */
package de.staropensource.engine.logging.implementable package de.staropensource.engine.base.type.logging

View file

@ -1,167 +0,0 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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
import kotlin.reflect.KClass
/**
* The configuration of this logging system.
*
* @since v1-alpha10
*/
class LoggerConfiguration private constructor() {
/**
* Companion object of [LoggerConfiguration].
*
* @since v1-alpha10
*/
companion object {
// -----> Logging settings
/**
* Controls how [Logger]s should function.
*
* @since v1-alpha10
*/
@JvmStatic
var mode: OperationMode = OperationMode.NORMAL
/**
* Determines which levels are
* allowed to be processed.
*
* @since v1-alpha10
*/
@JvmStatic
var levels: MutableSet<Level> = mutableSetOf(
Level.INFORMATIONAL,
Level.WARNING,
Level.ERROR,
Level.CRASH
)
/**
* Determines which log enabledFeatures shall
* be displayed in the final output.
*
* @since v1-alpha10
*/
@JvmStatic
var features: MutableSet<Feature> = mutableSetOf(
Feature.FORMATTING,
Feature.TIME,
Feature.LEVEL,
Feature.ORIGIN,
Feature.LINE_NUMBER,
)
/**
* Controls how fast the logging thread
* shall wait until processing the log
* queue after it has been processed
* minus the processing time.
*
* This only takes effect if an
* appropriate [ThreadingHandler]
* is configured.
*
* @since v1-alpha10
*/
@JvmStatic
var threadPollingDelay: Int = 5
/**
* Contains log channel settings.
*
* @since v1-alpha10
*/
@JvmStatic
var channelSettings: MutableMap<String, ChannelSettings> = mutableMapOf()
/**
* Contains all registered [CrashCategory]s.
*
* @since v1-alpha10
*/
@JvmStatic
var crashCategories: LinkedHashSet<CrashCategory> = 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<FormatBuilder>? = 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
/**
* Controls which [TimeZone] to use
* for [Feature.DATE] & [Feature.TIME].
*
* @since v1-alpha10
*/
var featureDateTimeTZ: TimeZone = TimeZone.currentSystemDefault()
}
}

View file

@ -1,22 +0,0 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.staropensource.engine.logging.type

View file

@ -21,7 +21,7 @@
package de.staropensource.engine.testapp package de.staropensource.engine.testapp
import de.staropensource.engine.base.Engine import de.staropensource.engine.base.Engine
import de.staropensource.engine.logging.Logger import de.staropensource.engine.base.logging.Logger
/** /**
* Testing program for the StarOpenSource Engine. * Testing program for the StarOpenSource Engine.
@ -53,7 +53,9 @@ class Main private constructor() {
logger.info("Hello World!") logger.info("Hello World!")
// Shutdown engine // Shutdown engine
Engine.shutdown() Engine.shutdownFinal()
logger.info("You shouldn't see this")
} }
} }
} }