Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加EnvironmentPostProcessor处理,将Apollo配置加载提到初始化日志系统之前 #1614

Merged

Conversation

LuanLouis
Copy link
Contributor

@LuanLouis LuanLouis commented Oct 29, 2018

解决的问题:

将Apollo的配置加载提到Spring 初始化日志系统之前,能够让 logback-spring.xml可以读取到Apollo中的配置数据

目前版本存在的问题:

目前Apollo加载配置信息的时机如下图所示:
image
目前Apollo加载配置信息的时机比日志系统初始化晚,如果要让logbak-spring.xml文件能够正常读取Apollo的配置,则有两种方案可供选择:

方案一:在ConfigFileApplicationListenerLoggingApplicationListener之间插入一个监听器,用于初始化Apollo 配置信息;

这种方式在SpringBoot模式下想在这两者之间插入一个Listener 有点问题,Spring Boot 会将添加的Listener踢掉,目前还没弄清楚咋回事;另外这种插入方式和Listener的Order顺序有关,写死顺序不是很优雅;

方案二:实现一个EnvironmentPostProcessor,供ConfigFileApplicationListener在加载好bootstrap.properties 和application.properties之后加载Apollo的配置信息

这种方式比较好些,添加一个EnvironmentPostProcessor实现,然后在spring.factories里面指定即可

org.springframework.boot.env.EnvironmentPostProcessor=\
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer

注意:
这种方式使得Apollo的加载顺序放到了日志系统加载之前,会导致Apollo的启动过程无法通过日志的方式输出(因为执行Apollo加载的时候,日志系统压根没有准备好呢!所以在Apollo代码中使用Slf4j的日志输出便没有任何内容)

这种加载时间太靠前的方式不是必选的,通过参数apollo.bootstrap.eagerLoad.enabled可控制是否走这种逻辑:

  /**
   *
   * In order to load  Apollo configurations even as early before Spring loading logging system phase,
   *
   *  This EnvironmentPostProcessor can be called Just After ConfigFileApplicationListener has succeeded.
   *
   *
   *  The processing sequence would be like this:
   *
   *  Load Bootstrap properties and application properties -----> load Apollo configuration properties ----> Initialize Logging systems
   *
   *
   *
   * @param configurableEnvironment
   * @param springApplication
   */
  @Override
  public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {

    Boolean eagerLoadEnabled  = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_EAGER_LOAD_ENABLED,Boolean.class,false);


    //EnvironmentPostProcessor should not be triggered if you don't want Apollo Loading before Logging System Initialization
    if(!eagerLoadEnabled){
      return;
    }

    Boolean bootstrapEnabled = configurableEnvironment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED,Boolean.class,false);

    if(bootstrapEnabled) {
        initialize(configurableEnvironment);
    }

  }

@LuanLouis
Copy link
Contributor Author

#1243

@codecov-io
Copy link

codecov-io commented Oct 29, 2018

Codecov Report

Merging #1614 into master will increase coverage by 7.47%.
The diff coverage is 90%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #1614      +/-   ##
============================================
+ Coverage     48.71%   56.18%   +7.47%     
+ Complexity     1901     1067     -834     
============================================
  Files           392      191     -201     
  Lines         11483     5656    -5827     
  Branches       1195      591     -604     
============================================
- Hits           5594     3178    -2416     
+ Misses         5459     2237    -3222     
+ Partials        430      241     -189
Impacted Files Coverage Δ Complexity Δ
...ring/boot/ApolloApplicationContextInitializer.java 97.72% <90%> (+3.44%) 14 <2> (+4) ⬆️
...ework/apollo/portal/controller/ItemController.java
...o/configservice/wrapper/DeferredResultWrapper.java
...omponent/emailbuilder/GrayPublishEmailBuilder.java
...k/apollo/portal/controller/FavoriteController.java
...apollo/portal/entity/vo/AppRolesAssignedUsers.java
...ponent/emailbuilder/NormalPublishEmailBuilder.java
.../framework/apollo/portal/entity/vo/SystemInfo.java
...rk/apollo/portal/service/NamespaceLockService.java
...k/apollo/portal/spi/ctrip/CtripUserInfoHolder.java
... and 193 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 10fdf4d...0b098f6. Read the comment docs.

@coveralls
Copy link

coveralls commented Oct 29, 2018

Coverage Status

Coverage increased (+0.05%) to 52.506% when pulling f427699 on LuanLouis:pr-eager-load-before-logging into 703398f on ctripcorp:master.

@nobodyiam
Copy link
Member

Thanks! Will take a detailed look soon.

@pandalin
Copy link

pandalin commented Nov 2, 2018

作者看着好眼熟。。。

Copy link
Member

@nobodyiam nobodyiam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LuanLouis

This works great!

However, there is an issue of the executing sequence of initializeSystemProperty, so I submitted a pull request to your repository instead, please have a look - LuanLouis#1

Thank!

Copy link
Member

@nobodyiam nobodyiam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@nobodyiam nobodyiam merged commit f79f1ac into apolloconfig:master Nov 5, 2018
@hnotyet
Copy link

hnotyet commented Jun 13, 2019

这个方案解决了logback可以加载到apollo的配置,但是修改apollo无法做到日志参数跟着变,比如修改日志级别。看了springboot关于 logback扩展的文档,如果使用了扩展,logback原本的scan功能将失效,不知道跟这个是否有关系,希望能够优化。原文地址:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logback-extensions

@bugmakesprogress
Copy link

这个方案解决了logback可以加载到apollo的配置,但是修改apollo无法做到日志参数跟着变,比如修改日志级别。看了springboot关于 logback扩展的文档,如果使用了扩展,logback原本的scan功能将失效,不知道跟这个是否有关系,希望能够优化。原文地址:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logback-extensions

如果只是日志级别的话,是可以做到动态修改日志级别的。 添加@ApolloConfigChangeListener注解,然后在application这个默认(看看你是不是使用的默认namespace)的namespace里添加对应日志级别即可控制细化到某一类的日志级别。
具体可以参考下下面两个链接:
https://www.jianshu.com/p/7d91cb5109a4
https://blog.csdn.net/qq_31289187/article/details/84346529

@lawrencewu
Copy link

lawrencewu commented Jul 24, 2019

@nobodyiam @LuanLouis 测试了springboot 项目(无logback.xml)的情形和spring+logback.xml的情形以及spring+logback-spring.xml的情形, 发现这个配置只在springboot项目下生效, 在spring项目中无效, 是吗?

@nobodyiam
Copy link
Member

@lawrencewu apollo.bootstrap.eagerLoad.enabled这个配置是针对Spring Boot生效的

@lawrencewu
Copy link

lawrencewu commented Jul 27, 2019

@nobodyiam 有两个问题 1. 那在Spring下有什么办法能让logback.xml读取apollo配置中心里面的内容吗? 如下面配置中的logger_logback_logpath. 2. 在3.2.1.3 Spring Boot集成方式(推荐)中应该是只针对springboot的应用吧, 针对spring应用该如何操作,能不能进一步细化该节的文档?

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="utf-8">
            <Pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] %logger %line --%mdc{client} %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="logfile-core" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${logger_logback_logpath}/sample.log</File>
        <encoder>
            <pattern>[%date] [%level] [%logger %line] [%thread] %msg %n</pattern>
            <charset>UTF-8</charset>
            <immediateFlush>false</immediateFlush>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logger_logback_logpath}/sample-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>3</maxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>512MB</maxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold >0</discardingThreshold>
        <queueSize>1024</queueSize>
        <includeCallerData>true</includeCallerData>
        <appender-ref ref ="logfile-core"/>
    </appender>

    <logger name="org.apache.commons" level="INFO"/>
    <logger name="org.springframework" level="INFO"/>
    <logger name="org.springframework.web.servlet.DispatcherServlet" level="INFO"/>
    <logger name="org.springframework.web.context.support.XmlWebApplicationContext" level="INFO"/>
    <logger name="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" level="INFO"/>
    <logger name="java.sql.PreparedStatement" level="INFO"/>
    <logger name="java.sql" level="INFO"/>
    <logger name="java.sql.Statement" level="INFO"/>
    <logger name="java.sql.ResultSet" level="INFO"/>
    <logger name="java.sql.Connection" level="INFO"/>
    <root level="${logging.level.root}">
        <appender-ref ref="ASYNC"/>
        <appender-ref ref="stdout"/>
    </root>
</configuration>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants