According to log4j2 documentation:
The Spring Boot Lookup retrieves the values of Spring properties from the Spring configuration. This Lookup will return null values until Spring Boot initializes application logging.
<File name="Application" fileName="application.log"> <PatternLayout> <pattern>%d %p %c{1.} [%t] $${spring:spring.application.name} %m%n</pattern> </PatternLayout> </File>This Lookup requires log4j-spring-cloud-config-client be included in the application.
What is the proper way to configure such a lookup?
I tried to assemble the following application:
build.gradle
plugins { id 'org.springframework.boot' version '2.2.5.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java' } sourceCompatibility = '13' repositories{ mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-log4j2' } configurations { all { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' exclude group: "ch.qos.logback", module: "logback-classic" } }
main
@SpringBootApplication public class DemoApplication implements ApplicationRunner { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } private final Logger logger = LogManager.getLogger(); @Override public void run(ApplicationArguments args) throws Exception { logger.debug("Debugging log"); logger.info("Info log"); logger.warn("Hey, This is a warning!"); logger.error("Oops! We have an Error. OK"); logger.fatal("Damn! Fatal error. Please fix me."); } }
application.yml
spring.application.name: Demo
log4j-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <Appenders> <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true"> <PatternLayout> <pattern>%d %p %c{1.} [%t] $${spring:spring.application.name} %m%n</pattern> </PatternLayout> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="ConsoleAppender" /> </Root> </Loggers> </Configuration>
I expect the resolver to properly substitute “Demo” as the application name, however this does not happen. Does spring-boot-starter-log4j2 missing some dependencies for this to work out of the box ?
Edit This is the most simplified case. In reality, I want to pass the application-name to the gelf graylog appender. And I would like to share the same logging configuration within multiple components. So workarounds, like defining a log4j property, or using spring logging configuration, are not suitable.
Advertisement
Answer
Update 14.05.2021: Starting from log4j 2.14.0 there is a separate module for spring-lookup. Unfortunately, spring-boot still does not have high-enough dependency of log4j. But at least one can avoid using whole cloud-config-dependency.
implementation "org.apache.logging.log4j:log4j-api:${log4j2version}" implementation "org.apache.logging.log4j:log4j-core:${log4j2version}" implementation "org.apache.logging.log4j:log4j-spring-boot:${log4j2version}"
+++++++++++++++++++
Based on @rgoers input I was able to assemble minimal configuration to run log4j2 Spring lookup:
build.gradle
plugins { id 'org.springframework.boot' version '2.2.5.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java' } sourceCompatibility = '13' repositories{ mavenCentral() } ext{ log4j2version = '2.13.1' } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-log4j2' implementation "org.apache.logging.log4j:log4j-spring-cloud-config-client:${log4j2version}" implementation "org.apache.logging.log4j:log4j-api:${log4j2version}" implementation "org.apache.logging.log4j:log4j-core:${log4j2version}" } configurations { all { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' exclude group: "ch.qos.logback", module: "logback-classic" exclude group: "org.springframework.cloud", module: "spring-cloud-bus" } }
Additionally, to disable cloud-config (which is required for look up, but might not be needed for the application):
bootstrap.yml (separate file additional to application.yml)
spring.cloud.config.enabled: false