fix(base): Separate bootstrap stage with fallback JPL->JUL->our JPL logger redirection
All checks were successful
ci/woodpecker/push/docs Pipeline was successful
ci/woodpecker/push/jfmod Pipeline was successful

This commit is contained in:
Johannes Frohnmeyer 2024-03-15 11:43:44 +01:00
parent 7080cfbff2
commit 3c691ffe86
Signed by: Johannes
GPG Key ID: E76429612C2929F4
3 changed files with 121 additions and 1 deletions

View File

@ -1,9 +1,11 @@
package io.gitlab.jfronny.libjf;
import io.gitlab.jfronny.commons.logger.DelegateLogger;
import io.gitlab.jfronny.commons.logger.HotswapLoggerFinder;
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
import io.gitlab.jfronny.libjf.log.JULBridge;
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
import org.slf4j.LoggerFactory;
@ -23,10 +25,24 @@ public class LibJf implements PreLaunchEntrypoint {
}
private static boolean setup = false;
private static boolean bootstrapped = false;
public static void setup() {
bootstrap();
if (!setup) {
setup = true;
HotswapLoggerFinder.updateAllStrategies((name, module, level) -> new SLF4JPlatformLogger(LoggerFactory.getLogger(name)));
}
}
public static void bootstrap() {
if (!bootstrapped) {
bootstrapped = true;
if (LOGGER instanceof DelegateLogger) {
LOGGER.debug("HotswapLoggerFinder was loaded successfully. No need to install JULBridge.");
} else {
JULBridge.install();
LOGGER.debug("JULBridge was installed. If available in your launcher, please enable the ServiceLoader fix for better performance.");
}
}
}
}

View File

@ -0,0 +1,98 @@
package io.gitlab.jfronny.libjf.log;
import io.gitlab.jfronny.commons.StringFormatter;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
/**
* Based on SLF4JBridgeHandler, modified for LibJF.
*/
public class JULBridge extends Handler {
public static void install() {
var rootLogger = getRootLogger();
rootLogger.addHandler(new JULBridge());
boolean bridgeFound = false;
for (Handler handler : rootLogger.getHandlers()) {
if (handler instanceof JULBridge) {
bridgeFound = true;
continue;
}
rootLogger.removeHandler(handler);
}
if (!bridgeFound) {
// Someone is wrapping our handlers. No matter, just add it again.
rootLogger.addHandler(new JULBridge());
}
}
private static java.util.logging.Logger getRootLogger() {
return LogManager.getLogManager().getLogger("");
}
private JULBridge() {
}
@Override
public void flush() {
// Do nothing
}
@Override
public void close() {
// Do nothing
}
private final Module module = JULBridge.class.getClassLoader().getUnnamedModule();
private final EarlyLoggerSetup loggerFinder = new EarlyLoggerSetup();
private System.Logger getLoggerFor(LogRecord record) {
return loggerFinder.getLogger(Objects.requireNonNullElse(record.getLoggerName(), ""), module);
}
private static System.Logger.Level getLevel(LogRecord record) {
System.Logger.Level level;
if (record.getLevel().equals(Level.OFF)) level = System.Logger.Level.OFF;
else if (record.getLevel().equals(Level.ALL)) level = System.Logger.Level.ALL;
else if (record.getLevel().intValue() >= Level.SEVERE.intValue()) {
level = System.Logger.Level.ERROR;
} else if (record.getLevel().intValue() >= Level.WARNING.intValue()) {
level = System.Logger.Level.WARNING;
} else if (record.getLevel().intValue() >= Level.INFO.intValue()) {
level = System.Logger.Level.INFO;
} else {
level = System.Logger.Level.DEBUG;
}
return level;
}
@Override
public void publish(LogRecord record) {
if (record == null) return;
System.Logger logger = getLoggerFor(record);
System.Logger.Level level = getLevel(record);
String message = record.getMessage();
ResourceBundle bundle = null;
if (message == null) message = "";
else bundle = record.getResourceBundle();
Object[] params = record.getParameters();
Throwable thrown = record.getThrown();
if (thrown == null) {
logger.log(level, bundle, message, params);
} else {
if (params != null && params.length > 0) {
String[] strings = new String[params.length];
for (int i = 0; i < params.length; i++) {
strings[i] = StringFormatter.toString(params[i]);
}
message = new MessageFormat(message).format(strings);
}
logger.log(level, bundle, message, thrown);
}
}
}

View File

@ -26,7 +26,13 @@ public class JfConfigSafe implements PreLaunchEntrypoint {
}
}
TRANSLATION_SUPPLIER = s -> {
String translated = Language.getInstance().get(s);
String translated;
try {
translated = Language.getInstance().get(s);
} catch (Throwable t) {
LibJf.LOGGER.debug("Failed to translate key " + s, t);
return null;
}
return translated.equals(s) ? null : translated;
};
}