diff --git a/base/src/main/java/de/staropensource/sosengine/base/Engine.java b/base/src/main/java/de/staropensource/sosengine/base/Engine.java
index 39492b87..96e4bb7d 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java
@@ -92,7 +92,7 @@ public final class Engine extends SubsystemClass {
* @see LoggerInstance
* @since v1-alpha0
*/
- private static LoggerInstance logger;
+ private static final LoggerInstance logger = new LoggerInstance.Builder().setClazz(Engine.class).setOrigin("ENGINE").setMetadata(EngineInformation.getVersioningCodename()).build();
/**
* Contains the engine state.
@@ -162,19 +162,18 @@ public final class Engine extends SubsystemClass {
return;
long initTime = Miscellaneous.measureExecutionTime(() -> {
- state = EngineState.STARTUP;
+ state = EngineState.EARLY_STARTUP;
- // Initialize engine configuration
new EngineConfiguration();
EngineConfiguration.getInstance().loadConfiguration();
+ logger.info("Initializing engine");
initializeClasses(); // Initialize classes
populateCrashContent(); // Populate crash content
cacheEvents(); // Cache event listeners
startThreads(); // Start threads
- // Set the logger instance
- logger = new LoggerInstance.Builder().setClazz(getClass()).setOrigin("ENGINE").setMetadata(EngineInformation.getVersioningCodename()).build();
+ state = EngineState.STARTUP;
// Perform automatic subsystem initialization
if (EngineConfiguration.getInstance().isOptimizeSubsystemInitialization()) {
@@ -199,9 +198,10 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha0
*/
private void initializeClasses() {
+ logger.verb("Initializing engine classes");
new PlaceholderEngine();
- EngineInformation.updateVariables();
+ EngineInformation.update();
}
/**
@@ -212,6 +212,8 @@ public final class Engine extends SubsystemClass {
*/
@SuppressWarnings({ "ExtractMethodRecommender" })
private void populateCrashContent() {
+ logger.diag("Populating crash content");
+
// Issuer
Map<@NotNull String, @NotNull String> crashContentIssuer = new LinkedHashMap<>();
crashContentIssuer.put("Code part", "%issuer_origin%");
@@ -261,6 +263,8 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha0
*/
private void cacheEvents() {
+ logger.diag("Caching events");
+
// Internal events
EventHelper.cacheEvent(InternalEngineShutdownEvent.class);
@@ -278,6 +282,8 @@ public final class Engine extends SubsystemClass {
* @since v1-alpha1
*/
public void startThreads() {
+ logger.diag("Starting threads");
+
Logger.startLoggingThread();
}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/data/information/EngineInformation.java b/base/src/main/java/de/staropensource/sosengine/base/data/information/EngineInformation.java
index 8f8d5f7b..b115a844 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/data/information/EngineInformation.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/data/information/EngineInformation.java
@@ -314,19 +314,20 @@ public final class EngineInformation {
/**
* Updates all variables.
*
- * This method does not need to be invoked, as the information provided by this
- * class is static (does not change) and is already populated at engine startup.
+ * This method does not need to be invoked manually, as the information provided by
+ * this class is static (does not change) and is already populated at engine startup.
*
* @since v1-alpha1
*/
- public static synchronized void updateVariables() {
+ public static synchronized void update() {
+ logger.diag("Updating engine information");
+
// Load properties from bundled gradle.properties
Properties gradleProperties = new Properties();
InputStream gradleStream = EngineInformation.class.getClassLoader().getResourceAsStream("sosengine-gradle.properties");
if (gradleStream == null) {
- System.out.println("Unable to load build information: The bundled gradle.properties file could not be found.");
- Engine.getInstance().shutdown(69);
+ logger.crash("Unable to load build information: The bundled gradle.properties file could not be found.");
return;
}
@@ -335,9 +336,7 @@ public final class EngineInformation {
gradleStream.close();
} catch (IOException exception) {
StackTraceParser parser = new StackTraceParser(exception);
- System.out.println("Unable to load build information: InputStream 'gradleStream' failed");
- System.out.println(parser.getHeader() + "\n" + parser.getStackTrace());
- Engine.getInstance().shutdown(69);
+ logger.crash("Unable to load build information: InputStream 'gradleStream' failed", exception);
return;
}
@@ -365,9 +364,7 @@ public final class EngineInformation {
gitStream.close();
} catch (IOException exception) {
StackTraceParser parser = new StackTraceParser(exception);
- System.out.println("Unable to load build information: InputStream 'gitStream' failed");
- System.out.println(parser.getHeader() + "\n" + parser.getStackTrace());
- Engine.getInstance().shutdown(69);
+ logger.crash("Unable to load build information: InputStream 'gitStream' failed", exception);
return;
}
}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/logging/InitLogger.java b/base/src/main/java/de/staropensource/sosengine/base/logging/InitLogger.java
new file mode 100644
index 00000000..685224af
--- /dev/null
+++ b/base/src/main/java/de/staropensource/sosengine/base/logging/InitLogger.java
@@ -0,0 +1,201 @@
+/*
+ * STAROPENSOURCE ENGINE SOURCE FILE
+ * Copyright (c) 2024 The StarOpenSource Engine Contributors
+ * Licensed under the GNU Affero General Public License v3
+ *
+ * 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.sosengine.base.logging;
+
+import de.staropensource.sosengine.base.EngineConfiguration;
+import de.staropensource.sosengine.base.internal.placeholders.logger.LogMessage;
+import de.staropensource.sosengine.base.internal.placeholders.logger.LogPath;
+import de.staropensource.sosengine.base.types.logging.LogLevel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Provides logging capabilities during engine startup.
+ *
+ * @since v1-alpha4
+ */
+public final class InitLogger {
+ /**
+ * Contains the logging template used during startup.
+ *
+ * @since v1-alpha4
+ */
+ private static final @NotNull String template = "%log_level% %log_path% %log_message%";
+
+ /**
+ * Constructs this class.
+ *
+ * @since v1-alpha4
+ */
+ public InitLogger() {}
+
+ /**
+ * {@link Logger#log(LogLevel, Class, String, String, String)} and {@link Logger#processLogMessage(LogLevel, Class, String, String, String)} combined into one method.
+ *
+ * @param level level
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ private static synchronized void log(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ // Dismiss if level is not allowed
+ if (level.compareTo(EngineConfiguration.getInstance().getLoggerLevel()) < 0)
+ return;
+
+ // Invoke LoggerImpl#prePlaceholder
+ String base = Logger.getLoggerImplementation().prePlaceholder(level, issuerClass, issuerOrigin, issuerMetadata, message, template);
+ if (base == null)
+ base = template;
+
+ // Replace placeholders
+ // This is done manually to avoid depending on PlaceholderEngine
+ base = new de.staropensource.sosengine.base.internal.placeholders.logger.LogLevel(level).replace(base);
+ base = new LogPath(issuerClass).replace(base);
+ base = new LogMessage(message).replace(base);
+
+ // Invoke LoggerImpl#postPlaceholder
+ base = Logger.getLoggerImplementation().postPlaceholder(level, issuerClass, issuerOrigin, issuerMetadata, message, base);
+
+ // Print log message by invoking LoggerImpl#print
+ Logger.getLoggerImplementation().print(level, issuerClass, issuerOrigin, issuerMetadata, message, base);
+ }
+
+ /**
+ * Prints a diagnostic message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void diag(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.DIAGNOSTIC, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Prints a verbose message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void verb(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.VERBOSE, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Prints a silent warning message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void sarn(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.SILENT_WARNING, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Prints an informational message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void info(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.INFORMATIONAL, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Prints a warning message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void warn(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.WARNING, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Prints an error message.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void error(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ log(LogLevel.ERROR, issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+
+ /**
+ * Crashes the entire engine.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @param throwable the throwable that caused this crash
+ * @param handled declares the throwable has handled, not causing the engine to shutdown
+ * @since v1-alpha4
+ */
+ public static void crash(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull Throwable throwable, boolean handled) {
+ Logger.crash(issuerClass, issuerOrigin, issuerMetadata, message, throwable, handled);
+ }
+
+ /**
+ * Crashes the entire engine.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @param throwable the throwable that caused this crash
+ * @since v1-alpha4
+ */
+ public static void crash(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull Throwable throwable) {
+ Logger.crash(issuerClass, issuerOrigin, issuerMetadata, message, throwable);
+ }
+
+ /**
+ * Crashes the entire engine.
+ *
+ * @param issuerClass class of the issuer
+ * @param issuerOrigin origin of the issuer
+ * @param issuerMetadata metadata about the issuer
+ * @param message message
+ * @since v1-alpha4
+ */
+ public static void crash(@NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message) {
+ Logger.crash(issuerClass, issuerOrigin, issuerMetadata, message);
+ }
+}
diff --git a/base/src/main/java/de/staropensource/sosengine/base/logging/LoggerInstance.java b/base/src/main/java/de/staropensource/sosengine/base/logging/LoggerInstance.java
index 60ba7277..2628bc69 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/logging/LoggerInstance.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/logging/LoggerInstance.java
@@ -19,6 +19,8 @@
package de.staropensource.sosengine.base.logging;
+import de.staropensource.sosengine.base.Engine;
+import de.staropensource.sosengine.base.types.EngineState;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -88,7 +90,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void diag(@NotNull String message) {
- Logger.diag(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.diag(clazz, origin, metadata, message);
+ else
+ Logger.diag(clazz, origin, metadata, message);
}
/**
@@ -98,7 +103,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void verb(@NotNull String message) {
- Logger.verb(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.verb(clazz, origin, metadata, message);
+ else
+ Logger.verb(clazz, origin, metadata, message);
}
/**
@@ -108,7 +116,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void sarn(@NotNull String message) {
- Logger.sarn(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.sarn(clazz, origin, metadata, message);
+ else
+ Logger.sarn(clazz, origin, metadata, message);
}
/**
@@ -118,7 +129,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void info(@NotNull String message) {
- Logger.info(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.info(clazz, origin, metadata, message);
+ else
+ Logger.info(clazz, origin, metadata, message);
}
/**
@@ -128,7 +142,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void warn(@NotNull String message) {
- Logger.warn(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.warn(clazz, origin, metadata, message);
+ else
+ Logger.warn(clazz, origin, metadata, message);
}
/**
@@ -138,7 +155,10 @@ public final class LoggerInstance {
* @since v1-alpha0
*/
public void error(@NotNull String message) {
- Logger.error(clazz, origin, metadata, message);
+ if (Engine.getInstance().getState() == EngineState.EARLY_STARTUP)
+ InitLogger.error(clazz, origin, metadata, message);
+ else
+ Logger.error(clazz, origin, metadata, message);
}
/**
diff --git a/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/PlainLoggerImplementation.java b/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/PlainLoggerImplementation.java
index 33a8a81f..3c804bb8 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/PlainLoggerImplementation.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/PlainLoggerImplementation.java
@@ -45,16 +45,14 @@ public class PlainLoggerImplementation implements LoggerImplementation {
/** {@inheritDoc} */
@Override
- public @NotNull String prePlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
- // No modifications necessary
- return format;
+ public @Nullable String prePlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
+ return null; // No modifications necessary
}
/** {@inheritDoc} */
@Override
public @NotNull String postPlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
- // No modifications necessary
- return format;
+ return format; // No modifications necessary
}
/** {@inheritDoc} */
diff --git a/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/RawLoggerImplementation.java b/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/RawLoggerImplementation.java
index f42cf52c..3807bc3a 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/RawLoggerImplementation.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/logging/implementation/RawLoggerImplementation.java
@@ -45,16 +45,14 @@ public class RawLoggerImplementation implements LoggerImplementation {
/** {@inheritDoc} */
@Override
- public @NotNull String prePlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
- // No modifications necessary
- return format;
+ public @Nullable String prePlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
+ return null; // No modifications necessary
}
/** {@inheritDoc} */
@Override
public @NotNull String postPlaceholder(@NotNull LogLevel level, @NotNull Class> issuerClass, @NotNull String issuerOrigin, @Nullable String issuerMetadata, @NotNull String message, @NotNull String format) {
- // No modifications necessary
- return format;
+ return format; // No modifications necessary
}
/** {@inheritDoc} */
diff --git a/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java b/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java
index 0af32cd7..034c7941 100644
--- a/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java
+++ b/base/src/main/java/de/staropensource/sosengine/base/types/EngineState.java
@@ -19,6 +19,9 @@
package de.staropensource.sosengine.base.types;
+import de.staropensource.sosengine.base.logging.InitLogger;
+import de.staropensource.sosengine.base.logging.Logger;
+
/**
* Determines in which state the engine is currently in.
*
@@ -35,9 +38,25 @@ public enum EngineState {
UNKNOWN,
/**
- * The engine is currently starting up.
+ * The engine is in early startup.
+ * The engine is largely uninitialized and
+ * the logging infrastructure is not yet ready
+ * to be used.
+ *
+ * This state is used to indicate that the
+ * {@link InitLogger} shall be used instead
+ * of {@link Logger}.
+ *
+ * @since v1-alpha4
+ */
+ EARLY_STARTUP,
+
+ /**
+ * The engine is starting up.
* Some parts of the engine may not be initialized
- * yet and may be unsafe to access.
+ * yet and may be unsafe to access. The logging
+ * infrastructure is ready to be used though and is
+ * safe to access.
*
* @since v1-alpha2
*/