Add InitLogger and startup logging
This commit is contained in:
parent
78b12dee67
commit
8f12e8b0c8
7 changed files with 274 additions and 35 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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} */
|
||||
|
|
|
@ -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} */
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue