Tag Archives: logback.xml

Logback: solve the problem that logback.xml configuration doesn’t work

Solve the problem that logback.xml configuration doesn’t work

Logback is a logging framework in Java. Today, when learning to use the logback logging framework, configuring logback-test.xml has never worked. For the record

Use logback to output logs:

The app.java code is as follows:

public class App {
    private static final Logger logger = LoggerFactory.getLogger(App.class);
    public static void main( String[] args ){
        System.out.println( "Hello World!" );

        System.out.println("----> logback start");
        logger.trace("--> Hello trace.");
        logger.debug("--> Hello debug.");
        logger.info("--> Hello info.");
        logger.warn("--> Goodbye warn.");
        logger.error("--> Goodbye error.");
        System.out.println("----> logback end");
    }
}

It can output normally, and the output results of the console are as follows:

Hello World!
----> logback start
11:48:41.601 [main] DEBUG com.wang123net.App - --> Hello debug.
11:48:41.604 [main] INFO com.wang123net.App - --> Hello info.
11:48:41.604 [main] WARN com.wang123net.App - --> Goodbye warn.
11:48:41.605 [main] ERROR com.wang123net.App - --> Goodbye error.
----> logback end

You can see that a trace level log is not printed

Because there is no configuration file specified in the project, and the default level of root logger in the default configuration is debug , the trace log will not be printed, no problem

As can be seen from the logback document, the reading order of configuration files is as follows: logback-test.xml > logback.grooy > logback.xml. If none of the three configuration files exist, the default configuration will be used

Settings profile

Now set a configuration file logback test. XML as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{YY-mm-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="TRACE">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

As you can see, the level of root in the configuration file is set to trace , which is expected to output trace level logs, but the result is not expected and does not take effect

Solution 1: put the configuration file in the classpath directory

Check the document again. It says that the configuration file needs to be placed in the classpath directory

// from: https://logback.qos.ch/faq.html#configFileLocation
Where should the configuration files such as 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 the question is, where is the classpath

Use the class ch.qos.logback.core.util.statusprinter tool to check the status:


LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);

The printed log is as follows:

11:48:41.605 [main] INFO com.wang123net.App - Hello, this is a line of log message logged by Logback
11:48:41,542 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
11:48:41,542 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:48:41,542 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
11:48:41,549 |-INFO in ch.qos.logback.classic.BasicConfigurator@5ce65a89 - Setting up default configuration.

Get classpath path:


String s = Thread.currentThread().getContextClassLoader().getResource("").getPath();
System.out.println("classpath => " + s );


String path = App.class.getResource("/").toString();
System.out.println("classpath => " + path);

Output results:

classpath =>/Users/wangtest/IdeaProjects/wang123net/target/classes/
classpath => file:/Users/wangtest/IdeaProjects/wang123nettest/target/classes/

Move the configuration file to the target/classes directory (SRC/main/target/classes/logback test. XML), and the output result is normal

Online materials:
Maven projects are generally divided into SRC, resource, test/SRC and test/resource; Code directory: SRC and resource correspond to the target/classes directory of the project. If classpath is called in SRC directory, the root directory of the class is target/classes
test directory: Test/SRC, test/resource corresponds to the target/test classes directory. If classpath is called in the test/SRC directory, the root directory of the class is target/test classes

Solution 2: set the resources directory to resource roots

However, the tartset directory is the output directory of compilation results. It’s not appropriate to put the configuration files in this directory. And there are many articles on the Internet that say that the configuration file should be in the resource directory. Look again to see if there is a better solution

Some say it can be placed in the SRC directory, but it still doesn’t work after trying. It is also not allowed to try to place it in the root directory of the project, that is, at the same level as the POM. XML file. Try to put it in the Src/resources directory, which is also not allowed

Until I read this article, to solve the problem, it turned out that one step was missing

In idea, click the resources directory, click “mark directory as” in the pop-up box, and then select “resource roots” to convert the directory to resource roots

According to the Maven standard directory structure, there will be resources directory under the main and test directory

src/main/java	    Application/Library sources (java source files, will be automatically compiled to the classes folder)
src/main/resources Application/Library resources (resource library, will be automatically compiled to the classes folder)
src/test/java Test sources (test java source files)
src/test/resources Test resources (library of resources needed for testing)

Code instance

The complete Java code is as follows:

package com.wang123net;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;

public class App 
{
    private static final Logger logger = LoggerFactory.getLogger(App.class);

    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );

        
        String s = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        System.out.println("classpath : " + s );

        System.out.println("----> logback start");
        logger.trace("--> Hello trace.");
        logger.debug("--> Hello debug.");
        logger.info("--> Hello info.");
        logger.warn("--> Goodbye warn.");
        logger.error("--> Goodbye error.");
        System.out.println("----> logback end");

        
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        StatusPrinter.print(lc);
    }

}

The configuration file is as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%d{YY-mm-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--<logger name="com.wang123net.App" level="debug" />-->
	
	<!--root设置全局的log level-->
    <root level="warn">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

The output log is as follows:

Hello World!
classpath : /Users/wangtest/IdeaProjects/wang123nettest/target/classes/
----> logback start
18-28-21 15:28:27.741 [main] WARN  com.wang123net.App - --> Goodbye warn.
18-28-21 15:28:27.744 [main] ERROR com.wang123net.App - --> Goodbye error.
----> logback end
15:28:27,561 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:/Users/wangtest/IdeaProjects/wang123net/target/classes/logback-test.xml]
15:28:27,646 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
15:28:27,648 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
15:28:27,660 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
15:28:27,670 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
15:28:27,735 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to WARN
15:28:27,735 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
15:28:27,736 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
15:28:27,737 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@ba4d54 - Registering current configuration as safe fallback point

You can see that the output log level corresponds to the configuration file

It is worth noting that the internal status of printing logback is “found resource [logback test. XML] at [file/users/wangtest/ideaprojects/wang123net/target/classes/logback test. XML]”. The configuration file is still in the /target/classes/ directory, because the resource (Resource Library) will be automatically compiled into the classes directory