diff --git a/SUPPORT.md b/SUPPORT.md index 2e07d9b23a..f6a1804944 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -27,7 +27,7 @@ Identifying the Source of a Problem You're most likely to get fast and valuable responses to your issues if you report them in the correct place. For this, you need to find the root cause of the problem. -The most important source for this information are the log files Forge creates for every run of the game. You can find them in the `logs` subdirectory of your Minecraft game directory. The most important log file is `fml-client-latest.log` for client instances (singleplayer or *connecting* to a server) and `fml-server-latest.log` for dedicated servers which contains all of Forge's and any mod's output. +The most important source for this information are the log files Forge creates for every run of the game. You can find them in the `logs` subdirectory of your Minecraft game directory. The most important log file is `latest.log` which contains all of Forge's and any mod's output for `info` of above. `debug.log` contains all the logs in `latest.log` plus the `debug` logs for more detailed debugging. If you're faced by a crash, consult these logs files first. Near the end of the log should be a section labelled 'Minecraft Crash Report', and after it, one about `a detailed walkthrough of the error, ...`. In these sections, you'll see a bunch of lines that look like @@ -108,7 +108,7 @@ If you're certain that your issue went unnoticed up until now, you can get to ac - **Mod Version:** Just like the Forge and Minecraft version, this is crucial for quickly telling where an issue might come from. *If you're reporting an issue caused by Forge that only occurs with a certain mod installed, include this mod here. No mod version is required if it's a pure Forge bug.* - **Complete List of Mods:** In order to reliably analyze a bug, developers need the exact same context as you do when trying to find its cause. Hence, you should always include a *full list of mods with their corresponding version* in your report. Note that you should probably only include the ones you found by [isolating the issue](#isolating-an-issue). - **Steps to Reproduce:** You should always include a list of steps required to provoke an issue to occur. Without it, developers can only take rough guesses at what might cause the bug. Try to reduce the amount of steps to a bare minimum, to make reproducing the issue easier. If you require a sophisticated setup to get even close to the issue, you might want to consider including your save file in your report. - - **Full Log:** This is probably the most important part of your bug report. You *always* have to include the full log (`fml-client-latest.log` or `fml-server-latest.log` from earlier), since it is the only way of telling what has caused an issue in code. *Do not* paste the full log as plain text in your report, but use a site like [Pastebin](https://pastebin.com) or [GitHub Gist](https://gist.github.com) instead and link to that from your report. + - **Full Log:** This is probably the most important part of your bug report. You *always* have to include the full log (`debug.log` from earlier), since it is the only way of telling what has caused an issue in code. *Do not* paste the full log as plain text in your report, but use [GitHub Gist](https://gist.github.com) instead and link to that from your report. ### Markdown Issue Template GitHub and BitBucket allow you to use the Markdown format for writing your issues. Below you can find a simple template that you can copy and fill in with your data. `{variables}` are written in braces and are supposed to be replaced by you with the information the variable name indicates. Everything behind two slashes (`//`) has to be interpreted as a comment and should be removed. If you want to include any link, you have to write in the `[title](url)` form. For further information on Markdown, see [this cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java b/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java index 7fd1de9939..ae8e54c18b 100644 --- a/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java +++ b/src/main/java/net/minecraftforge/client/model/b3d/B3DModel.java @@ -44,6 +44,7 @@ import javax.vecmath.Vector2f; import javax.vecmath.Vector3f; import javax.vecmath.Vector4f; +import net.minecraftforge.common.ForgeVersion; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; @@ -63,7 +64,7 @@ import com.google.common.collect.Table; public class B3DModel { - static final Logger logger = LogManager.getLogger(B3DModel.class); + static final Logger logger = LogManager.getLogger(ForgeVersion.MOD_ID + ".B3DModel"); private static final boolean printLoadedModels = "true".equals(System.getProperty("b3dloader.printLoadedModels")); private final List textures; private final List brushes; diff --git a/src/main/java/net/minecraftforge/common/ForgeVersion.java b/src/main/java/net/minecraftforge/common/ForgeVersion.java index 61a833a371..6acaef1d7b 100644 --- a/src/main/java/net/minecraftforge/common/ForgeVersion.java +++ b/src/main/java/net/minecraftforge/common/ForgeVersion.java @@ -68,7 +68,7 @@ public class ForgeVersion @SuppressWarnings("unused") private static String target = null; - private static final Logger log = LogManager.getLogger("ForgeVersionCheck"); + private static final Logger log = LogManager.getLogger(MOD_ID + ".VersionCheck"); public static int getMajorVersion() { diff --git a/src/main/java/net/minecraftforge/common/UsernameCache.java b/src/main/java/net/minecraftforge/common/UsernameCache.java index 910bd29021..001d5a2ebb 100644 --- a/src/main/java/net/minecraftforge/common/UsernameCache.java +++ b/src/main/java/net/minecraftforge/common/UsernameCache.java @@ -61,7 +61,7 @@ public final class UsernameCache { private static final File saveFile = new File( /* The minecraft dir */(File) FMLInjectionData.data()[6], "usernamecache.json"); private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - private static final Logger log = LogManager.getLogger(UsernameCache.class); + private static final Logger log = LogManager.getLogger(ForgeVersion.MOD_ID + ".UsernameCache"); private UsernameCache() {} diff --git a/src/main/java/net/minecraftforge/common/config/Configuration.java b/src/main/java/net/minecraftforge/common/config/Configuration.java index e80322d5e4..1bb49319c1 100644 --- a/src/main/java/net/minecraftforge/common/config/Configuration.java +++ b/src/main/java/net/minecraftforge/common/config/Configuration.java @@ -1047,7 +1047,7 @@ public class Configuration } catch (IOException e) { - FMLLog.log.error("Error while loading config.", e); + FMLLog.log.error("Error while loading config {}.", fileName, e); } finally { @@ -1108,7 +1108,7 @@ public class Configuration } catch (IOException e) { - FMLLog.log.error("Error while saving config.", e); + FMLLog.log.error("Error while saving config {}.", fileName, e); } } diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 40460a6ce0..32e3bb7e2b 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -992,7 +992,7 @@ public class FMLClientHandler implements IFMLSidedHandler { return; } - Logger logger = LogManager.getLogger("TEXTURE ERRORS"); + Logger logger = LogManager.getLogger("FML.TEXTURE_ERRORS"); logger.error(Strings.repeat("+=", 25)); logger.error("The following texture errors were found."); Map resManagers = ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "domainResourceManagers", "field_110548"+"_a"); diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java b/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java index 1d3018e85e..1e52185ff7 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import net.minecraftforge.fml.common.FMLLog; import org.apache.logging.log4j.LogManager; import javax.imageio.ImageIO; @@ -59,7 +60,7 @@ public class FMLFileResourcePack extends FileResourcePack implements FMLContaine { if ("pack.mcmeta".equals(resourceName)) { - LogManager.getLogger(container.getName()).debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); + FMLLog.log.debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); return new ByteArrayInputStream(("{\n" + " \"pack\": {\n"+ " \"description\": \"dummy FML pack for "+container.getName()+"\",\n"+ diff --git a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java b/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java index 4297b2c24c..8644de50ad 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import net.minecraftforge.fml.common.FMLLog; import org.apache.logging.log4j.LogManager; import javax.imageio.ImageIO; @@ -64,7 +65,7 @@ public class FMLFolderResourcePack extends FolderResourcePack implements FMLCont { if ("pack.mcmeta".equals(resourceName)) { - LogManager.getLogger(container.getName()).debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); + FMLLog.log.debug("Mod {} is missing a pack.mcmeta file, substituting a dummy one", container.getName()); return new ByteArrayInputStream(("{\n" + " \"pack\": {\n"+ " \"description\": \"dummy FML pack for "+container.getName()+"\",\n"+ diff --git a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java b/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java index f10f1271e9..a420ae4f47 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java @@ -31,7 +31,7 @@ import java.io.File; public class GuiErrorBase extends GuiErrorScreen { static final File minecraftDir = new File(Loader.instance().getConfigDir().getParent()); - static final File clientLog = new File(minecraftDir, "logs/fml-client-latest.log"); + static final File logFile = new File(minecraftDir, "logs/latest.log"); public GuiErrorBase() { super(null, null); @@ -48,7 +48,7 @@ public class GuiErrorBase extends GuiErrorScreen super.initGui(); this.buttonList.clear(); this.buttonList.add(new GuiButton(10, 50, this.height - 38, this.width / 2 - 55, 20, translateOrDefault("fml.button.open.mods.folder", "Open Mods Folder"))); - String openFileText = translateOrDefault("fml.button.open.file", "Open %s", clientLog.getName()); + String openFileText = translateOrDefault("fml.button.open.file", "Open %s", logFile.getName()); this.buttonList.add(new GuiButton(11, this.width / 2 + 5, this.height - 38, this.width / 2 - 55, 20, openFileText)); } @@ -71,11 +71,11 @@ public class GuiErrorBase extends GuiErrorScreen { try { - Desktop.getDesktop().open(clientLog); + Desktop.getDesktop().open(logFile); } catch (Exception e) { - FMLLog.log.error("Problem opening log file {}", clientLog, e); + FMLLog.log.error("Problem opening log file {}", logFile, e); } } } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java index 7460b172c2..bad93f6b0e 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java @@ -61,7 +61,7 @@ public class GuiModsMissing extends GuiErrorBase this.drawCenteredString(this.fontRenderer, String.format(TextFormatting.BOLD + "%s" + TextFormatting.RESET + " : %s", v.getLabel(), v.getRangeString()), this.width / 2, offset, 0xEEEEEE); } offset+=20; - String seeLogText = I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.clientLog.getName()); + String seeLogText = I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.logFile.getName()); this.drawCenteredString(this.fontRenderer, seeLogText, this.width / 2, offset, 0xFFFFFF); super.drawScreen(mouseX, mouseY, partialTicks); } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java b/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java index 76c2c87607..c6566cf9d0 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java @@ -44,7 +44,7 @@ public class GuiWrongMinecraft extends GuiErrorBase offset+=15; this.drawCenteredString(this.fontRenderer, I18n.format("fml.messages.mod.wrongminecraft.fix", wrongMC.mod.getName()),this.width/2, offset, 0xFFFFFF); offset+=20; - this.drawCenteredString(this.fontRenderer, I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.clientLog.getName()), this.width / 2, offset, 0xFFFFFF); + this.drawCenteredString(this.fontRenderer, I18n.format("fml.messages.mod.missing.dependencies.see.log", GuiErrorBase.logFile.getName()), this.width / 2, offset, 0xFFFFFF); super.drawScreen(mouseX, mouseY, partialTicks); } } diff --git a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java b/src/main/java/net/minecraftforge/fml/common/FMLContainer.java index c400684cbb..83a7da263c 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLContainer.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLContainer.java @@ -51,6 +51,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; +import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; @@ -60,6 +61,8 @@ import javax.annotation.Nullable; */ public final class FMLContainer extends DummyModContainer implements WorldAccessContainer { + private static final Logger modTrackerLogger = LogManager.getLogger("FML.ModTracker"); + public FMLContainer() { super(new ModMetadata()); @@ -190,12 +193,12 @@ public final class FMLContainer extends DummyModContainer implements WorldAccess ModContainer container = Loader.instance().getIndexedModList().get(modId); if (container == null) { - LogManager.getLogger("fml.ModTracker").error("This world was saved with mod {} which appears to be missing, things may not work well", modId); + modTrackerLogger.error("This world was saved with mod {} which appears to be missing, things may not work well", modId); continue; } if (!modVersion.equals(container.getVersion())) { - LogManager.getLogger("fml.ModTracker").info("This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, container.getVersion()); + modTrackerLogger.info("This world was saved with mod {} version {} and it is now at version {}, things may not work well", modId, modVersion, container.getVersion()); } } } diff --git a/src/main/java/net/minecraftforge/fml/common/FMLLog.java b/src/main/java/net/minecraftforge/fml/common/FMLLog.java index 45a9fda25d..e64f40b9ec 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLLog.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLLog.java @@ -19,37 +19,21 @@ package net.minecraftforge.fml.common; -import java.util.Locale; - import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.relauncher.FMLLaunchHandler; import net.minecraftforge.fml.relauncher.FMLRelaunchLog; -import net.minecraftforge.fml.relauncher.Side; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.ThreadContext; /** * FMLs logging class. Internal use only, NOT FOR MOD LOGGING! Mods use your own log, see {@link FMLPreInitializationEvent#getModLog()}. + * TODO 1.13 remove all the deprecated methods */ public class FMLLog { - public static final Logger log; - - static { - log = LogManager.getLogger("FML"); - // Default side to client for test harness purposes - Side side = FMLLaunchHandler.side(); - if (side == null) side = Side.CLIENT; - ThreadContext.put("side", side.name().toLowerCase(Locale.ENGLISH)); - - log.debug("Injecting tracing printstreams for STDOUT/STDERR."); - System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out)); - System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err)); - } + public static final Logger log = LogManager.getLogger("FML"); public static void bigWarning(String format, Object... data) { diff --git a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java index 3cc51e84dd..73eccdd2f8 100644 --- a/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java @@ -58,8 +58,6 @@ import net.minecraftforge.fml.relauncher.Side; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -106,8 +104,6 @@ public class FMLModContainer implements ModContainer private URL updateJSONUrl; private int classVersion; - private final Logger modLog; - public FMLModContainer(String className, ModCandidate container, Map modDescriptor) { this.className = className; @@ -129,8 +125,6 @@ public class FMLModContainer implements ModContainer FMLLog.log.trace("Using custom language adapter {} for {} (modid: {})", languageAdapterType, this.className, getModId()); } sanityCheckModId(); - - modLog = LogManager.getLogger(getModId()); } private void sanityCheckModId() @@ -217,15 +211,15 @@ public class FMLModContainer implements ModContainer modMetadata.requiredMods = info.requirements; modMetadata.dependencies = info.dependencies; modMetadata.dependants = info.dependants; - modLog.trace("Parsed dependency info : Requirements: {} After:{} Before:{}", info.requirements, info.dependencies, info.dependants); + FMLLog.log.trace("Parsed dependency info for {}: Requirements: {} After:{} Before:{}", getModId(), info.requirements, info.dependencies, info.dependants); } else { - modLog.trace("Using mcmod dependency info : {} {} {}", modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants); + FMLLog.log.trace("Using mcmod dependency info for {}: {} {} {}", getModId(), modMetadata.requiredMods, modMetadata.dependencies, modMetadata.dependants); } if (Strings.isNullOrEmpty(modMetadata.name)) { - modLog.info("Mod {} is missing the required element 'name'. Substituting {}", getModId(), getModId()); + FMLLog.log.info("Mod {} is missing the required element 'name'. Substituting {}", getModId(), getModId()); modMetadata.name = getModId(); } internalVersion = (String)descriptor.get("version"); @@ -235,18 +229,18 @@ public class FMLModContainer implements ModContainer if (versionProps != null) { internalVersion = versionProps.getProperty(getModId() + ".version"); - modLog.debug("Found version {} for mod {} in version.properties, using", internalVersion, getModId()); + FMLLog.log.debug("Found version {} for mod {} in version.properties, using", internalVersion, getModId()); } } if (Strings.isNullOrEmpty(internalVersion) && !Strings.isNullOrEmpty(modMetadata.version)) { - modLog.warn("Mod {} is missing the required element 'version' and a version.properties file could not be found. Falling back to metadata version {}", getModId(), modMetadata.version); + FMLLog.log.warn("Mod {} is missing the required element 'version' and a version.properties file could not be found. Falling back to metadata version {}", getModId(), modMetadata.version); internalVersion = modMetadata.version; } if (Strings.isNullOrEmpty(internalVersion)) { - modLog.warn("Mod {} is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId()); + FMLLog.log.warn("Mod {} is missing the required element 'version' and no fallback can be found. Substituting '1.0'.", getModId()); modMetadata.version = internalVersion = "1.0"; } @@ -274,7 +268,7 @@ public class FMLModContainer implements ModContainer } catch (MalformedURLException e) { - modLog.debug("Specified json URL invalid: {}", jsonURL); + FMLLog.log.debug("Specified json URL for mod '{}' is invalid: {}", getModId(), jsonURL); } } } @@ -284,7 +278,7 @@ public class FMLModContainer implements ModContainer { try { - modLog.debug("Attempting to load the file version.properties from {} to locate a version number for {}", getSource().getName(), getModId()); + FMLLog.log.debug("Attempting to load the file version.properties from {} to locate a version number for mod {}", getSource().getName(), getModId()); Properties version = null; if (getSource().isFile()) { @@ -321,7 +315,7 @@ public class FMLModContainer implements ModContainer } catch (IOException e) { - modLog.trace("Failed to find a usable version.properties file"); + FMLLog.log.trace("Failed to find a usable version.properties file for mod {}", getModId()); return null; } } @@ -373,7 +367,7 @@ public class FMLModContainer implements ModContainer { if (this.enabled) { - modLog.debug("Enabling mod {}", getModId()); + FMLLog.log.debug("Enabling mod {}", getModId()); this.eventBus = bus; this.controller = controller; eventBus.register(this); @@ -403,7 +397,7 @@ public class FMLModContainer implements ModContainer } else { - modLog.error("The mod {} appears to have an invalid event annotation {}. This annotation can only apply to methods with recognized event arguments - it will not be called", getModId(), a.annotationType().getSimpleName()); + FMLLog.log.error("The mod {} appears to have an invalid event annotation {}. This annotation can only apply to methods with recognized event arguments - it will not be called", getModId(), a.annotationType().getSimpleName()); } } else if (a.annotationType().equals(Mod.InstanceFactory.class)) @@ -415,11 +409,11 @@ public class FMLModContainer implements ModContainer } else if (!(Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0)) { - modLog.error("The InstanceFactory annotation can only apply to a static method, taking zero arguments - it will be ignored on {}({})", m.getName(), Arrays.asList(m.getParameterTypes())); + FMLLog.log.error("The InstanceFactory annotation can only apply to a static method, taking zero arguments - it will be ignored on {}({}) for mod {}", m.getName(), Arrays.asList(m.getParameterTypes()), getModId()); } else if (factoryMethod != null) { - modLog.error("The InstanceFactory annotation can only be used once, the application to {}({}) will be ignored", m.getName(), Arrays.asList(m.getParameterTypes())); + FMLLog.log.error("The InstanceFactory annotation can only be used once, the application to {}({}) will be ignored for mod {}", m.getName(), Arrays.asList(m.getParameterTypes()), getModId()); } } } @@ -486,7 +480,7 @@ public class FMLModContainer implements ModContainer } catch (ReflectiveOperationException e) { - modLog.warn("Attempting to load @{} in class {} for {} and failing", annotationName, targets.getClassName(), mc.getModId(), e); + FMLLog.log.warn("Attempting to load @{} in class {} for {} and failing", annotationName, targets.getClassName(), mc.getModId(), e); } } if (f != null) @@ -497,7 +491,7 @@ public class FMLModContainer implements ModContainer target = modInstance; if (!modInstance.getClass().equals(clz)) { - modLog.warn("Unable to inject @{} in non-static field {}.{} for {} as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId()); + FMLLog.log.warn("Unable to inject @{} in non-static field {}.{} for {} as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId()); continue; } } @@ -538,7 +532,7 @@ public class FMLModContainer implements ModContainer { warnLevel = Level.TRACE; } - modLog.log(warnLevel, "The mod {} is expecting signature {} for source {}, however there is no signature matching that description", getModId(), expectedFingerprint, source.getName()); + FMLLog.log.log(warnLevel, "The mod {} is expecting signature {} for source {}, however there is no signature matching that description", getModId(), expectedFingerprint, source.getName()); } else { @@ -575,7 +569,7 @@ public class FMLModContainer implements ModContainer } Method factoryMethod = gatherAnnotations(clazz); modInstance = getLanguageAdapter().getNewInstance(this, clazz, modClassLoader, factoryMethod); - NetworkRegistry.INSTANCE.register(this, clazz, (String)(descriptor.containsKey("acceptableRemoteVersions") ? descriptor.get("acceptableRemoteVersions") : null), event.getASMHarvestedData()); + NetworkRegistry.INSTANCE.register(this, clazz, (String)(descriptor.getOrDefault("acceptableRemoteVersions", null)), event.getASMHarvestedData()); if (fingerprintNotPresent) { eventBus.post(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints), expectedFingerprint)); diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/src/main/java/net/minecraftforge/fml/common/LoadController.java index 17c9fa087f..c5ed6fb73a 100644 --- a/src/main/java/net/minecraftforge/fml/common/LoadController.java +++ b/src/main/java/net/minecraftforge/fml/common/LoadController.java @@ -131,7 +131,7 @@ public class LoadController } else { - LogManager.getLogger(mod.getModId()).warn("Mod {} has been disabled through configuration", mod.getModId()); + FMLLog.log.warn("Mod {} has been disabled through configuration", mod.getModId()); modStates.put(mod.getModId(), ModState.UNLOADED); modStates.put(mod.getModId(), ModState.DISABLED); } @@ -266,7 +266,7 @@ public class LoadController { if (av.getLabel()!= null && requirements.contains(av.getLabel()) && modStates.containsEntry(av.getLabel(),ModState.ERRORED)) { - LogManager.getLogger(modId).error("Skipping event {} and marking errored mod {} since required dependency {} has errored", stateEvent.getEventType(), modId, av.getLabel()); + FMLLog.log.error("Skipping event {} and marking errored mod {} since required dependency {} has errored", stateEvent.getEventType(), modId, av.getLabel()); modStates.put(modId, ModState.ERRORED); return; } @@ -274,9 +274,9 @@ public class LoadController activeContainer = mc; stateEvent.applyModContainer(mc); ThreadContext.put("mod", modId); - LogManager.getLogger(modId).trace("Sending event {} to mod {}", stateEvent.getEventType(), modId); + FMLLog.log.trace("Sending event {} to mod {}", stateEvent.getEventType(), modId); eventChannels.get(modId).post(stateEvent); - LogManager.getLogger(modId).trace("Sent event {} to mod {}", stateEvent.getEventType(), modId); + FMLLog.log.trace("Sent event {} to mod {}", stateEvent.getEventType(), modId); ThreadContext.remove("mod"); activeContainer = null; if (stateEvent instanceof FMLStateEvent) diff --git a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java b/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java index 81adfe55e4..b56b1ce3d0 100644 --- a/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java +++ b/src/main/java/net/minecraftforge/fml/common/asm/FMLSanityChecker.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import net.minecraftforge.fml.common.FMLLog; import org.apache.commons.io.IOUtils; import net.minecraft.launchwrapper.LaunchClassLoader; @@ -42,8 +43,6 @@ import net.minecraftforge.fml.relauncher.Side; import com.google.common.io.ByteStreams; -import static net.minecraftforge.fml.common.FMLLog.log; - public class FMLSanityChecker implements IFMLCallHook { private static final String FMLFINGERPRINT = "51:0A:FB:4C:AF:A4:A0:F2:F5:CF:C5:0E:B4:CC:3C:30:24:4A:E3:8E".toLowerCase().replace(":", ""); @@ -71,17 +70,17 @@ public class FMLSanityChecker implements IFMLCallHook String fingerprint = CertificateHelper.getFingerprint(cert); if (fingerprint.equals(FMLFINGERPRINT)) { - log.info("Found valid fingerprint for FML. Certificate fingerprint {}", fingerprint); + FMLLog.log.info("Found valid fingerprint for FML. Certificate fingerprint {}", fingerprint); goodFML = true; } else if (fingerprint.equals(FORGEFINGERPRINT)) { - log.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint {}", fingerprint); + FMLLog.log.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint {}", fingerprint); goodFML = true; } else { - log.error("Found invalid fingerprint for FML: {}", fingerprint); + FMLLog.log.error("Found invalid fingerprint for FML: {}", fingerprint); } } } @@ -133,7 +132,7 @@ public class FMLSanityChecker implements IFMLCallHook String fingerprint = CertificateHelper.getFingerprint(cert); if (fingerprint.equals(MCFINGERPRINT)) { - log.info("Found valid fingerprint for Minecraft. Certificate fingerprint {}", fingerprint); + FMLLog.log.info("Found valid fingerprint for Minecraft. Certificate fingerprint {}", fingerprint); goodMC = true; } } @@ -141,7 +140,7 @@ public class FMLSanityChecker implements IFMLCallHook } catch (Throwable e) { - log.error("A critical error occurred trying to read the minecraft jar file", e); + FMLLog.log.error("A critical error occurred trying to read the minecraft jar file", e); } finally { @@ -154,11 +153,11 @@ public class FMLSanityChecker implements IFMLCallHook } if (!goodMC) { - log.error("The minecraft jar {} appears to be corrupt! There has been CRITICAL TAMPERING WITH MINECRAFT, it is highly unlikely minecraft will work! STOP NOW, get a clean copy and try again!", codeSource.getLocation().getFile()); + FMLLog.log.error("The minecraft jar {} appears to be corrupt! There has been CRITICAL TAMPERING WITH MINECRAFT, it is highly unlikely minecraft will work! STOP NOW, get a clean copy and try again!", codeSource.getLocation().getFile()); if (!Boolean.parseBoolean(System.getProperty("fml.ignoreInvalidMinecraftCertificates","false"))) { - log.error("For your safety, FML will not launch minecraft. You will need to fetch a clean version of the minecraft jar file"); - log.error("Technical information: The class net.minecraft.client.ClientBrandRetriever should have been associated with the minecraft jar file, " + + FMLLog.log.error("For your safety, FML will not launch minecraft. You will need to fetch a clean version of the minecraft jar file"); + FMLLog.log.error("Technical information: The class net.minecraft.client.ClientBrandRetriever should have been associated with the minecraft jar file, " + "and should have returned us a valid, intact minecraft jar location. This did not work. Either you have modified the minecraft jar file (if so " + "run the forge installer again), or you are using a base editing jar that is changing this class (and likely others too). If you REALLY " + "want to run minecraft in this configuration, add the flag -Dfml.ignoreInvalidMinecraftCertificates=true to the 'JVM settings' in your launcher profile."); @@ -166,13 +165,13 @@ public class FMLSanityChecker implements IFMLCallHook } else { - log.error("FML has been ordered to ignore the invalid or missing minecraft certificate. This is very likely to cause a problem!"); - log.error("Technical information: ClientBrandRetriever was at {}, there were {} certificates for it", codeSource.getLocation(), certCount); + FMLLog.log.error("FML has been ordered to ignore the invalid or missing minecraft certificate. This is very likely to cause a problem!"); + FMLLog.log.error("Technical information: ClientBrandRetriever was at {}, there were {} certificates for it", codeSource.getLocation(), certCount); } } if (!goodFML) { - log.error("FML appears to be missing any signature data. This is not a good thing"); + FMLLog.log.error("FML appears to be missing any signature data. This is not a good thing"); } return null; } diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java index 1b87ec55ea..0f473123e9 100644 --- a/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLPreInitializationEvent.java @@ -151,11 +151,9 @@ public class FMLPreInitializationEvent extends FMLStateEvent */ public Logger getModLog() { - Logger log = LogManager.getLogger(modContainer.getModId()); - return log; + return LogManager.getLogger(modContainer.getModId()); } - /** * Retrieve the FML signing certificates, if any. Validate these against the * published FML certificates in your mod, if you wish. diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java b/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java index 720538ddf1..52a7f43dca 100644 --- a/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java +++ b/src/main/java/net/minecraftforge/fml/common/launcher/FMLServerTweaker.java @@ -37,7 +37,7 @@ public class FMLServerTweaker extends FMLTweaker { if (System.getProperty("log4j.configurationFile") == null) { - System.setProperty("log4j.configurationFile", "log4j2_server.xml"); + System.setProperty("log4j.configurationFile", "log4j2.xml"); ((LoggerContext) LogManager.getContext(false)).reconfigure(); } } diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java b/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java index ebf1fd7a90..9c446655c0 100644 --- a/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java +++ b/src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java @@ -129,7 +129,7 @@ public class FMLTweaker implements ITweaker { } catch (URISyntaxException e) { - LogManager.getLogger("FMLTWEAK").log(Level.ERROR, "Missing URI information for FML tweak"); + LogManager.getLogger("FML.TWEAK").error("Missing URI information for FML tweak"); throw new RuntimeException(e); } } diff --git a/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java b/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java index 9aa8dd0fdb..2ae3e6b2e8 100644 --- a/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java +++ b/src/main/java/net/minecraftforge/fml/common/launcher/Yggdrasil.java @@ -48,7 +48,7 @@ public class Yggdrasil } catch (AuthenticationException e) { - LogManager.getLogger("FMLTWEAK").error("-- Login failed! {}", e.getMessage(), e); + LogManager.getLogger("FML.TWEAK").error("-- Login failed!", e); throw new RuntimeException(e); // don't set other variables } diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java b/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java index aa569dcdd6..d321da3b47 100644 --- a/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java +++ b/src/main/java/net/minecraftforge/fml/common/patcher/GenDiffSet.java @@ -31,16 +31,13 @@ import java.util.jar.JarFile; import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import net.minecraftforge.fml.repackage.com.nothome.delta.Delta; -import org.apache.commons.io.IOUtils; -import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; -import java.util.logging.Logger; - import com.google.common.hash.Hashing; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; +import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; @@ -56,7 +53,8 @@ public class GenDiffSet { String outputDir = args[3]; //Path to place generated .binpatch String killTarget = args[4]; //"true" if we should destroy the target file if it generated a successful .binpatch - LogManager.getLogger("GENDIFF").log(Level.INFO, String.format("Creating patches at %s for %s from %s", outputDir, sourceJar, targetDir)); + Logger logger = LogManager.getLogger("FML.GENDIFF"); + logger.info("Creating patches at {} for {} from {}", outputDir, sourceJar, targetDir); Delta delta = new Delta(); FMLDeobfuscatingRemapper remapper = FMLDeobfuscatingRemapper.INSTANCE; remapper.setupLoadOnly(deobfData, false); @@ -109,11 +107,11 @@ public class GenDiffSet { File target = new File(outputDir, targetClassName+".binpatch"); target.getParentFile().mkdirs(); Files.write(diffOut.toByteArray(), target); - Logger.getLogger("GENDIFF").info(String.format("Wrote patch for %s (%s) at %s",name, targetClassName, target.getAbsolutePath())); + logger.info("Wrote patch for {} ({}) at {}", name, targetClassName, target.getAbsolutePath()); if (kill) { targetFile.delete(); - Logger.getLogger("GENDIFF").info(String.format(" Deleted target: %s", targetFile.toString())); + logger.info(" Deleted target: {}", targetFile); } } } diff --git a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java b/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java index ac34202ed4..b64aebfd3f 100644 --- a/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java +++ b/src/main/java/net/minecraftforge/fml/common/versioning/DependencyParser.java @@ -28,10 +28,9 @@ import java.util.Set; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; +import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.LoaderException; import net.minecraftforge.fml.relauncher.Side; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; public final class DependencyParser { @@ -42,7 +41,6 @@ public final class DependencyParser public final List dependants = new ArrayList<>(); } - private static final Logger LOGGER = LogManager.getLogger("FML"); private static final ImmutableList DEPENDENCY_INSTRUCTIONS = ImmutableList.of("client", "server", "required", "before", "after"); private static final Splitter DEPENDENCY_INSTRUCTIONS_SPLITTER = Splitter.on("-").omitEmptyStrings().trimResults(); private static final Splitter DEPENDENCY_PART_SPLITTER = Splitter.on(":").omitEmptyStrings().trimResults(); @@ -189,15 +187,15 @@ public final class DependencyParser { if (Strings.isNullOrEmpty(depModId)) { - LOGGER.error(new DependencyParserException(modId, dep, "The modId is null or empty").getMessage()); + FMLLog.log.error(new DependencyParserException(modId, dep, "The modId is null or empty").getMessage()); } else if (depModId.length() > 64) { - LOGGER.error(new DependencyParserException(modId, dep, String.format("The modId '%s' is longer than the maximum of 64 characters.", depModId)).getMessage()); + FMLLog.log.error(new DependencyParserException(modId, dep, String.format("The modId '%s' is longer than the maximum of 64 characters.", depModId)).getMessage()); } else if (!depModId.equals(depModId.toLowerCase(Locale.ENGLISH))) { - LOGGER.error(new DependencyParserException(modId, dep, String.format("The modId '%s' must be all lowercase.", depModId)).getMessage()); + FMLLog.log.error(new DependencyParserException(modId, dep, String.format("The modId '%s' must be all lowercase.", depModId)).getMessage()); } } diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java b/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java index 3e1e182b37..af5946884b 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/FMLLaunchHandler.java @@ -23,7 +23,9 @@ import java.io.File; import net.minecraft.launchwrapper.LaunchClassLoader; import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.TracingPrintStream; import net.minecraftforge.fml.common.launcher.FMLTweaker; +import org.apache.logging.log4j.LogManager; public class FMLLaunchHandler { @@ -79,12 +81,12 @@ public class FMLLaunchHandler { side = Side.SERVER; setupHome(); - } private void setupHome() { FMLInjectionData.build(minecraftHome, classLoader); + redirectStdOutputToLog(); FMLLog.log.info("Forge Mod Loader version {}.{}.{}.{} for Minecraft {} loading", FMLInjectionData.major, FMLInjectionData.minor, FMLInjectionData.rev, FMLInjectionData.build, FMLInjectionData.mccversion); FMLLog.log.info("Java is {}, version {}, running on {}:{}:{}, installed at {}", System.getProperty("java.vm.name"), System.getProperty("java.version"), System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"), System.getProperty("java.home")); @@ -105,6 +107,13 @@ public class FMLLaunchHandler } } + private void redirectStdOutputToLog() + { + FMLLog.log.debug("Injecting tracing printstreams for STDOUT/STDERR."); + System.setOut(new TracingPrintStream(LogManager.getLogger("STDOUT"), System.out)); + System.setErr(new TracingPrintStream(LogManager.getLogger("STDERR"), System.err)); + } + public static Side side() { return side; diff --git a/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java b/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java index 55c50ef240..d390aee3c9 100644 --- a/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java +++ b/src/main/java/net/minecraftforge/fml/relauncher/FMLRelaunchLog.java @@ -28,6 +28,7 @@ import org.apache.logging.log4j.Logger; /** * Legacy FML logging class. Mods use {@link FMLPreInitializationEvent#getModLog()} instead, for Forge internal use use FMLLog. + * TODO 1.13 remove this class */ @Deprecated public class FMLRelaunchLog { diff --git a/src/main/java/net/minecraftforge/server/console/TerminalConsoleAppender.java b/src/main/java/net/minecraftforge/server/console/TerminalConsoleAppender.java index 5a7160b3d2..15c995e4dd 100644 --- a/src/main/java/net/minecraftforge/server/console/TerminalConsoleAppender.java +++ b/src/main/java/net/minecraftforge/server/console/TerminalConsoleAppender.java @@ -36,6 +36,7 @@ import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginElement; import org.apache.logging.log4j.core.config.plugins.PluginFactory; import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.core.util.Booleans; import org.apache.logging.log4j.util.PropertiesUtil; import org.fusesource.jansi.AnsiConsole; @@ -47,6 +48,13 @@ import jline.console.ConsoleReader; import javax.annotation.Nullable; +/** + * TODO 1.13 remove this class + * @deprecated use the version in the log4j sub-package: {@link net.minecraftforge.server.console.log4j.TerminalConsoleAppender} + * This is being moved into its own package so that the log configuration doesn't load this whole package, + * which has references to Minecraft in it that can load lots of extra classes. + */ +@Deprecated @Plugin(name = "TerminalConsole", category = "Core", elementType = "appender", printObject = true) public class TerminalConsoleAppender extends AbstractAppender { @@ -67,7 +75,7 @@ public class TerminalConsoleAppender extends AbstractAppender public static void setFormatter(Function format) { - formatter = format != null ? format : Functions. identity(); + formatter = format != null ? format : Functions.identity(); } protected TerminalConsoleAppender(String name, Filter filter, Layout layout, boolean ignoreExceptions) @@ -78,7 +86,7 @@ public class TerminalConsoleAppender extends AbstractAppender @PluginFactory @Nullable public static TerminalConsoleAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filters") Filter filter, - @PluginElement("Layout") Layout layout, @PluginAttribute("ignoreExceptions") String ignore) + @PluginElement("Layout") Layout layout, @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) String ignore) { if (name == null) @@ -91,7 +99,7 @@ public class TerminalConsoleAppender extends AbstractAppender layout = PatternLayout.newBuilder().build(); } - boolean ignoreExceptions = Boolean.parseBoolean(ignore); + boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); // This is handled by jline System.setProperty("log4j.skipJansi", "true"); diff --git a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java b/src/main/java/net/minecraftforge/server/console/TerminalHandler.java index 6160859cb9..a922db2905 100644 --- a/src/main/java/net/minecraftforge/server/console/TerminalHandler.java +++ b/src/main/java/net/minecraftforge/server/console/TerminalHandler.java @@ -24,8 +24,6 @@ import java.io.IOException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.function.Function; - import jline.console.ConsoleReader; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.util.text.TextFormatting; diff --git a/src/main/java/net/minecraftforge/server/console/log4j/TerminalConsoleAppender.java b/src/main/java/net/minecraftforge/server/console/log4j/TerminalConsoleAppender.java new file mode 100644 index 0000000000..aaedafaa1d --- /dev/null +++ b/src/main/java/net/minecraftforge/server/console/log4j/TerminalConsoleAppender.java @@ -0,0 +1,187 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.server.console.log4j; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.io.PrintStream; +import java.io.Serializable; +import java.io.Writer; +import java.util.function.Function; + +import static jline.TerminalFactory.OFF; +import static jline.console.ConsoleReader.RESET_LINE; + +import com.google.common.base.Functions; +import jline.TerminalFactory; +import jline.console.ConsoleReader; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.core.util.Booleans; +import org.apache.logging.log4j.util.PropertiesUtil; +import org.fusesource.jansi.AnsiConsole; + +@Plugin(name = "TerminalConsole", category = "Core", elementType = "appender", printObject = true) +public class TerminalConsoleAppender extends AbstractAppender +{ + + private static final boolean ENABLE_JLINE = PropertiesUtil.getProperties().getBooleanProperty("jline.enable", true); + + private static final PrintStream out = System.out; + + private static boolean initialized; + private static ConsoleReader reader; + + public static ConsoleReader getReader() + { + return reader; + } + + private static Function formatter = Functions.identity(); + + public static void setFormatter(Function format) + { + formatter = format != null ? format : Functions.identity(); + } + + protected TerminalConsoleAppender(String name, Filter filter, Layout layout, boolean ignoreExceptions) + { + super(name, filter, layout, ignoreExceptions); + } + + @PluginFactory + @Nullable + public static TerminalConsoleAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filters") Filter filter, + @PluginElement("Layout") Layout layout, @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) String ignore) + { + + if (name == null) + { + LOGGER.error("No name provided for TerminalConsoleAppender"); + return null; + } + if (layout == null) + { + layout = PatternLayout.newBuilder().build(); + } + + boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); + + // This is handled by jline + System.setProperty("log4j.skipJansi", "true"); + return new TerminalConsoleAppender(name, filter, layout, ignoreExceptions); + } + + @Override + public void start() + { + // Initialize the reader if that hasn't happened yet + if (!initialized && reader == null) + { + initialized = true; + + if (ENABLE_JLINE) + { + final boolean hasConsole = System.console() != null; + if (hasConsole) + { + try + { + AnsiConsole.systemInstall(); + reader = new ConsoleReader(); + reader.setExpandEvents(false); + } + catch (Exception e) + { + LOGGER.warn("Failed to initialize terminal. Falling back to default.", e); + } + } + + if (reader == null) + { + // Eclipse doesn't support colors and characters like \r so enabling jline2 on it will + // just cause a lot of issues with empty lines and weird characters. + // Enable jline2 only on IntelliJ IDEA to prevent that. + // Also see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=76936 + + if (hasConsole || System.getProperty("java.class.path").contains("idea_rt.jar")) + { + // Disable advanced jline features + TerminalFactory.configure(OFF); + TerminalFactory.reset(); + + try + { + reader = new ConsoleReader(); + reader.setExpandEvents(false); + } + catch (Exception e) + { + LOGGER.warn("Failed to initialize fallback terminal. Falling back to standard output console.", e); + } + } + else + { + LOGGER.warn("Disabling terminal, you're running in an unsupported environment."); + } + } + } + } + + super.start(); + } + + @Override + public void append(LogEvent event) + { + if (reader != null) + { + try + { + Writer out = reader.getOutput(); + out.write(RESET_LINE); + out.write(formatEvent(event)); + + reader.drawLine(); + reader.flush(); + } + catch (IOException ignored) + { + } + } + else + { + out.print(formatEvent(event)); + } + } + + protected String formatEvent(LogEvent event) + { + return formatter.apply(getLayout().toSerializable(event).toString()); + } + +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index 41ecc8d8c6..ae512a6270 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -1,59 +1,42 @@ - + - - - - - - + + + + + - + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - + + + - - - + + + + + + + diff --git a/src/main/resources/log4j2_server.xml b/src/main/resources/log4j2_server.xml deleted file mode 100644 index a33c726e09..0000000000 --- a/src/main/resources/log4j2_server.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -