Add InitLogger and startup logging

This commit is contained in:
JeremyStar™ 2024-08-17 12:41:53 +02:00
parent 78b12dee67
commit 8f12e8b0c8
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
7 changed files with 274 additions and 35 deletions

View file

@ -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();
}

View file

@ -314,19 +314,20 @@ public final class EngineInformation {
/**
* Updates all variables.
* <p>
* 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;
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View file

@ -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);
}
/**

View file

@ -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} */

View file

@ -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} */

View file

@ -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.
* <p>
* 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
*/