【问题标题】:Dump Spring boot Configuration转储 Spring Boot 配置
【发布时间】:2016-02-22 00:41:41
【问题描述】:

我们的运维人员希望在应用启动时将 Spring 引导配置(即所有属性)转储到日志文件中。我假设这可以通过注入带有注释 @ConfigurationProperties 的属性并打印它们来完成。

问题在于是否有更好的或内置的机制来实现这一点。

鉴于似乎没有内置的解决方案,我试图自己做饭。这是我想出的:

@Component
public class ConfigurationDumper {


    @Autowired
    public void init(Environment env){
        log.info("{}",env);
    }

}

这样做的挑战是它不会打印我的 application.yml 中的变量。相反,这是我得到的:

StandardServletEnvironment 
{
    activeProfiles=[],
    defaultProfiles=[default],
    propertySources=[
        servletConfigInitParams,
        servletContextInitParams,
        systemProperties,
        systemEnvironment,
        random,
        applicationConfig: [classpath: /application.yml]
    ]
}

如何解决这个问题,以便加载和打印所有属性?

【问题讨论】:

    标签: spring configuration spring-boot


    【解决方案1】:

    如果您使用 actuatorenv endpoint 将为您提供在ConfigurableEnvironment 中设置的所有配置属性,configprops 将为您提供@ConfigurationProperties 的列表,但不在日志中。

    查看source codeenv 端点,它可能会让您了解如何获取您感兴趣的所有属性。

    【讨论】:

      【解决方案2】:

      没有内置机制,这实际上取决于您所说的“所有属性”是什么意思。您只想要 编写的实际键还是想要所有属性(包括默认值)。

      对于前者,您可以轻松收听ApplicationEnvironmentPreparedEvent 并记录您感兴趣的属性来源。对于后者,/configprops 确实是一个更好/完整的输出。

      【讨论】:

        【解决方案3】:

        这仅记录配置的属性 *.properties 文件。

        /**
         * maps given property names to its origin
         * @return a map where key is property name and value the origin
         */
        public Map<String, String> fromWhere() {
            final Map<String, String> mapToLog = new HashMap<>();
        
            final MutablePropertySources propertySources = env.getPropertySources();
        
            final Iterator<?> it = propertySources.iterator();
        
            while (it.hasNext()) {
                final Object object = it.next();
                if (object instanceof MapPropertySource) {
                    MapPropertySource propertySource = (MapPropertySource) object;
                    String propertySourceName = propertySource.getName();
        
                    if (propertySourceName.contains("properties")) {
        
                        Map<String, Object> sourceMap = propertySource.getSource();
        
                        for (String key : sourceMap.keySet()) {
                            final String envValue = env.getProperty(key);
                            String env2Val = System.getProperty(key);
        
                            String source = propertySource.getName().contains("file:") ? "FILE" : "JAR";
        
                            if (envValue.equals(env2Val)) {
                                source = "ENV";
                            }
        
                            mapToLog.putIfAbsent(key, source);               
                        }
                    }
                }
            }
            return mapToLog;
        }
        

        我的示例输出描述了属性名称、值及其来源。我的属性值描述了它们的来源。:

        myprop: fooFromJar from JAR
        aPropFromFile: fromExternalConfFile from FILE
        mypropEnv: here from vm arg from ENV
        
        • ENV 表示我已经通过 -D 将它交给了 JVM。
        • JAR 表示它来自 JAR 中的 application.properties
        • FILE 表示它来自 JAR 之外的 application.properties

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-28
          • 2017-05-02
          • 2016-01-09
          • 2015-12-26
          • 2016-04-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多