forked from StarOpenSource/Engine
Add log rules
This commit is contained in:
parent
9e4cfee89a
commit
79dbc65f63
3 changed files with 152 additions and 10 deletions
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.classes.logging;
|
||||||
|
|
||||||
|
import de.staropensource.sosengine.base.types.LogIssuer;
|
||||||
|
import de.staropensource.sosengine.base.types.LogLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a rule used during logging to allow or prevent certain log calls.
|
||||||
|
*
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({ "unused", "JavadocDeclaration", "JavadocBlankLines" })
|
||||||
|
@Getter
|
||||||
|
public class LogRule {
|
||||||
|
/**
|
||||||
|
* Determines if the log rule should disallow or permit matching log calls.
|
||||||
|
*
|
||||||
|
* @see LogRuleType
|
||||||
|
* @since 1-alpha1
|
||||||
|
*
|
||||||
|
* -- GETTER --
|
||||||
|
* Returns if the log rule should disallow or permit matching log calls.
|
||||||
|
*
|
||||||
|
* @return rule type
|
||||||
|
* @see LogRuleType
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
private final LogRuleType type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public LogRule(@NotNull LogRuleType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates the rule and returns if the rule matches.
|
||||||
|
*
|
||||||
|
* @param issuer issuer
|
||||||
|
* @param level log level
|
||||||
|
* @param message raw message
|
||||||
|
*/
|
||||||
|
public boolean evaluate(@NotNull LogIssuer issuer, @NotNull LogLevel level, @NotNull String message) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.classes.logging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for determining if a {@link LogRule} should allow (whitelist) or prevent (blacklist) log call processing.
|
||||||
|
*
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({ "unused" })
|
||||||
|
public enum LogRuleType {
|
||||||
|
/**
|
||||||
|
* Indicates that log calls matching this rule will always be allowed, even if blacklisted.
|
||||||
|
*
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
WHITELIST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that log calls matching this will always be disallowed except when whitelisted.
|
||||||
|
*
|
||||||
|
* @see LogRuleType#WHITELIST
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
BLACKLIST
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ package de.staropensource.sosengine.base.logging;
|
||||||
|
|
||||||
import de.staropensource.sosengine.base.Engine;
|
import de.staropensource.sosengine.base.Engine;
|
||||||
import de.staropensource.sosengine.base.EngineConfiguration;
|
import de.staropensource.sosengine.base.EngineConfiguration;
|
||||||
|
import de.staropensource.sosengine.base.classes.logging.LogRule;
|
||||||
|
import de.staropensource.sosengine.base.classes.logging.LogRuleType;
|
||||||
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
|
import de.staropensource.sosengine.base.classes.logging.LoggerImpl;
|
||||||
import de.staropensource.sosengine.base.classes.Placeholder;
|
import de.staropensource.sosengine.base.classes.Placeholder;
|
||||||
import de.staropensource.sosengine.base.events.LogEvent;
|
import de.staropensource.sosengine.base.events.LogEvent;
|
||||||
|
@ -94,6 +96,20 @@ public final class Logger {
|
||||||
*/
|
*/
|
||||||
private static final LinkedList<QueuedLogMessage> queuedMessages = new LinkedList<>();
|
private static final LinkedList<QueuedLogMessage> queuedMessages = new LinkedList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains all active {@link LogRule}s.
|
||||||
|
*
|
||||||
|
* @since 1-alpha1
|
||||||
|
*
|
||||||
|
* -- GETTER --
|
||||||
|
* Returns all active {@link LogRule}s.
|
||||||
|
*
|
||||||
|
* @return active rules
|
||||||
|
* @since 1-alpha1
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private static final List<LogRule> activeRules = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -109,24 +125,25 @@ public final class Logger {
|
||||||
*/
|
*/
|
||||||
public static void startLoggingThread() {
|
public static void startLoggingThread() {
|
||||||
if (loggingThread == null) {
|
if (loggingThread == null) {
|
||||||
|
// Logging thread not defined, create and start new one
|
||||||
loggingThread = Thread.ofPlatform().start(() -> {
|
loggingThread = Thread.ofPlatform().start(() -> {
|
||||||
while (true) {
|
while (true) { // Run in loop
|
||||||
|
// Stop thread when engine is shutting down
|
||||||
if (Engine.getInstance().isShuttingDown())
|
if (Engine.getInstance().isShuttingDown())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Process all log messages
|
||||||
flushLogMessages();
|
flushLogMessages();
|
||||||
|
|
||||||
|
// Sleep for whatever has been configured
|
||||||
try {
|
try {
|
||||||
//noinspection BusyWait
|
//noinspection BusyWait
|
||||||
Thread.sleep(EngineConfiguration.getInstance().getLoggerPollingSpeed());
|
Thread.sleep(EngineConfiguration.getInstance().getLoggerPollingSpeed());
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {}
|
||||||
}
|
|
||||||
|
|
||||||
if (Engine.getInstance().isShuttingDown())
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// Restart logging thread if dead
|
||||||
if (!loggingThread.isAlive())
|
if (!loggingThread.isAlive())
|
||||||
loggingThread.start();
|
loggingThread.start();
|
||||||
}
|
}
|
||||||
|
@ -138,12 +155,15 @@ public final class Logger {
|
||||||
* @since 1-alpha1
|
* @since 1-alpha1
|
||||||
*/
|
*/
|
||||||
public static synchronized void flushLogMessages() {
|
public static synchronized void flushLogMessages() {
|
||||||
|
// Only execute code if queued messages list is not empty
|
||||||
if (!queuedMessages.isEmpty()) {
|
if (!queuedMessages.isEmpty()) {
|
||||||
|
// Clone queued messages and clear original to avoid issues
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
LinkedList<QueuedLogMessage> queuedMessagesCloned = (LinkedList<QueuedLogMessage>) queuedMessages.clone();
|
LinkedList<QueuedLogMessage> queuedMessagesCloned = (LinkedList<QueuedLogMessage>) queuedMessages.clone();
|
||||||
queuedMessages.clear();
|
queuedMessages.clear();
|
||||||
|
|
||||||
for (QueuedLogMessage queuedLogMessage : queuedMessagesCloned) {// Check if level is allowed
|
// Invoke processLogMessage method for every queued message
|
||||||
|
for (QueuedLogMessage queuedLogMessage : queuedMessagesCloned) {
|
||||||
processLogMessage(queuedLogMessage.getIssuer(), queuedLogMessage.getLevel(), queuedLogMessage.getMessage());
|
processLogMessage(queuedLogMessage.getIssuer(), queuedLogMessage.getLevel(), queuedLogMessage.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,13 +178,22 @@ public final class Logger {
|
||||||
* @since 1-alpha1
|
* @since 1-alpha1
|
||||||
*/
|
*/
|
||||||
private static void processLogMessage(@NotNull LogIssuer issuer, @NotNull LogLevel level, @NotNull String message) {
|
private static void processLogMessage(@NotNull LogIssuer issuer, @NotNull LogLevel level, @NotNull String message) {
|
||||||
|
// Check if level is allowed
|
||||||
if (level.compareTo(EngineConfiguration.getInstance().getLoggerLevel()) < 0)
|
if (level.compareTo(EngineConfiguration.getInstance().getLoggerLevel()) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Evaluate all active rules
|
||||||
|
for (LogRule rule : activeRules) {
|
||||||
|
if (rule.evaluate(issuer, level, message)) {
|
||||||
|
if (rule.getType() == LogRuleType.WHITELIST) break; // Continue processing
|
||||||
|
if (rule.getType() == LogRuleType.BLACKLIST) return; // Cancel processing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Template for now, final log message later
|
// Template for now, final log message later
|
||||||
String base = EngineConfiguration.getInstance().getLoggerTemplate();
|
String base = EngineConfiguration.getInstance().getLoggerTemplate();
|
||||||
|
|
||||||
// Execute LoggerImpl#prePlaceholder
|
// Invoke LoggerImpl#prePlaceholder
|
||||||
base = loggerImplementation.prePlaceholder(level, issuer, base);
|
base = loggerImplementation.prePlaceholder(level, issuer, base);
|
||||||
|
|
||||||
// Create list of temporary placeholders
|
// Create list of temporary placeholders
|
||||||
|
@ -183,14 +212,14 @@ public final class Logger {
|
||||||
// Replace placeholders
|
// Replace placeholders
|
||||||
base = PlaceholderEngine.getInstance().process(base, temporaryPlaceholders);
|
base = PlaceholderEngine.getInstance().process(base, temporaryPlaceholders);
|
||||||
|
|
||||||
// Execute LoggerImpl#postPlaceholder
|
// Invoke LoggerImpl#postPlaceholder
|
||||||
base = loggerImplementation.postPlaceholder(level, issuer, base);
|
base = loggerImplementation.postPlaceholder(level, issuer, base);
|
||||||
|
|
||||||
// Call event
|
// Call event
|
||||||
if (!issuer.getClazz().getName().equals("de.staropensource.sosengine.slf4j_compat.CompatibilityLogger"))
|
if (!issuer.getClazz().getName().equals("de.staropensource.sosengine.slf4j_compat.CompatibilityLogger"))
|
||||||
new LogEvent().callEvent(level, issuer, message);
|
new LogEvent().callEvent(level, issuer, message);
|
||||||
|
|
||||||
// Print log message
|
// Print log message by invoking LoggerImpl#print
|
||||||
loggerImplementation.print(level, issuer, base);
|
loggerImplementation.print(level, issuer, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +236,10 @@ public final class Logger {
|
||||||
if (Engine.getInstance() == null) return;
|
if (Engine.getInstance() == null) return;
|
||||||
|
|
||||||
if (EngineConfiguration.getInstance().isOptimizeLogging())
|
if (EngineConfiguration.getInstance().isOptimizeLogging())
|
||||||
|
// Optimizations enabled, add to message queue
|
||||||
queuedMessages.add(new QueuedLogMessage(issuer, level, message));
|
queuedMessages.add(new QueuedLogMessage(issuer, level, message));
|
||||||
else
|
else
|
||||||
|
// Optimizations disabled, print right away
|
||||||
processLogMessage(issuer, level, message);
|
processLogMessage(issuer, level, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue