mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Fix missing console logs with Geyser-Standalone gui present (#5376)
* Fix missing console logs with gui present * Properly redirect stdout & stderr & also redirect JUL
This commit is contained in:
@@ -40,4 +40,6 @@ tasks.named<JavaExec>("run") {
|
|||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
jvmArgs("-Dio.netty.leakDetection.level=PARANOID")
|
jvmArgs("-Dio.netty.leakDetection.level=PARANOID")
|
||||||
workingDir = dir
|
workingDir = dir
|
||||||
|
|
||||||
|
standardInput = System.`in`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,9 @@ import com.fasterxml.jackson.databind.introspect.AnnotatedField;
|
|||||||
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
|
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
|
||||||
import io.netty.util.ResourceLeakDetector;
|
import io.netty.util.ResourceLeakDetector;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecrell.terminalconsole.TerminalConsoleAppender;
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.core.Appender;
|
|
||||||
import org.apache.logging.log4j.core.Logger;
|
import org.apache.logging.log4j.core.Logger;
|
||||||
import org.apache.logging.log4j.core.appender.ConsoleAppender;
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.geysermc.geyser.GeyserBootstrap;
|
import org.geysermc.geyser.GeyserBootstrap;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
@@ -92,6 +89,9 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); // Can eat performance
|
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.DISABLED); // Can eat performance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
|
||||||
|
GeyserStandaloneLogger.setupStreams();
|
||||||
|
|
||||||
GeyserStandaloneBootstrap bootstrap = new GeyserStandaloneBootstrap();
|
GeyserStandaloneBootstrap bootstrap = new GeyserStandaloneBootstrap();
|
||||||
// Set defaults
|
// Set defaults
|
||||||
boolean useGuiOpts = bootstrap.useGui;
|
boolean useGuiOpts = bootstrap.useGui;
|
||||||
@@ -175,17 +175,10 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
@Override
|
@Override
|
||||||
public void onGeyserInitialize() {
|
public void onGeyserInitialize() {
|
||||||
log4jLogger = (Logger) LogManager.getRootLogger();
|
log4jLogger = (Logger) LogManager.getRootLogger();
|
||||||
for (Appender appender : log4jLogger.getAppenders().values()) {
|
|
||||||
// Remove the appender that is not in use
|
|
||||||
// Prevents multiple appenders/double logging and removes harmless errors
|
|
||||||
if ((useGui && appender instanceof TerminalConsoleAppender) || (!useGui && appender instanceof ConsoleAppender)) {
|
|
||||||
log4jLogger.removeAppender(appender);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useGui && gui == null) {
|
if (useGui && gui == null) {
|
||||||
gui = new GeyserStandaloneGUI(geyserLogger);
|
gui = new GeyserStandaloneGUI(geyserLogger);
|
||||||
gui.redirectSystemStreams();
|
gui.addGuiAppender();
|
||||||
gui.startUpdateThread();
|
gui.startUpdateThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +191,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
public void onGeyserEnable() {
|
public void onGeyserEnable() {
|
||||||
try {
|
try {
|
||||||
File configFile = FileUtils.fileOrCopiedFromResource(new File(configFilename), "config.yml",
|
File configFile = FileUtils.fileOrCopiedFromResource(new File(configFilename), "config.yml",
|
||||||
(x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
(x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
||||||
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
|
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
|
||||||
|
|
||||||
handleArgsConfigOptions();
|
handleArgsConfigOptions();
|
||||||
@@ -246,9 +239,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
|
|
||||||
geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
|
geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
|
||||||
|
|
||||||
if (!useGui) {
|
geyserLogger.start();
|
||||||
geyserLogger.start(); // Throws an error otherwise
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -261,7 +252,8 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
Class<?> graphicsEnv = Class.forName("java.awt.GraphicsEnvironment");
|
Class<?> graphicsEnv = Class.forName("java.awt.GraphicsEnvironment");
|
||||||
Method isHeadless = graphicsEnv.getDeclaredMethod("isHeadless");
|
Method isHeadless = graphicsEnv.getDeclaredMethod("isHeadless");
|
||||||
return (boolean) isHeadless.invoke(null);
|
return (boolean) isHeadless.invoke(null);
|
||||||
} catch (Exception ignore) { }
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -347,12 +339,12 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
|
|
||||||
// Get the ignored properties
|
// Get the ignored properties
|
||||||
Set<String> ignoredProperties = OBJECT_MAPPER.getSerializationConfig().getAnnotationIntrospector()
|
Set<String> ignoredProperties = OBJECT_MAPPER.getSerializationConfig().getAnnotationIntrospector()
|
||||||
.findPropertyIgnoralByName(OBJECT_MAPPER.getSerializationConfig() ,beanDescription.getClassInfo()).getIgnored();
|
.findPropertyIgnoralByName(OBJECT_MAPPER.getSerializationConfig(), beanDescription.getClassInfo()).getIgnored();
|
||||||
|
|
||||||
// Filter properties removing the ignored ones
|
// Filter properties removing the ignored ones
|
||||||
return properties.stream()
|
return properties.stream()
|
||||||
.filter(property -> !ignoredProperties.contains(property.getName()))
|
.filter(property -> !ignoredProperties.contains(property.getName()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,7 +28,10 @@ package org.geysermc.geyser.platform.standalone;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.core.config.Configurator;
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
|
import org.apache.logging.log4j.io.IoBuilder;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||||
@@ -39,6 +42,15 @@ import org.jline.reader.LineReaderBuilder;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, GeyserCommandSource {
|
public class GeyserStandaloneLogger extends SimpleTerminalConsole implements GeyserLogger, GeyserCommandSource {
|
||||||
|
private static final Logger logger = LogManager.getLogger("GeyserConsole");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up {@code System.out} and {@code System.err} to redirect to log4j.
|
||||||
|
*/
|
||||||
|
public static void setupStreams() {
|
||||||
|
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
||||||
|
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.ERROR).buildPrintStream());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LineReader buildReader(LineReaderBuilder builder) {
|
protected LineReader buildReader(LineReaderBuilder builder) {
|
||||||
|
|||||||
@@ -25,7 +25,14 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.platform.standalone.gui;
|
package org.geysermc.geyser.platform.standalone.gui;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.Logger;
|
||||||
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||||
|
import org.apache.logging.log4j.core.config.NullConfiguration;
|
||||||
|
import org.apache.logging.log4j.core.config.Property;
|
||||||
|
import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||||
|
import org.apache.logging.log4j.core.pattern.PatternFormatter;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.command.CommandRegistry;
|
import org.geysermc.geyser.command.CommandRegistry;
|
||||||
@@ -36,11 +43,16 @@ import javax.swing.*;
|
|||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import javax.swing.text.Document;
|
import javax.swing.text.Document;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -83,7 +95,8 @@ public class GeyserStandaloneGUI {
|
|||||||
// Remove Java UI look
|
// Remove Java UI look
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
} catch (Exception ignored) { }
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
// Show a confirm dialog on close
|
// Show a confirm dialog on close
|
||||||
frame.addWindowListener(new WindowAdapter() {
|
frame.addWindowListener(new WindowAdapter() {
|
||||||
@@ -181,7 +194,8 @@ public class GeyserStandaloneGUI {
|
|||||||
openButton.addActionListener(e -> {
|
openButton.addActionListener(e -> {
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().open(new File("./"));
|
Desktop.getDesktop().open(new File("./"));
|
||||||
} catch (IOException ignored) { }
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
fileMenu.add(openButton);
|
fileMenu.add(openButton);
|
||||||
|
|
||||||
@@ -245,29 +259,8 @@ public class GeyserStandaloneGUI {
|
|||||||
/**
|
/**
|
||||||
* Redirect the default io streams to the text pane
|
* Redirect the default io streams to the text pane
|
||||||
*/
|
*/
|
||||||
public void redirectSystemStreams() {
|
public void addGuiAppender() {
|
||||||
// Setup a new output stream to forward it to the text pane
|
new GUIAppender().start();
|
||||||
OutputStream out = new OutputStream() {
|
|
||||||
@Override
|
|
||||||
public void write(final int b) {
|
|
||||||
appendConsole(String.valueOf((char) b));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte @NonNull [] b, int off, int len) {
|
|
||||||
appendConsole(new String(b, off, len));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(byte @NonNull[] b) {
|
|
||||||
write(b, 0, b.length);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Override the system output streams
|
|
||||||
System.setOut(new PrintStream(out, true));
|
|
||||||
System.setErr(new PrintStream(out, true));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -354,4 +347,30 @@ public class GeyserStandaloneGUI {
|
|||||||
commandInput.setText(""); // clear the input
|
commandInput.setText(""); // clear the input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class GUIAppender extends AbstractAppender {
|
||||||
|
private static final List<PatternFormatter> FORMATTERS = PatternLayout.createPatternParser(new NullConfiguration())
|
||||||
|
.parse(
|
||||||
|
"[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
protected GUIAppender() {
|
||||||
|
super("GUIAppender", null, null, false, Property.EMPTY_ARRAY);
|
||||||
|
|
||||||
|
((Logger) LogManager.getRootLogger()).addAppender(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(LogEvent event) {
|
||||||
|
StringBuilder formatted = new StringBuilder();
|
||||||
|
for (PatternFormatter formatter : FORMATTERS) {
|
||||||
|
formatter.format(event, formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendConsole(formatted.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,6 @@
|
|||||||
<TerminalConsole name="TerminalConsole">
|
<TerminalConsole name="TerminalConsole">
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
||||||
</TerminalConsole>
|
</TerminalConsole>
|
||||||
<Console name="Console" target="SYSTEM_OUT" follow="true">
|
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
|
||||||
</Console>
|
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss.SSS} %t/%level] %minecraftFormatting{%msg}{strip}%n"/>
|
<PatternLayout pattern="[%d{HH:mm:ss.SSS} %t/%level] %minecraftFormatting{%msg}{strip}%n"/>
|
||||||
<Policies>
|
<Policies>
|
||||||
@@ -18,7 +15,6 @@
|
|||||||
<Loggers>
|
<Loggers>
|
||||||
<Root level="INFO" >
|
<Root level="INFO" >
|
||||||
<AppenderRef ref="TerminalConsole"/>
|
<AppenderRef ref="TerminalConsole"/>
|
||||||
<AppenderRef ref="Console"/>
|
|
||||||
<AppenderRef ref="File"/>
|
<AppenderRef ref="File"/>
|
||||||
<filters>
|
<filters>
|
||||||
<MarkerFilter marker="packet_logging" onMatch="DENY" onMismatch="ACCEPT" />
|
<MarkerFilter marker="packet_logging" onMatch="DENY" onMismatch="ACCEPT" />
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ netty-transport-native-io_uring = { group = "io.netty.incubator", name = "netty-
|
|||||||
log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" }
|
log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" }
|
||||||
log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" }
|
log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" }
|
||||||
log4j-slf4j2-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j2-impl", version.ref = "log4j" }
|
log4j-slf4j2-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j2-impl", version.ref = "log4j" }
|
||||||
|
log4j-iostreams = { group = "org.apache.logging.log4j", name = "log4j-iostreams", version.ref = "log4j" }
|
||||||
|
log4j-jul = { group = "org.apache.logging.log4j", name = "log4j-jul", version.ref = "log4j" }
|
||||||
|
|
||||||
jline-terminal = { group = "org.jline", name = "jline-terminal", version.ref = "jline" }
|
jline-terminal = { group = "org.jline", name = "jline-terminal", version.ref = "jline" }
|
||||||
jline-terminal-jna = { group = "org.jline", name = "jline-terminal-jna", version.ref = "jline" }
|
jline-terminal-jna = { group = "org.jline", name = "jline-terminal-jna", version.ref = "jline" }
|
||||||
@@ -160,6 +162,6 @@ runpaper = { id = "xyz.jpenilla.run-paper", version.ref = "runtask" }
|
|||||||
jackson = [ "jackson-annotations", "jackson-databind", "jackson-dataformat-yaml" ]
|
jackson = [ "jackson-annotations", "jackson-databind", "jackson-dataformat-yaml" ]
|
||||||
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ]
|
fastutil = [ "fastutil-int-int-maps", "fastutil-int-long-maps", "fastutil-int-byte-maps", "fastutil-int-boolean-maps", "fastutil-object-int-maps", "fastutil-object-object-maps" ]
|
||||||
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
|
adventure = [ "adventure-text-serializer-gson", "adventure-text-serializer-legacy", "adventure-text-serializer-plain" ]
|
||||||
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl" ]
|
log4j = [ "log4j-api", "log4j-core", "log4j-slf4j2-impl", "log4j-iostreams", "log4j-jul" ]
|
||||||
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]
|
jline = [ "jline-terminal", "jline-terminal-jna", "jline-reader" ]
|
||||||
protocol = [ "protocol-common", "protocol-codec", "protocol-connection" ]
|
protocol = [ "protocol-common", "protocol-codec", "protocol-connection" ]
|
||||||
|
|||||||
Reference in New Issue
Block a user