logback.xml
filelogback.groovy
, logback-test.xml
or logback.xml
be located on the classpath?logback.xml
file?
logback.xml
or config file ignored or not picked up or doesn’t work?
In this modules we’ll configure LOGBACK with SLF4J for logging in a simple Java project.
As this is a simple Java project and does not use any build tools like Maven or Gradle etc., so we’ll have to add the required dependencies explicitly. Following are the dependencies required for logging:
Following is the simple sample code to test different log levels:
package au.com.lucidtech.logback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggingExample {
private static final Logger logger = LoggerFactory.getLogger(LoggingExample.class);
public static void main(String[] args) {
final String parameter = "logging";
if (logger.isTraceEnabled()) {
logger.trace("This is trace " + parameter);
}
if (logger.isDebugEnabled()) {
logger.debug("This is debug " + parameter);
}
if (logger.isInfoEnabled()) {
logger.info("This is info " + parameter);
}
logger.warn("This is warn " + parameter);
logger.error("This is error " + parameter);
}
}
Now, if we run this code, we should be able to see the logs with the default settings/configurations.
If we want to customize logging in order to be able to:
then we’ll need to add the logback.xml
file somewhere on the classpath.
logback.xml
fileThe following logback.xml
can be placed in the src/main/resources
folder:
<configuration>
<variable name="LOGS_DIR" value="out/logs"/>
<!-- Stop output INFO at start -->
<!-- As it won't show any start up logs, so consider commenting it out in case things are not working as expected
in order to see if there are any issues during start up -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOGS_DIR}/application.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] -%kvp- %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%L -%kvp- %msg%n</pattern>
</encoder>
</appender>
<appender name="ColorAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %green([%thread]) %highlight(%-5level) %logger{50}:%L - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE"/>
<appender-ref ref="ColorAppender"/>
</root>
</configuration>
logback.groovy
, logback-test.xml
or logback.xml
be located on the classpath?Configuration files such as logback.groovy
, logback-test.xml
or logback.xml
can be located directly under any folder
declared in the class path. For example, if the class path reads c:/java/jdk15/lib/rt.jar;c:/mylibs/
, then the
logback.xml
file should be located directly under c:/mylibs/
, that is as c:/mylibs/logback.xml
.
Placing it under a sub-folder of c:/mylibs/
, say, c:/mylibs/other/
, will not work.
For web-applications, configuration files can be placed directly under WEB-INF/classes/
.
So you need to put logback.xml
in the classpath. On one project, faced a similar problem although logback.xml
was
in the right place. Renaming it to logback-test.xml
helped.
logback.xml
file?logback.groovy
in the classpath.logback-test.xml
in the classpath.logback.xml
in the classpath..logback.xml
or config file ignored or not picked up or doesn’t work?We need to ensure that the config file is on the class path. We might have created the file in the src/main/resources
folder and might assume that, that’s it, it should work now. But unfortunately that’s not enough as we need to ensure
that it gets copied over to the target
folder (or wherever you’re compiling your project files).
So, if we are using some build tool like Maven then we can use the maven’s resource
plugin to copy them over.
When running the application in IDEs, ensure that the resources
folder is marked as resources in project setting,
as that’ll ensure that the logback.xml
inside resources folder is copied over to the target folder (and that’s where
the config file will be searched for configuration when the application is started).
If the file is located at the right location, then there is no need to setting the path explicitly, but if for some reason, you need to set the path explicitly, then here it is how to do it:
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
System.setProperty("logback.configurationFile", "/path/to/config.xml");
Or:
System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "/path/to/config.xml");
Modifying environment variables might not always be feasible. To do it properly see logback manual.
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(loggerContext);
class CustomLogbackConfigurer {
static void configureLogback() {
// assume SLF4J is bound to logback in the current environment
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(context);
// Call context.reset() to clear any previous configuration, e.g. default
// configuration. For multi-step configuration, omit calling context.reset().
context.reset();
configurator.doConfigure("src/main/resources/logback.xml");
} catch (JoranException je) {
// StatusPrinter will handle this
}
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
}
}
The logbook will output its own status (INFO or WARN) at the start of the program, it’s really annoying!
15:34:46,181 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
15:34:46,181 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
15:34:46,181 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/E:/spring-boot-simple/target/classes/logback.xml]
15:34:46,247 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
15:34:46,260 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
15:34:46,267 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
15:34:46,319 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - This appender no longer admits a layout as a sub-component, set an encoder instead.
15:34:46,319 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
15:34:46,319 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
15:34:46,320 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework.web] to ERROR
15:34:46,320 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.springframework.web] to false
15:34:46,320 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.springframework.web]
15:34:46,320 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.mkyong] to ERROR
15:34:46,320 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.mkyong] to false
15:34:46,320 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.mkyong]
15:34:46,320 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR
15:34:46,321 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
15:34:46,321 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
15:34:46,322 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@7bb11784 - Registering current configuration as safe fallback point
To fix it, add a NopStatusListener
like this:
<!-- Stop output INFO at start -->
<!-- As it won't show any start up logs, so consider commenting it out in case things are not working as expected
in order to see if there are any issues during start up -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />