복붙노트

[SPRING] 어떻게 봄 부팅 응용 프로그램에서 활성 구성을 기록하는?

SPRING

어떻게 봄 부팅 응용 프로그램에서 활성 구성을 기록하는?

난 정말이 상당히 읽기 쉽고 유용한 속성 내 다른 프로필에서 활약하는 것을 보여주는 하나의 파일을 찾을으로, 봄 부팅을 위해 YAML의 설정을 사용하고 싶습니다. 불행히도, 난 application.yml에 속성을 설정하는 것은 다소 취약 할 수 있다는 찾는거야.

속성 (최대한 멀리 볼 수 경고없이) 존재하지하게됩니다 대신 공간의 탭을 사용하고, 같은 상황이 너무 자주 내 활성 프로파일이 때문에 내 YAML에 알 수없는 문제로, 설정되지 않는 것을 찾을 수 있습니다.

그래서 나는 내가 그들을 로그인 할 수 있도록, 현재 활성화 된 프로파일 및 속성 잡아 저를 가능하게하는 어떤 고리가 있는지 궁금 해서요.

마찬가지로, application.yml에 오류가있는 경우 실패 시작을 야기 할 수있는 방법은 무엇입니까? 어느 쪽이든 또는 내가 시작 프로세스를 종료 할 수 있도록 나를는 YAML 자신을 검증하기위한 수단.

해결법

  1. ==============================

    1.저도 같은 문제가 있고, 유용한 로깅을 뱉어 프로파일 처리 시스템을 말할 것 디버그 플래그가 있었다 바랍니다. 응용 프로그램 컨텍스트에 대한 이벤트 리스너를 등록하고, 환경에서 프로파일을 인쇄하는 것입니다 그것을하는 한 가지 방법입니다. 나는 이런 식으로 자신을 일을 시도하지 않은, 그래서 귀하의 마일리지가 다를 수 있습니다. 나는 여기에 설명 무슨 같은 아마 뭔가를 생각한다 :

    저도 같은 문제가 있고, 유용한 로깅을 뱉어 프로파일 처리 시스템을 말할 것 디버그 플래그가 있었다 바랍니다. 응용 프로그램 컨텍스트에 대한 이벤트 리스너를 등록하고, 환경에서 프로파일을 인쇄하는 것입니다 그것을하는 한 가지 방법입니다. 나는 이런 식으로 자신을 일을 시도하지 않은, 그래서 귀하의 마일리지가 다를 수 있습니다. 나는 여기에 설명 무슨 같은 아마 뭔가를 생각한다 :

    어떻게 응용 프로그램 컨텍스트 초기화 이벤트에 후크를 추가하려면?

    그런 다음 리스너에서 같은 것을 할 것입니다 :

    System.out.println("Active profiles: " + Arrays.toString(ctxt.getEnvironment().getActiveProfiles()));
    

    시도 가치가있을 수도 있습니다. 당신은 아마 환경을 선언하는 것입니다 할 수있는 또 다른 방법은 프로파일을 인쇄하는 데 필요한 코드를 주입한다. 즉 :

    @Component
    public class SomeClass {
      @Autowired
      private Environment env;
      ...
      private void dumpProfiles() {
        // Print whatever needed from env here
      }
    }
    
  2. ==============================

    2.액추에이터 / ENV 서비스 속성을 표시하지만, 속성 값이 실제로 활성화되지 표시한다. 매우 자주 사용하여 응용 프로그램 속성을 재정의 할 수 있습니다

    액추에이터 / ENV 서비스 속성을 표시하지만, 속성 값이 실제로 활성화되지 표시한다. 매우 자주 사용하여 응용 프로그램 속성을 재정의 할 수 있습니다

    따라서 당신은 여러 곳에서 동일한 속성과 다른 값을 가질 것이다.

    시작시 울부 짖는 인쇄 활성 응용 프로그램 속성 값을 니펫

    @Configuration
    public class PropertiesLogger {
        private static final Logger log = LoggerFactory.getLogger(PropertiesLogger.class);
    
        @Autowired
        private AbstractEnvironment environment;
    
        @PostConstruct
        public void printProperties() {
    
            log.info("**** APPLICATION PROPERTIES SOURCES ****");
    
            Set<String> properties = new TreeSet<>();
            for (PropertiesPropertySource p : findPropertiesPropertySources()) {
                log.info(p.toString());
                properties.addAll(Arrays.asList(p.getPropertyNames()));
            }
    
            log.info("**** APPLICATION PROPERTIES VALUES ****");
            print(properties);
    
        }
    
        private List<PropertiesPropertySource> findPropertiesPropertySources() {
            List<PropertiesPropertySource> propertiesPropertySources = new LinkedList<>();
            for (PropertySource<?> propertySource : environment.getPropertySources()) {
                if (propertySource instanceof PropertiesPropertySource) {
                    propertiesPropertySources.add((PropertiesPropertySource) propertySource);
                }
            }
            return propertiesPropertySources;
        }
    
        private void print(Set<String> properties) {
            for (String propertyName : properties) {
                log.info("{}={}", propertyName, environment.getProperty(propertyName));
            }
        }
    
    }
    
  3. ==============================

    3.다른 답변에 추가 : 컨텍스트 새로 고침 이벤트에 활성 특성을 기록.

    다른 답변에 추가 : 컨텍스트 새로 고침 이벤트에 활성 특성을 기록.

    자바 (8)

    package mypackage;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.context.event.EventListener;
    import org.springframework.core.env.ConfigurableEnvironment;
    import org.springframework.core.env.MapPropertySource;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    @Slf4j
    @Component
    public class AppContextEventListener {
    
        @EventListener
        public void handleContextRefreshed(ContextRefreshedEvent event) {
            printActiveProperties((ConfigurableEnvironment) event.getApplicationContext().getEnvironment());
        }
    
        private void printActiveProperties(ConfigurableEnvironment env) {
    
            System.out.println("************************* ACTIVE APP PROPERTIES ******************************");
    
            List<MapPropertySource> propertySources = new ArrayList<>();
    
            env.getPropertySources().forEach(it -> {
                if (it instanceof MapPropertySource && it.getName().contains("applicationConfig")) {
                    propertySources.add((MapPropertySource) it);
                }
            });
    
            propertySources.stream()
                    .map(propertySource -> propertySource.getSource().keySet())
                    .flatMap(Collection::stream)
                    .distinct()
                    .sorted()
                    .forEach(key -> {
                        try {
                            System.out.println(key + "=" + env.getProperty(key));
                        } catch (Exception e) {
                            log.warn("{} -> {}", key, e.getMessage());
                        }
                    });
            System.out.println("******************************************************************************");
        }
    }
    

    코 틀린

    package mypackage
    
    import mu.KLogging
    import org.springframework.context.event.ContextRefreshedEvent
    import org.springframework.context.event.EventListener
    import org.springframework.core.env.ConfigurableEnvironment
    import org.springframework.core.env.MapPropertySource
    import org.springframework.stereotype.Component
    
    @Component
    class AppContextEventListener {
    
        companion object : KLogging()
    
        @EventListener
        fun handleContextRefreshed(event: ContextRefreshedEvent) {
            printActiveProperties(event.applicationContext.environment as ConfigurableEnvironment)
        }
    
        fun printActiveProperties(env: ConfigurableEnvironment) {
            println("************************* ACTIVE APP PROPERTIES ******************************")
            env.propertySources
                    .filter { it.name.contains("applicationConfig") }
                    .map { it as EnumerablePropertySource<*> }
                    .map { it -> it.propertyNames.toList() }
                    .flatMap { it }
                    .distinctBy { it }
                    .sortedBy { it }
                    .forEach { it ->
                        try {
                            println("$it=${env.getProperty(it)}")
                        } catch (e: Exception) {
                            logger.warn("$it -> ${e.message}")
                        }
                    }
            println("******************************************************************************")
        }
    }
    

    출력과 같은 :

    ************************* ACTIVE APP PROPERTIES ******************************
    server.port=3000
    spring.application.name=my-app
    ...
    2017-12-29 13:13:32.843  WARN 36252 --- [           main] m.AppContextEventListener        : spring.boot.admin.client.service-url -> Could not resolve placeholder 'management.address' in value "http://${management.address}:${server.port}"
    ...
    spring.datasource.password=
    spring.datasource.url=jdbc:postgresql://localhost/my_db?currentSchema=public
    spring.datasource.username=db_user
    ...
    ******************************************************************************
    
  4. ==============================

    4.application.yml 오류가있는 경우는 시작시 고장의 원인이됩니다. 나는 당신이 비록 "오류"가 무슨 뜻인지 달려 같아요. YAML이 잘 형성되어 있지 않은 경우 확실히 실패합니다. 또한이 예를 들어 진정한 ignoreInvalidFields =으로 표시됩니다 @ConfigurationProperties을 설정하는 경우, 또는 당신은 변환 할 수없는 값을 설정합니다. 즉 오류의 매우 넓은 범위입니다.

    application.yml 오류가있는 경우는 시작시 고장의 원인이됩니다. 나는 당신이 비록 "오류"가 무슨 뜻인지 달려 같아요. YAML이 잘 형성되어 있지 않은 경우 확실히 실패합니다. 또한이 예를 들어 진정한 ignoreInvalidFields =으로 표시됩니다 @ConfigurationProperties을 설정하는 경우, 또는 당신은 변환 할 수없는 값을 설정합니다. 즉 오류의 매우 넓은 범위입니다.

    활성 프로파일은 아마도 환경 구현에 의해 시작에 기록됩니다 (하지만 당신이 잡아하고 실행 코드에 로그하는 어떤 경우에 간단합니다 - 있으며, toString 내가 생각하는 활성 프로파일을 나열합니다 TEH 환경의 ()). 당신이 액추에이터를 추가하면 활성 프로파일 (등)도 / ENV 엔드 포인트에서 사용할 수 있습니다.

  5. ==============================

    5.경우 당신은 콩 / 응용 프로그램을 초기화하기 전에 활성 프로파일을 얻으려면, 내가 찾은 유일한 방법은 SpringBootServletInitializer / SpringApplication (즉 ApplicationWebXml JHipster 응용 프로그램)에 사용자 정의 배너를 등록한다.

    경우 당신은 콩 / 응용 프로그램을 초기화하기 전에 활성 프로파일을 얻으려면, 내가 찾은 유일한 방법은 SpringBootServletInitializer / SpringApplication (즉 ApplicationWebXml JHipster 응용 프로그램)에 사용자 정의 배너를 등록한다.

    EG

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
    {
        // set a default to use when no profile is configured.
        DefaultProfileUtil.addDefaultProfile(builder.application());
        return builder.sources(MyApp.class).banner(this::printBanner);
    }
    
    /** Custom 'banner' to obtain early access to the Spring configuration to validate and debug it. */
    private void printBanner(Environment env, Class<?> sourceClass, PrintStream out)
    {
        if (env.getProperty("spring.datasource.url") == null)
        {
            throw new RuntimeException(
                "'spring.datasource.url' is not configured! Check your configuration files and the value of 'spring.profiles.active' in your launcher.");
        }
        ...
    }
    

  6. from https://stackoverflow.com/questions/24448947/how-to-log-the-active-configuration-in-a-spring-boot-application by cc-by-sa and MIT license