From 3c434951238ddef3e0b4e1bc04daea0f1f12b983 Mon Sep 17 00:00:00 2001 From: Aurelien Date: Mon, 15 Sep 2025 16:03:51 +0200 Subject: [PATCH] Force Logback to INFO level (due to default behaviour change in Logback 1.5) --- gradle.properties | 4 +- .../tc/l2/logging/BootstrapConfigurator.java | 3 +- .../com/tc/l2/logging/TCLogbackLogging.java | 18 +++- tc-server/src/main/resources/logback.xml | 32 ++++++ .../tc/l2/logging/TCLogbackLoggingTest.java | 97 +++++++++++++------ 5 files changed, 117 insertions(+), 37 deletions(-) create mode 100644 tc-server/src/main/resources/logback.xml diff --git a/gradle.properties b/gradle.properties index 8625d5f3d0..1fb0cf444a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ apiVersion=5.12.14 defaultVersion=5.12-SNAPSHOT -slf4jVersion = 1.7.36 +slf4jVersion = 2.0.17 terracottaApisVersion = 1.9.1 tripwireVersion = 1.0.6 @@ -10,7 +10,7 @@ mockitoVersion = 5.14.2 junitVersion = 4.13.1 hamcrestVersion = 1.3 commonsIOVersion = 2.7 -logbackVersion = 1.2.13 +logbackVersion = 1.5.18 org.gradle.parallel=true compileVM=17 \ No newline at end of file diff --git a/tc-server/src/main/java/com/tc/l2/logging/BootstrapConfigurator.java b/tc-server/src/main/java/com/tc/l2/logging/BootstrapConfigurator.java index e1a5c19877..9e03dc3e1a 100644 --- a/tc-server/src/main/java/com/tc/l2/logging/BootstrapConfigurator.java +++ b/tc-server/src/main/java/com/tc/l2/logging/BootstrapConfigurator.java @@ -31,7 +31,7 @@ public class BootstrapConfigurator extends ContextAwareBase implements Configurator { @Override - public void configure(LoggerContext loggerContext) { + public ExecutionStatus configure(LoggerContext loggerContext) { ch.qos.logback.classic.Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); BufferingAppender appender = new BufferingAppender(); @@ -56,5 +56,6 @@ public void configure(LoggerContext loggerContext) { root.setLevel(Level.INFO); loggerContext.start(); } + return ExecutionStatus.INVOKE_NEXT_IF_ANY; } } diff --git a/tc-server/src/main/java/com/tc/l2/logging/TCLogbackLogging.java b/tc-server/src/main/java/com/tc/l2/logging/TCLogbackLogging.java index a477386bbc..6bead953d3 100644 --- a/tc-server/src/main/java/com/tc/l2/logging/TCLogbackLogging.java +++ b/tc-server/src/main/java/com/tc/l2/logging/TCLogbackLogging.java @@ -51,6 +51,12 @@ public static void resetLogging() { root.detachAndStopAllAppenders(); console.detachAndStopAllAppenders(); loggerContext.reset(); + + try { + new ch.qos.logback.classic.util.ContextInitializer(loggerContext).autoConfig(); + } catch (Exception e) { + ch.qos.logback.core.util.StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); + } } public static void setServerName(String name) { @@ -91,7 +97,7 @@ public static void bootstrapLogging(OutputStream out) { appender.start(); root.addAppender(appender); } - + if (!hasJfr && EventAppender.isEnabled()) { EventAppender events = new EventAppender(); events.setName("LogToJFR"); @@ -103,7 +109,7 @@ public static void bootstrapLogging(OutputStream out) { ch.qos.logback.classic.Logger silent = loggerContext.getLogger(TCLogging.SILENT_LOGGER_NAME); silent.setAdditive(false); silent.setLevel(Level.OFF); - + if (!loggerContext.isStarted()) { root.setLevel(Level.INFO); loggerContext.start(); @@ -122,13 +128,19 @@ public static void redirectLogging(File logDirFile) { } else { disableBufferingAppender(null); } + + Appender bootstrap = root.getAppender("TC_BASE"); + if (bootstrap != null) { + root.detachAppender(bootstrap); + try { bootstrap.stop(); } catch (Exception ignore) {} + } } private static void disableBufferingAppender(Appender continuingAppender) { LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); ch.qos.logback.classic.Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME); ch.qos.logback.classic.Logger console = loggerContext.getLogger(CONSOLE); - + Iterator> appenders = root.iteratorForAppenders(); if (appenders != null) { while (appenders.hasNext()) { diff --git a/tc-server/src/main/resources/logback.xml b/tc-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..960807aab4 --- /dev/null +++ b/tc-server/src/main/resources/logback.xml @@ -0,0 +1,32 @@ + + + + + + + %d [%t] %p %c - %m%n + + + + + + + + + + diff --git a/tc-server/src/test/java/com/tc/l2/logging/TCLogbackLoggingTest.java b/tc-server/src/test/java/com/tc/l2/logging/TCLogbackLoggingTest.java index 78fd00a09a..baf40d75b3 100644 --- a/tc-server/src/test/java/com/tc/l2/logging/TCLogbackLoggingTest.java +++ b/tc-server/src/test/java/com/tc/l2/logging/TCLogbackLoggingTest.java @@ -19,19 +19,21 @@ import static com.tc.l2.logging.TCLogbackLogging.CONSOLE; import java.io.File; -import java.io.FileReader; -import java.io.LineNumberReader; import java.nio.file.Files; -import java.util.Arrays; -import static org.hamcrest.Matchers.contains; + +import static junit.framework.TestCase.assertTrue; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; import org.junit.Rule; import org.junit.contrib.java.lang.system.SystemOutRule; import org.junit.rules.TemporaryFolder; @@ -43,7 +45,7 @@ */ public class TCLogbackLoggingTest { - public @Rule SystemOutRule sysout = new SystemOutRule().enableLog(); + public @Rule SystemOutRule systemOutRule = new SystemOutRule().enableLog(); public @Rule TemporaryFolder temp = new TemporaryFolder(); public TCLogbackLoggingTest() { @@ -63,6 +65,7 @@ public void setUp() { @After public void tearDown() { + TCLogbackLogging.resetLogging(); } /** @@ -76,17 +79,24 @@ public void testBootstrapLogging() throws Exception { // test that console logger is properly installed Logger test = LoggerFactory.getLogger(CONSOLE); + systemOutRule.clearLog(); test.info("this is a test"); - assertThat(sysout.getLog(), not(containsString("this is a test"))); - File f = temp.newFolder(); - TCLogbackLogging.redirectLogging(f); - assertThat(sysout.getLog(), containsString("this is a test")); - sysout.clearLog(); - assertThat(sysout.getLog(), not(containsString("this is a test"))); - System.out.println("PRINTING " + f.listFiles()[0].toPath()); - Files.readAllLines(f.listFiles()[0].toPath()).forEach(System.out::println); - System.out.println("FINISHED " + f.listFiles()[0].toPath()); - assertThat(Files.readAllLines(f.listFiles()[0].toPath()), contains(Arrays.asList(containsString("this is a test"), containsString("Log file:")))); + + // redirect logging so buffered lines reach the console and the file + File logDir = temp.newFolder(); + systemOutRule.clearLog(); + TCLogbackLogging.redirectLogging(logDir); + + String consoleLog = systemOutRule.getLog(); + assertThat("Buffered message should hit the console once logging is redirected", + consoleLog, containsString("this is a test")); + assertThat("Console should announce redirection target", consoleLog, containsString("Log file:")); + + File logFile = new File(logDir, "terracotta.server.log"); + assertTrue("Log file should exist after redirect", logFile.exists()); + String fileContents = Files.readString(logFile.toPath()); + assertThat("Buffered message should be written to the log file", + fileContents, containsString("this is a test")); } /** @@ -100,30 +110,55 @@ public void testRedirectLogging() throws Exception { // test that console logger is properly installed Logger test = LoggerFactory.getLogger(CONSOLE); + systemOutRule.clearLog(); test.info("this is a test"); - assertThat(sysout.getLog(), not(containsString("this is a test"))); File folder = temp.newFolder(); + systemOutRule.clearLog(); TCLogbackLogging.redirectLogging(folder); - assertThat(sysout.getLog(), containsString("this is a test")); + assertThat(systemOutRule.getLog(), containsString("this is a test")); LoggerFactory.getLogger(CONSOLE).info("flush1"); LoggerFactory.getLogger(CONSOLE).info("flush2"); LoggerFactory.getLogger(CONSOLE).info("flush3"); LoggerFactory.getLogger(CONSOLE).info("flush4"); - FileReader read = new FileReader(new File(folder, "terracotta.server.log")); - LineNumberReader lines = new LineNumberReader(read); - boolean contains = false; - String line = lines.readLine(); - while (line != null) { - System.out.println("TESTING " + line); - if (line.contains("this is a test")) { - contains = true; - break; - } - line = lines.readLine(); - } - assertTrue(contains); + File logFile = new File(folder, "terracotta.server.log"); + assertTrue("Log file should exist after redirect", logFile.exists()); + String fileContents = Files.readString(logFile.toPath()); + assertTrue(fileContents.contains("this is a test")); + } + + @Test + public void testResetLoggingForcesInfoLevel() { + TCLogbackLogging.resetLogging(); + + LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory(); + ch.qos.logback.classic.Logger console = ctx.getLogger(TCLogbackLogging.CONSOLE); + + assertThat(console.getEffectiveLevel(), is(Level.INFO)); } + @Test + public void testBootstrapLoggingKeepsRootAtInfo() throws Exception { + TCLogbackLogging.resetLogging(); + + TCLogbackLogging.bootstrapLogging(null); // console appender setup + + // Redirect logging to a temporary folder to enable console output + File folder = temp.newFolder(); + TCLogbackLogging.redirectLogging(folder); + + LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory(); + ch.qos.logback.classic.Logger root = ctx.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + + assertThat(root.getLevel(), is(Level.INFO)); + + systemOutRule.clearLog(); + LoggerFactory.getLogger(TCLogbackLogging.CONSOLE).debug("debug-should-NOT-appear"); + LoggerFactory.getLogger(TCLogbackLogging.CONSOLE).info("info-should-appear"); + + String log = systemOutRule.getLog(); + assertThat("DEBUG should be filtered", log, not(containsString("debug-should-NOT-appear"))); + assertThat("INFO should be logged", log, containsString("info-should-appear")); + } }