From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Mon, 28 Jun 2021 13:33:12 -0500 Subject: [PATCH] Enhance SysoutCatcher diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java index 76d0d00cd6742991e3f3ec827a75ee87d856b6c9..784076cd05e161a3b496bfb2e2daa82f738b7ee6 100644 --- a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java +++ b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java @@ -1,5 +1,8 @@ package io.papermc.paper.logging; +import net.minecraft.server.MinecraftServer; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.filter.AbstractFilter; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -11,9 +14,13 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; +import java.util.logging.Handler; import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; public final class SysoutCatcher { + private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); // Purpur - moved from below private static final boolean SUPPRESS_NAGS = Boolean.getBoolean("io.papermc.paper.suppress.sout.nags"); // Nanoseconds between nag at most; if interval is caught first, this is reset. // <= 0 for disabling. @@ -34,10 +41,75 @@ public final class SysoutCatcher { public SysoutCatcher() { System.setOut(new WrappedOutStream(System.out, Level.INFO, "[STDOUT] ")); System.setErr(new WrappedOutStream(System.err, Level.SEVERE, "[STDERR] ")); + + // Purpur start + Logger.getLogger("Minecraft").setUseParentHandlers(false); + Logger.getLogger("Minecraft").addHandler(new Handler() { + @Override + public void publish(LogRecord record) { + if (record != null) { + Logger logger; + try { + final Class clazz = STACK_WALKER.walk(stream -> + stream.map(StackWalker.StackFrame::getDeclaringClass) + .skip(2) + .filter(e -> Logger.class != e) + .findFirst() + ).orElse(null); + logger = JavaPlugin.getProvidingPlugin(clazz).getLogger(); + } catch (Throwable e) { + logger = Logger.getLogger(""); + } + logger.log(record.getLevel(), record.getMessage(), record.getParameters()); + } + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }); + ((org.apache.logging.log4j.core.Logger) MinecraftServer.LOGGER).addFilter(new AbstractFilter() { + @Override + public Result filter(LogEvent event) { + try { + final Class clazz = STACK_WALKER.walk(stream -> + stream.map(StackWalker.StackFrame::getDeclaringClass) + .skip(2) + .filter(e -> !e.getPackageName().contains("org.apache.logging.log4j")) + .findFirst() + ).orElse(null); + final Logger logger = JavaPlugin.getProvidingPlugin(clazz).getLogger(); + Level level = null; + // https://github.com/apache/logging-log4j2/blob/5370298f3a549a3502a585e2de997a97101e651a/log4j-jul/src/main/java/org/apache/logging/log4j/jul/DefaultLevelConverter.java#L65-L75 + if (event.getLevel() == org.apache.logging.log4j.Level.ALL) level = Level.ALL; + else if (event.getLevel() == org.apache.logging.log4j.Level.DEBUG) level = Level.FINE; + else if (event.getLevel() == org.apache.logging.log4j.Level.ERROR) level = Level.SEVERE; + else if (event.getLevel() == org.apache.logging.log4j.Level.FATAL) level = Level.SEVERE; + else if (event.getLevel() == org.apache.logging.log4j.Level.INFO) level = Level.INFO; + else if (event.getLevel() == org.apache.logging.log4j.Level.OFF) level = Level.OFF; + else if (event.getLevel() == org.apache.logging.log4j.Level.TRACE) level = Level.FINER; + else if (event.getLevel() == org.apache.logging.log4j.Level.WARN) level = Level.WARNING; + logger.log(level, event.getMessage().getFormattedMessage()); + return Result.DENY; + } catch (Throwable ignore) { + return Result.NEUTRAL; + } + } + + @Override + protected boolean equalsImpl(Object obj) { + return super.equalsImpl(obj); + } + }); + // Purpur end } private final class WrappedOutStream extends PrintStream { - private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + //private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); // Purpur - move up private final Level level; private final String prefix; @@ -54,9 +126,9 @@ public final class SysoutCatcher { final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(clazz); // Instead of just printing the message, send it to the plugin's logger - plugin.getLogger().log(this.level, this.prefix + line); + plugin.getLogger().log(this.level, /*this.prefix +*/ line); // Purpur - prefix not needed - if (SysoutCatcher.SUPPRESS_NAGS) { + if (true || SysoutCatcher.SUPPRESS_NAGS) { // Purpur - nagging is annoying return; } if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {