Search code examples
spring-bootlogginglogbackspring-logbackspring-boot-starter

Logback configuration in custom Spring Boot starter


The purpose of a custom Spring Boot starter is to provide a default Logback XML configuration, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml"/>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

It also provides a default logging.pattern.level defined in the starter's properties loaded by EnvironmentPostProcessor. For instance, let's assume it appends spring.application.name to the logging level:

logging.pattern.level=%5p [${spring.application.name}]

The problems that occur:

  • Property spring.application.name is not recognized:

2023-02-07 09:44:00.704 INFO [spring.application.name_IS_UNDEFINED] 70495 ---...

  • The default logging.pattern.level cannot be overridden in the application properties. For example, if the application.properties contains the property:
logging.pattern.level=%5p stackoverflow
@Bean
public String test(@Value("${logging.pattern.level}") String loggingPattern) {
  Logger logger = Logger.getLogger("LogDemo");
  logger.info(loggingPattern);
  return loggingPattern;
}

2023-02-07 09:57:50.124 INFO [spring.application.name_IS_UNDEFINED] 70880 --- [ main] LogDemo : %5p stackoverflow

If logback.xml is not defined in the custom starter the spring.application.name is recognized successfully. If logging.pattern.level is moved from the starter's properties to the application.properties it also works.

It seems like logging is being configured right after loading the starter's properties but before loading the application properties, in case the starter's properties contain the logging.pattern.level.

Is there a way to define a default logging configuration without the problems listed above?


Solution

  • I managed to define a default logging configuration in a custom starter using Spring Boot's extensions to Logback, without additional properties and EnvironmentPostProcessor.

    Because the standard logback.xml configuration file is loaded too early, you cannot use extensions in it. You need to either use logback-spring.xml or define a logging.config property.

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <springProperty scope="context" name="SPRING_APPLICATION_NAME" source="spring.application.name"/>
        <springProperty scope="context" name="SPRING_LOG_LEVEL_PATTERN" source="logging.pattern.level"/>
        <property name="DEFAULT_LOG_LEVEL_PATTERN"
                  value="%5p [${SPRING_APPLICATION_NAME}]"/>
        <property name="LOG_LEVEL_PATTERN"
                  value="${SPRING_LOG_LEVEL_PATTERN:-${DEFAULT_LOG_LEVEL_PATTERN}}"/>
    
        <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
        <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
        <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
        <include resource="org/springframework/boot/logging/logback/file-appender.xml"/>
    
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </root>
    </configuration>