携程apollo配置中心使用

 

携程apollo配置中心搭建:https://blog.csdn.net/itwxming/article/details/104776170

目录

一、 服务接入配置中心

1.1、调整微服务配置

1.2 在配置中心中创建项目

1.3 在项目中创建Namespace

1.4 添加配置信息

1.5 发布

二、 公共空间使用

2.1 新建公共配置项目

2.2 新建公共Namespace

2.3 公共配置放入公共Namespace

2.4 微服务端bootstrap.yml配置

三、单个服务覆盖公共配置

3.1 新建Namespace

3.2 关联公共Namespace

3.3 修改要覆盖的配置

四、代码中具体使用相关

4.1客户端获取配置

4.1.1、最直接的Api方式

4.2、Spring Annotation支持

4.3、常见问题解决与实践

4.3.1、ConfigurationProperties注解配置的类使用Apollo没有随配置动态变化

4.3.2、日志级别配置没有更新

4.3.3、zuul做网关时动态路由等相关配置变化可发布事件RoutesRefreshedEvent

4.3.4、不同类型配置文件的监听


一、 服务接入配置中心

添加了apollo客户端依赖的微服务工程要接入配置中心,按以下后续步骤即可:

<dependency>
  <groupId>com.ctrip.framework.apollo</groupId>
  <artifactId>apollo-client</artifactId>
  <version>1.3.0</version>
</dependency>

1.1、调整微服务配置

微服务的boostrap.yml文件中,开发apollo的连接并配置正确的apollo地址:

app:
    id: mystart #apollo配置中心应用名
apollo:
    meta: http://192.168.232.128:9001 #apollo地址
    bootstrap:
        enabled: true #是否启用apollo
        namespaces: application.yml  #Namespace
        # namespaces: application.yml,application,TEST1.public #多个用逗号隔开,默认properties后缀

配置说明:

app.id:在配置中心配置的应用名。
apollo.bootstrap.enabled:在应用启动阶段是否向Spring容器注入被托管的properties文件配置信息。
apollo.bootstrap.namespaces:配置的命名空间,多个逗号分隔,一个namespace相当于一个配置文件。
apollo.meta:当前环境服务配置地址,生产环境建议至少双节点,可以填写多个逗号分隔,使用一个单独的域,如http://config.xxx.com(由nginx等软件负载平衡器支持),而不是多个IP地址,因为服务器可能会扩展或缩小。

apollo.bootstrap.eagerLoad.enabled:将Apollo配置加载提到初始化日志系统之前。如果希望把日志相关的配置(如logging.level.root=infologback-spring.xml中的参数)也放在Apollo管理,那么可以额外配置apollo.bootstrap.eagerLoad.enabled=true来使Apollo的加载顺序放到日志系统加载之前,不过这会导致Apollo的启动过程无法通过日志的方式输出(因为执行Apollo加载的时候,日志系统压根没有准备好呢!所以在Apollo代码中使用Slf4j的日志输出便没有任何内容),更多信息可以参考PR 1614

1.2 在配置中心中创建项目

登录配置中心(默认用户密码为apollo/admin),然后创建项目

应用Id为微服务接入Apollo的唯一标识。一般取工程创建后的配置文件boostrap.yml的app.id配置项的值,或自定义。

      务必保证此应用Id于微服务配置文件boostrap.yml中的app.id配置项保持一致!!!

1.3 在项目中创建Namespace

       点击左下角的“创建Namespace”

然后创建类型为"private",名称为application,后缀为yml的Namespace

创建完成后,直接返回到项目首页

1.4 添加配置信息

 点击右侧的“修改配置”按钮

将工程中的application.yml文件中的配置信息调整后,复制到文本框中,然后点击“修改提交”

1.5 发布

点击“发布”按钮后,会出现本次修改信息的弹框,检查无误后,点击最下方的“发布”按钮即可。

如上常规的配置使用即可以了。

二、 公共空间使用

一些多个微服务都会使用到的配置可以使用公共空间来配置

2.1 新建公共配置项目

2.2 新建公共Namespace

2.3 公共配置放入公共Namespace

2.4 微服务端bootstrap.yml配置

在原私有空间后,追加公共Namespace,如上的“TEST1.public-config”,英文逗号隔开:

app:
    id: mystart #apollo配置中心应用名
apollo:
    meta: http://192.168.232.128:9001 #apollo地址
    bootstrap:
        enabled: true #是否启用apollo
        namespaces: application.yml,TEST1.public-config  #Namespace

三、单个服务覆盖公共配置

如果在使用公共空间配置的时候,个别微服务的某个配置需要跟公共的项不一样,需要覆盖,则可通过关联公共Namespace来做。

3.1 新建Namespace

注意是新建Namespace,不需要再新建项目。进入要实现上述需求的那个项目中,点击左下角的“添加Namespace”。

3.2 关联公共Namespace

       namespace中选择要关联的公共Namespace。

提交后,先直接返回到项目首页,权限全部默认。

3.3 修改要覆盖的配置

注:1、关联公共配置只是单独给这个微服务修改了公共配置项,别的不影响。且服务的bootstrap.yml中namespaces任需配上上述公共空间TEST1.public-config。2、如果apollo上没有读到某个配置项,会去本地的application.yml配置文件找。3、Apollo会从远程拉取到本地生成缓存文件,如果远程连接有问题也会走本地的缓存文件。默认缓存目录:https://github.com/ctripcorp/apollo/wiki/Java客户端使用指南#123-本地缓存路径

  • Mac/Linux: /opt/data/{appId}/config-cache
  • Windows: C:\opt\data\{appId}\config-cache

四、代码中具体使用相关

4.1客户端获取配置

详见:https://github.com/ctripcorp/apollo/wiki/Java客户端使用指南#三客户端用法

4.1.1、最直接的Api方式

API方式是最简单、高效使用Apollo配置的方式,不依赖Spring框架即可使用。

4.1.1.1、获取默认namespace的配置(application)

Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
String someKey = "someKeyFromDefaultNamespace";
String someDefaultValue = "someDefaultValueForTheKey";
String value = config.getProperty(someKey, someDefaultValue);

通过上述的config.getProperty可以获取到someKey对应的实时最新的配置值。

另外,配置值从内存中获取,所以不需要应用自己做缓存

4.1.1.2、监听配置变化事件

监听配置变化事件只在应用真的关心配置变化,需要在配置变化时得到通知时使用,比如:数据库连接串变化后需要重建连接等。

如果只是希望每次都取到最新的配置的话,只需要按照上面的例子,调用config.getProperty即可。

Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
config.addChangeListener(new ConfigChangeListener() {
    @Override
    public void onChange(ConfigChangeEvent changeEvent) {
        System.out.println("Changes for namespace " + changeEvent.getNamespace());
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
        }
    }
});

 

4.2、Spring Annotation支持

Apollo同时还增加了几个新的Annotation来简化在Spring环境中的使用。

  1. @ApolloConfig:用来自动注入Config对象
  2. @ApolloConfigChangeListener:用来自动注册ConfigChangeListener
  3. @ApolloJsonValue:用来把配置的json字符串自动注入为对象

使用样例如下:

public class TestApolloAnnotationBean {
  @ApolloConfig
  private Config config; //inject config for namespace application
  @ApolloConfig("application")
  private Config anotherConfig; //inject config for namespace application
  @ApolloConfig("FX.apollo")
  private Config yetAnotherConfig; //inject config for namespace FX.apollo
  @ApolloConfig("application.yml")
  private Config ymlConfig; //inject config for namespace application.yml
 
  /**
   * ApolloJsonValue annotated on fields example, the default value is specified as empty list - []
   * <br />
   * jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
   */
  @ApolloJsonValue("${jsonBeanProperty:[]}")
  private List<JsonBean> anotherJsonBeans;

  @Value("${batch:100}")
  private int batch;
  
  //config change listener for namespace application
  @ApolloConfigChangeListener
  private void someOnChange(ConfigChangeEvent changeEvent) {
    //update injected value of batch if it is changed in Apollo
    if (changeEvent.isChanged("batch")) {
      batch = config.getIntProperty("batch", 100);
    }
  }
 
  //config change listener for namespace application
  @ApolloConfigChangeListener("application")
  private void anotherOnChange(ConfigChangeEvent changeEvent) {
    //do something
  }
 
  //config change listener for namespaces application, FX.apollo and application.yml
  @ApolloConfigChangeListener({"application", "FX.apollo", "application.yml"})
  private void yetAnotherOnChange(ConfigChangeEvent changeEvent) {
    //do something
  }

  //example of getting config from Apollo directly
  //this will always return the latest value of timeout
  public int getTimeout() {
    return config.getIntProperty("timeout", 200);
  }

  //example of getting config from injected value
  //the program needs to update the injected value when batch is changed in Apollo using @ApolloConfigChangeListener shown above
  public int getBatch() {
    return this.batch;
  }

  private static class JsonBean{
    private String someString;
    private int someInt;
  }
}

4.3、常见问题解决与实践

4.3.1、ConfigurationProperties注解配置的类使用Apollo没有随配置动态变化

比如:person01相关的配置变化之后程序没有动态变化。

/**
 * @author twotiger-wxm.
 * @date 2019/6/5.
 */
//prefix取配置的前缀,随便命名。
@EnableCaching//最简单的在启动类上开启此注解就可用spring那套注解缓存。但在单独配置类上加也行。但需要自己配置CacheManager,如下。
@ConfigurationProperties(prefix = "person01")
public class Person {
    private static final Logger logger = LoggerFactory.getLogger(Person.class);

    private String name;
    private Integer age;
    private Date birthDate;
    private List<String> pets;
    private List<String> cars;
    private Map maps;
    //myGirlFriend1必须是另一个类的类型,不能是Person类本身,否则myGirlFriend1=null。
    private GirlFriend myGirlFriend1;

解决方案:使用@ApolloConfigChangeListener监听配置变化,监听到之后去修改上下文中的内容(修改上下文spring已有实现,自己监听到之后将对应事件和内容传入即可。)

import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;

/**
 * 写一个配置类,类中去实现监听Apollo配置变化。
 */
@Configuration //或者@Component都可。
public class ApolloConfigListener implements ApplicationContextAware {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigListener.class);

    private ApplicationContext applicationContext;

   /**
     * 配置监听
     * @ApolloConfigChangeListener > value属性默认命名空间 "application",默认点properties结尾的。
     *
     * 示例: @ApolloConfigChangeListener(value = {"application", "test_space"})
     */
    @ApolloConfigChangeListener
    private void onChange(ConfigChangeEvent changeEvent) {
        LOGGER.info("【Apollo-config-change】start");
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            LOGGER.info("key={} , propertyName={} , oldValue={} , newValue={} ", key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
        }
        //发布EnvironmentChangeEvent事件,去更新相应的bean的属性值,主要是存在@ConfigurationProperties注解的bean
        this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));

        LOGGER.info("【Apollo-config-change】end");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

SpringCloud配置刷新监听实现源码:

该类监听了ChangeEnvrionmentEvent事件,它最主要作用是拿到更新的配置以后,重新绑定@ConfigurationProperties标记的类使之能够读取最新的属性:

@Component
@ManagedResource
public class ConfigurationPropertiesRebinder
        implements ApplicationContextAware, ApplicationListener<EnvironmentChangeEvent> {

    private ConfigurationPropertiesBeans beans;

    private ApplicationContext applicationContext;

    private Map<String, Exception> errors = new ConcurrentHashMap<>();

    public ConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
        this.beans = beans;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * A map of bean name to errors when instantiating the bean.
     *
     * @return the errors accumulated since the latest destroy
     */
    public Map<String, Exception> getErrors() {
        return this.errors;
    }

    @ManagedOperation
    public void rebind() {
        this.errors.clear();
        for (String name : this.beans.getBeanNames()) {
            rebind(name);
        }
    }

    @ManagedOperation
    public boolean rebind(String name) {
        if (!this.beans.getBeanNames().contains(name)) {
            return false;
        }
        if (this.applicationContext != null) {
            try {
                Object bean = this.applicationContext.getBean(name);
                if (AopUtils.isAopProxy(bean)) {
                    bean = getTargetObject(bean);
                }
                this.applicationContext.getAutowireCapableBeanFactory().destroyBean(bean);
                this.applicationContext.getAutowireCapableBeanFactory()
                        .initializeBean(bean, name);
                return true;
            }
            catch (RuntimeException e) {
                this.errors.put(name, e);
                throw e;
            }
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    private static <T> T getTargetObject(Object candidate) {
        try {
            if (AopUtils.isAopProxy(candidate) && (candidate instanceof Advised)) {
                return (T) ((Advised) candidate).getTargetSource().getTarget();
            }
        }
        catch (Exception ex) {
            throw new IllegalStateException("Failed to unwrap proxied object", ex);
        }
        return (T) candidate;
    }

    @ManagedAttribute
    public Set<String> getBeanNames() {
        return new HashSet<String>(this.beans.getBeanNames());
    }

    @Override//此处监听上下文变化事件
    public void onApplicationEvent(EnvironmentChangeEvent event) {
        if (this.applicationContext.equals(event.getSource())
                // Backwards compatible
                || event.getKeys().equals(event.getSource())) {
            rebind();
        }
    }

}

 

4.3.2、日志级别配置没有更新

解决方案:使用@ApolloConfigChangeListener监听配置变化,监听到之后去修改日志级别。

import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;

/**
 * 日志Apollo动态配置监听
 */
@Configuration
public class LoggerConfigListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConfigListener.class);
    private static final String LOGGER_TAG = "logging.level.";

    @Resource
    private LoggingSystem loggingSystem;//注入日志系统抽象类接口

    /**
     * 只监听对应的日志配置的变化
     */
    @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG)
    private void onChangeLogger(ConfigChangeEvent changeEvent) {
        LOGGER.info("【Apollo-logger-config-change】>> start");
        refreshLoggingLevel(changeEvent);
        LOGGER.info("【Apollo-logger-config-change】>> end");
    }

    /**
     * 刷新日志级别
     */
    private void refreshLoggingLevel(ConfigChangeEvent changeEvent) {
        if (null == loggingSystem) {
            return;
        }
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            if (!StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
                continue;//非日志配置的变化跳过。
            }
            LOGGER.info("【Apollo-logger-config-change】>> key={} , propertyName={} , oldValue={} , newValue={} ",
                    key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
            String newLevel = change.getNewValue();//获取新配置值
            LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
            loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);//修改日志系统级别。
            LOGGER.info("【Apollo-logger-config-change】>> {} -> {}", key, newLevel);
        }
    }
}

日志配置跟4.3.1的都是系统级别的配置,可整合在一起,中间做判断去做不同操作。

import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;

/**
 * Apollo动态配置监听
 */
@Configuration
public class ApolloConfigListener implements ApplicationContextAware {
    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigListener.class);
    /**
     * 日志配置常量
     */
    private static final String LOGGER_TAG = "logging.level.";

    @Resource
    private LoggingSystem loggingSystem;

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    /**
     * 监听所有配置变化
     */
    @ApolloConfigChangeListener
    private void onChangeConfig(ConfigChangeEvent changeEvent) {
        LOGGER.info("【Apollo-config-change】>> start");
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            LOGGER.info("【Apollo-config-change】>> key={} , propertyName={} , oldValue={} , newValue={} ",
                    key, change.getPropertyName(), change.getOldValue(), change.getNewValue());
            //是否为日志配置
            if (StringUtils.containsIgnoreCase(key, LOGGER_TAG)) {
                //日志配置刷新
                changeLoggingLevel(key, change);
                continue;
            }
            // 更新相应的bean的属性值,主要是存在@ConfigurationProperties注解的bean
            this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
        }
        LOGGER.info("【Apollo-config-change】>> end");
    }

    /**
     * 刷新日志级别
     */
    private void changeLoggingLevel(String key, ConfigChange change) {
        if (null == loggingSystem) {
            return;
        }
        String newLevel = change.getNewValue();
        LogLevel level = LogLevel.valueOf(newLevel.toUpperCase());
        loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), level);
        LOGGER.info("【Apollo-logger-config-change】>> {} -> {}", key, newLevel);
    }
}

4.3.3、zuul做网关时动态路由等相关配置变化可发布事件RoutesRefreshedEvent

    @Autowired
    private RouteLocator routeLocator;


/**
         * refresh routes。zuul已经实现的刷新事件监听见ZuulRefreshListener
         * @see org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration.ZuulRefreshListener#onApplicationEvent
         */
        this.applicationContext.publishEvent(new RoutesRefreshedEvent(routeLocator));

4.3.4、不同类型配置文件的监听

//不同类型的配置环境
public class ApolloConstants {
    
    public final static String NAMESPACE_APPLICATION_YAML = "application.yaml";
    
    public final static String NAMESPACE_APPLICATION_YML = "application.yml";
    
    public final static String NAMESPACE_APPLICATION_PROPERTIES = "application.properties";
    
    public final static String NAMESPACE_APPLICATION_XML = "application.xml";
    
    public final static String NAMESPACE_APPLICATION_JSON = "application.json";

}

以动态日志为例:

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 动态日志配置.
 */
public class DynamicRefreshLogLevelAutoConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(DynamicRefreshLogLevelAutoConfiguration.class);

    private static final String LOGGER_TAG = "logging.level.";

    /**
     * application.properties配置文件修改日志.
     * 默认开启.
     */
    @Configuration
    public class PropertiesRefreshLogLevel {

        @ApolloConfig
        private Config config;

        @ApolloConfigChangeListener(interestedKeyPrefixes = {LOGGER_TAG})
        private void onChange(ConfigChangeEvent changeEvent) {
            logger.info("Properties configuration modify log level...");
            DynamicRefreshLogLevelAutoConfiguration.this.onChange(config, changeEvent);
        }

    }

    /**
     * application.yml配置文件修改日志
     */
    @Configuration
    @ConditionalOnExpression("'${apollo.bootstrap.namespaces}'.contains('" + ApolloConstants.NAMESPACE_APPLICATION_YML + "')")
    public class YmlRefreshLogLevel {

        @ApolloConfig(ApolloConstants.NAMESPACE_APPLICATION_YML)
        private Config config;

        @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG, value = ApolloConstants.NAMESPACE_APPLICATION_YML)
        private void onChange(ConfigChangeEvent changeEvent) {
            logger.info("yml configuration modify log level...");
            DynamicRefreshLogLevelAutoConfiguration.this.onChange(config, changeEvent);
        }

    }

    /**
     * application.yaml配置文件修改日志
     */
    @Configuration
    @ConditionalOnExpression("'${apollo.bootstrap.namespaces}'.contains('" + ApolloConstants.NAMESPACE_APPLICATION_YAML + "')")
    public class YamlRefreshLogLevel {

        @ApolloConfig(ApolloConstants.NAMESPACE_APPLICATION_YAML)
        private Config config;

        @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG, value = ApolloConstants.NAMESPACE_APPLICATION_YAML)
        private void onChange(ConfigChangeEvent changeEvent) {
            logger.info("yml configuration modify log level...");
            DynamicRefreshLogLevelAutoConfiguration.this.onChange(config, changeEvent);
        }

    }

    /**
     * application.xml配置文件修改日志
     *
     */
    /*@Configuration
    public class XmlRefreshLogLevel {
        
        @ApolloConfig(ApolloConstants.NAMESPACE_APPLICATION_XML)
        private Config config;
        
        @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG, value = ApolloConstants.NAMESPACE_APPLICATION_XML)
        private void onChange(ConfigChangeEvent changeEvent) {
            logger.info("xml配置修改日志级别...");
            DynamicRefreshLogLevelAutoConfiguration.this.onChange(config, changeEvent);
        }
        
    }*/

    /**
     * application.json配置文件修改日志
     */
    /*@Configuration
    public class JsonRefreshLogLevel {
        
        @ApolloConfig(ApolloConstants.NAMESPACE_APPLICATION_JSON)
        private Config config;
        
        @ApolloConfigChangeListener(interestedKeyPrefixes = LOGGER_TAG, value = ApolloConstants.NAMESPACE_APPLICATION_JSON)
        private void onChange(ConfigChangeEvent changeEvent) {
            logger.info("json配置修改日志级别...");
            DynamicRefreshLogLevelAutoConfiguration.this.onChange(config, changeEvent);
        }
        
    }*/

    @Autowired
    private LoggingSystem loggingSystem;

    private void onChange(Config config, ConfigChangeEvent event) {
        Set<String> loggingKeys = event.changedKeys();
        Map<String, String> loggings = new HashMap<>();
        loggingKeys.forEach(s -> loggings.put(s, config.getProperty(s, "info")));
        refreshLoggingLevels(loggings);
    }

    private void refreshLoggingLevels(Map<String, String> loggings) {
        for (String key : loggings.keySet()) {
            String level = loggings.get(key);
            LogLevel logLevel = LogLevel.valueOf(level.toUpperCase());
            loggingSystem.setLogLevel(key.replace(LOGGER_TAG, ""), logLevel);
            logger.info("{}:{}", key, level);
        }
    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值