diff --git a/README.md b/README.md index 7f9e29969b..50f13c81a2 100644 --- a/README.md +++ b/README.md @@ -304,9 +304,12 @@ Note: Your Java environment may need to be set up correctly to use SSL. Restart OBP-API, if you get an error, check your Java environment can connect to the host over SSL. -Note: You can copy the following example files to prepare your own configurations: +Note: `/obp-api/src/main/resources/logback.xml` ships ready to use, defaulting to INFO. Set the +`LOG_LEVEL` environment variable (e.g. `LOG_LEVEL=DEBUG` or `LOG_LEVEL=TRACE`) to override it per +environment without editing the file. + +You can also copy the following example file to prepare your own test-run configuration: -- `/obp-api/src/main/resources/logback.xml.example` -> `/obp-api/src/main/resources/logback.xml` (try TRACE or DEBUG). - `/obp-api/src/main/resources/logback-test.xml.example` -> `/obp-api/src/main/resources/logback-test.xml` (try TRACE or DEBUG). There is a gist/tool which is useful for this. Search the web for SSLPoke. Note this is an external repository. diff --git a/obp-api/src/main/resources/docs/brief_system_documentation.md b/obp-api/src/main/resources/docs/brief_system_documentation.md index 08a7315b9c..3b7f2edce2 100644 --- a/obp-api/src/main/resources/docs/brief_system_documentation.md +++ b/obp-api/src/main/resources/docs/brief_system_documentation.md @@ -137,7 +137,7 @@ User ──(has roles/entitlements)──► Bank/System actions **Logging** -- Copy `logback.xml.example` to `logback.xml`; adjust levels (TRACE/DEBUG/INFO) per environment. +- `logback.xml` ships ready to use, defaulting to INFO; set `LOG_LEVEL` (TRACE/DEBUG/INFO/...) to override per environment. - In Docker/K8s, logs go to stdout/stderr → aggregate with your stack (e.g., Loki/Promtail, EFK). **Health & metrics** diff --git a/obp-api/src/main/resources/logback.xml b/obp-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..8044beb0bf --- /dev/null +++ b/obp-api/src/main/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + %d{yyyy-MM-dd HH:mm:ss} %t %c{0} [%p] %m%n + + + + + + + + \ No newline at end of file diff --git a/obp-api/src/main/resources/logback.xml.example b/obp-api/src/main/resources/logback.xml.example deleted file mode 100644 index 871aea062a..0000000000 --- a/obp-api/src/main/resources/logback.xml.example +++ /dev/null @@ -1,12 +0,0 @@ - - - - - %d{yyyy-MM-dd HH:mm:ss} %t %c{0} [%p] %m%n - - - - - - - \ No newline at end of file diff --git a/obp-api/src/test/scala/bootstrap/http4s/LogbackDefaultLevelTest.scala b/obp-api/src/test/scala/bootstrap/http4s/LogbackDefaultLevelTest.scala new file mode 100644 index 0000000000..527c81bfa5 --- /dev/null +++ b/obp-api/src/test/scala/bootstrap/http4s/LogbackDefaultLevelTest.scala @@ -0,0 +1,55 @@ +package bootstrap.http4s + +import ch.qos.logback.classic.{Level, Logger, LoggerContext} +import ch.qos.logback.classic.joran.JoranConfigurator +import ch.qos.logback.classic.spi.LoggerContextListener +import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers} +import org.slf4j.Logger.ROOT_LOGGER_NAME + +/** + * Directly verifies the shipped src/main/resources/logback.xml resolves + * the way this fix depends on: + * + * - LOG_LEVEL unset -> root defaults to INFO, not the old hard-coded DEBUG. + * - LOG_LEVEL set -> root honours it. + * + * The application's actual SLF4J LoggerContext is configured once, at JVM start, from whatever + * LOG_LEVEL happened to be set at that moment -- so asserting against + * LoggerFactory.getILoggerFactory() here wouldn't exercise the default-value resolution at all, + * only whatever this test JVM's own environment happened to be. Instead this parses the actual + * classpath resource into a fresh, throwaway LoggerContext per scenario (via Joran, the same + * parser Logback uses internally), with the system property set immediately beforehand -- this is + * the standard way to unit-test a logback.xml's own logic rather than the ambient environment. + */ +class LogbackDefaultLevelTest extends FlatSpec with Matchers with BeforeAndAfterEach { + + private val propertyName = "LOG_LEVEL" + + override def afterEach(): Unit = { + System.clearProperty(propertyName) + } + + private def rootLevelFromShippedConfig(): Level = { + val context = new LoggerContext() + context.reset() + val configurator = new JoranConfigurator() + configurator.setContext(context) + configurator.doConfigure(getClass.getClassLoader.getResource("logback.xml")) + context.getLogger(ROOT_LOGGER_NAME).getLevel + } + + "the shipped logback.xml" should "default the root level to INFO when LOG_LEVEL is unset" in { + System.clearProperty(propertyName) + rootLevelFromShippedConfig() should equal(Level.INFO) + } + + it should "honour LOG_LEVEL=DEBUG when set" in { + System.setProperty(propertyName, "DEBUG") + rootLevelFromShippedConfig() should equal(Level.DEBUG) + } + + it should "honour LOG_LEVEL=WARN when set" in { + System.setProperty(propertyName, "WARN") + rootLevelFromShippedConfig() should equal(Level.WARN) + } +}