fix(base): Separate bootstrap stage with fallback JPL->JUL->our JPL logger redirection
This commit is contained in:
parent
7080cfbff2
commit
3c691ffe86
|
@ -1,9 +1,11 @@
|
||||||
package io.gitlab.jfronny.libjf;
|
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.HotswapLoggerFinder;
|
||||||
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
||||||
import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
|
import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
|
||||||
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
||||||
|
import io.gitlab.jfronny.libjf.log.JULBridge;
|
||||||
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
|
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
|
||||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -23,10 +25,24 @@ public class LibJf implements PreLaunchEntrypoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean setup = false;
|
private static boolean setup = false;
|
||||||
|
private static boolean bootstrapped = false;
|
||||||
public static void setup() {
|
public static void setup() {
|
||||||
|
bootstrap();
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
setup = true;
|
setup = true;
|
||||||
HotswapLoggerFinder.updateAllStrategies((name, module, level) -> new SLF4JPlatformLogger(LoggerFactory.getLogger(name)));
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,13 @@ public class JfConfigSafe implements PreLaunchEntrypoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRANSLATION_SUPPLIER = s -> {
|
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;
|
return translated.equals(s) ? null : translated;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user