Skip to content

Instantly share code, notes, and snippets.

@nemoinho
Last active November 12, 2020 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nemoinho/31fbf51226259d687fc7c6ea0032bbe1 to your computer and use it in GitHub Desktop.
Save nemoinho/31fbf51226259d687fc7c6ea0032bbe1 to your computer and use it in GitHub Desktop.

Error in Spring Cloud + Logback

Spring Cloud program uses logback error

Let me start with the conclusion

For Spring Cloud programs that do not use Spring Cloud Context, it is best to disable Spring Cloud Context, because if it is not disabled, it will cause some configuration loading errors. Disable method: add in the main SpringBoot function System.setProperty("spring.cloud.bootstrap.enabled", "false"); An example of this code is as follows:

@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("cn.xgq.operator.impl.mapper")
public class OperatorImplApplication {

    public static void main(String[] args) {
        // Disable Spring Cloud Context, otherwise logback-spring.xml will be loaded twice
        // Spring Cloud Context details: https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html
        System.setProperty("spring.cloud.bootstrap.enabled", "false");
        SpringApplication.run(OperatorImplApplication.class, args);
    }

}

Problem recurrence

The logback-spring.xml configuration contextName uses the spring.application.name configured in application.yml, the log file path uses logging.file.path, and then an error is reported after starting the application: Failed to rename context [projectName_IS_UNDEFINED] as [operator] java.lang.IllegalStateException: Context has been already given a name

Exception in thread "main" java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.classic.joran.action.ContextNameAction - Failed to rename context [projectName_IS_UNDEFINED] as [operator] java.lang.IllegalStateException: Context has been already given a name
	at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169)
	at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
	at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
	at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:118)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:313)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:288)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:76)
	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at cn.xgq.operator.OperatorImplApplication.main(OperatorImplApplication.java:17)

The logback-spring.xml part is configured as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
         <!-- Property file: Find the corresponding configuration item in the application.yml file -->
    <springProperty scope="context" name="filePath" source="logging.file.path"/>
    <springProperty scope="context" name="projectName" source="spring.application.name"/>
    <contextName>${projectName}</contextName>

    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
    	     <!-- appender configuration -->
    </appender>

         <!-- Separate logs according to log levels and output them to different files-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    	     <!-- appender configuration -->
    </appender>

    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
		 <!-- appender configuration -->
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>

The application.yml part is configured as follows:

server:
  port: 9001

spring:
  application:
    name: operator
  datasource:
    # Data source configuration

logging:
  file:
    path: ./logs

mybatis:
  mapper-locations: classpath:mapper/*.xml

eureka:
  client:
    service-url: {defaultZone: http://localhost:9002/eureka/}

The cause of the problem

Simply put, because the Spring Cloud program has two contexts, one is the "bootstrap" context, which is responsible for loading configuration properties from external sources and decrypting properties in local external configuration files, reading configuration properties from the bootstrap.yml file, and the other is The main program context, which mainly reads the configuration properties from application.yml or the external configuration center, and then both contexts will read the configuration of logback-spring.xml for loading, but because this application is not configured with bootstrap.yml, it is "booted" Cannot read when logback-spring.xml is loaded in the contextprojectName with filePath Variable value, so these two values will be used projectName_IS_UNDEFINED with filePath_IS_UNDEFINED As the value, when the main program context loads logback-spring.xml, because the contextName read at this time is different from the one loaded by the “bootstrap” context, an error is reported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment