nacos作为配置中心是否可以将log4j2.xml配置在nacos上面实现动态配置

Created on 9 Apr 2020  ·  14Comments  ·  Source: alibaba/nacos

如题
我现在的做法是将spring的配置文件放到了nacos上面,可以通过logging:config:classpath:log4j2.xml之低昂配置文件的路径到编译目录下,但是我的想法是做到将配置文件放到nacos上,实现动态修改。不知现在nacos是否支持,如果支持,我该怎么实际应用

For example

My current practice is to put the spring configuration file on Nacos. I can go to the compilation directory through the low profile path of logging: config: classpath: log4j2.xml, but my idea is to put the configuration file on Nacos to realize dynamic modification. I don't know if Nacos supports it now. If so, how can I actually apply it

areSpring Boot areSpring Cloud

All 14 comments

这个是可以的,但是你需要自己修改下log4j的读取配置逻辑,或者修改springboot关于日志读取的相关代码,配置的读取时机这个是需要第三方生态组件去适配或者自己去实现的

我也有这个问题 实在搞不定的 水平比较差不会修改相关代码的感觉太复杂了 我用了一个比较low的办法

  1. 前提是log4j2.xml外置 比如同级目录的config内 也是sb默认的加载位置 本来我的程序也是要把log4j2.xml外置出来的
  2. 先预制一个默认的
  3. 使用javasdk的监听方式nacos上的配置 getConfigAndSignListener 并在listener里实现写入log4j2.xml中
  4. log4j2配置成热部署的 再修改后由自身机制保障重新加载
    当然了 如果官方能出一个更好的更简单的办法 就再好不过了

我也是遇到这个问题,发现nacos好像根本不支持log4j2.xml的配置,有没有解决办法

现在是这个问题。我从nacos配置中心拿到了配置文件。但是无法写入资源目录下。项目在idea环境下是没有问题的,但是当项目打成jar包之后就无法更新里面的配置文件了。这个问题有没有大神解决一下。有思路的可以聊一下,多谢了

现在是这个问题。我从nacos配置中心拿到了配置文件。但是无法写入资源目录下。项目在idea环境下是没有问题的,但是当项目打成jar包之后就无法更新里面的配置文件了。这个问题有没有大神解决一下。有思路的可以聊一下,多谢了

将yml放在外面,与jar同级目录呢

这就相当于部署项目的时候不仅仅需要一个jar包。还需要一个配置文件放在外边。
jar包部署还好点。那如果是使用容器部署就很难操作了

还需要一个配置文件放在外边。
jar包部署还好点。那如果是使用容器部署就很难操作了

能否看下你的实现代码?我最近也遇到一些问题,借鉴一下.谢谢.

现在有好的解决方案吗

现在有好的解决方案吗
在nacos上面新建日志配置文件log4j2.xml
然后在项目配置文件中这样配置:
logging:
config: http://${spring.cloud.nacos.discovery.server-addr}/nacos/v1/cs/configs?dataId=log4j2.xml&group=DEFAULT_GROUP
应该就能找到,这是springcloud的解决方案。我试了是可以的。但是生产环境下edas是不好用的

我才用了 nacos上配置日志参数及logging:config:classpath:log4j2.xml
然后自定义AbstractLookup方式获取

现在有好的解决方案吗

我的实现方式是:

  1. 将 log4j2 配置文件外置 (通过 logging.config 指定配置路径不加 classpath 前缀实现 )
  2. 程序启动时将 nacos 中的 log4j2 配置加载到本地
    配置文件从 nacos 加载到本地的时机要比 LoggingApplicationListener 和 PropertySourceBootstrapConfiguration 高,核心代码如下(代码基于 nacos-client 1.1 和 SpringCloud Greenwich.SR1 实现,只包含核心思想):
public class Log4j2ConfigLoaderForNacosApplicationListener
        implements GenericApplicationListener {

    private static final Class<?>[] EVENT_TYPES = {
            ApplicationEnvironmentPreparedEvent.class };

    private static final Class<?>[] SOURCE_TYPES = { SpringApplication.class,
            ApplicationContext.class };

    @Override
    public boolean supportsEventType(ResolvableType eventType) {
        return isAssignableFrom(eventType.getRawClass(), EVENT_TYPES);
    }

    private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {
        if (type != null) {
            for (Class<?> supportedType : supportedTypes) {
                if (supportedType.isAssignableFrom(type)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return isAssignableFrom(sourceType, SOURCE_TYPES);
    }

    /**
     * 优先级要比 {@link LoggingApplicationListener#getOrder()} 高 目的在于让
     * {@link LoggingApplicationListener} 初始化日志配置时 log4j2 的配置文件已从配置中心加载到本地能够被其读取
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 19;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            ConfigurableEnvironment environment = ((ApplicationEnvironmentPreparedEvent) event)
                    .getEnvironment();

            if (NacosHelper.isNacosConfigEnabled(environment)) {
                Log4j2NacosConfigLoader log4J2NacosConfigLoader = new Log4j2NacosConfigLoader(
                        environment);
                log4J2NacosConfigLoader.loadLog4j2Config(environment.getActiveProfiles(),
                        LoggingHelper.getLoggingConfig(environment));
            }
        }
    }

}
@Configuration
@EnableConfigurationProperties(PropertySourceBootstrapProperties.class)
public class Log4j2LoadNacosConfigBootstrapConfiguration implements
        ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {

    private int order = Ordered.HIGHEST_PRECEDENCE + 9;

    @Autowired(required = false)
    private List<PropertySourceLocator> propertySourceLocators = new ArrayList<>();

    public void setPropertySourceLocators(
            Collection<PropertySourceLocator> propertySourceLocators) {
        this.propertySourceLocators = new ArrayList<>(propertySourceLocators);
    }

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        if (NacosHelper.isNacosConfigEnabled(environment)) {
            String oldLoggingConfig = LoggingHelper.getLoggingConfig(environment);
            PropertyResolver complete = getPropertyResolver(environment);
            String newLoggingConfig = LoggingHelper.getLoggingConfig(complete);
            new Log4j2NacosConfigLoader(complete)
                    .loadLog4j2Config(environment.getActiveProfiles(), newLoggingConfig)
                    .deleteOldLog4j2Config(oldLoggingConfig, newLoggingConfig);
        }
    }

    private PropertyResolver getPropertyResolver(ConfigurableEnvironment environment) {
        CompositePropertySource extPropertySource = new CompositePropertySource(
                "EXT-TEMP");
        AnnotationAwareOrderComparator.sort(this.propertySourceLocators);
        boolean empty = true;
        for (PropertySourceLocator locator : this.propertySourceLocators) {
            PropertySource<?> source = null;
            source = locator.locate(environment);
            if (source == null) {
                continue;
            }
            extPropertySource.addPropertySource(source);
            empty = false;
        }
        if (!empty) {
            MutablePropertySources complete = new MutablePropertySources(
                    environment.getPropertySources());
            complete.addFirst(extPropertySource);
            return new PropertySourcesPropertyResolver(complete);
        }
        else {
            return environment;
        }
    }

    /**
     * 优先级要比 {@link PropertySourceBootstrapConfiguration#getOrder()} 高 目的在于让
     * {@link PropertySourceBootstrapConfiguration} 重新从外部 {@link PropertySource} 刷新日志配置时
     * log4j2 的配置文件已从配置中心加载到本地能够被其读取
     */
    @Override
    public int getOrder() {
        return order;
    }
}

Nacos本身只负责配置的分发,至于加载的这属于客户端自己需要考虑的问题,我想这个功能应该提到周边生态上,比如Spring cloud alibaba 或者你使用了自己的生态,可以通过Nacos的Client客户端去自定义集成。

Nacos本身只负责配置的分发,至于加载的这属于客户端自己需要考虑的问题,我想这个功能应该提到周边生态上,比如Spring cloud alibaba 或者你使用了自己的生态,可以通过Nacos的Client客户端去自定义集成。

完全同意,Nacos作为配置中心并不关心使用者如何使用配置项,只对配置项进行管理才是正确的。

Was this page helpful?
0 / 5 - 0 ratings