配置 SpringBoot, 從日誌配置提及

應用能夠死, 日誌必須活.html


大小系統都須要打日誌.java

系統在不一樣環境下對日誌的配置要求是不同的spring

好比bash

開發本地: 直接輸出到控制檯app

生產環境: 輸出到文件或者額外的日誌收集系統, 好比 graylog.ide

(本文不探討具體日誌系統的配置)spring-boot

Spring Boot 官方方案

Profile-specific Configuration

1545102456.png
Logback 專屬, 各環境配置歸於同一文件, 經過 Spring Profile 啓用.

  • 優勢: 幾乎無改動, 只需系統配置文件制定 spring.profiles.action=
  • 缺點: 多環境配置混合在一塊兒, 應用運行時應該對運行配置無感知.

放棄.spa

配置 logging.config

1545102771.png

須要在配置文件中指定 logging.config命令行

須要提供多個 日誌配置文件日誌

e.g

logging.config=classpath:logback-console.xml
logging.config=classpath:logback-file.xml
logging.config=classpath:logback-graylog.xml
複製代碼

可行.

落地

採用 配置 logging.config 方案

背景: 公司配置文件採用基於文件的配置中心, 經過發佈系統發佈到應用機器指定目錄, 應用始終讀取指定目錄下配置文件.

幾個問題

  1. 如何讀取指定目錄應用配置?
  2. 如何保證日誌初始化時能讀取到指定的 config ?

官方的外置配置文件加載順序

1545103791.png

從文檔能夠看出, 默認的 Spring Boot 應用的配置文件 classpath:application.propreties 是在第 15 順位上加載的.

Application properties packaged inside your jar (application.properties and YAML variants).

@PropertySource ?

即第 16 順位的選擇.

然而, 事情沒有這麼簡單.

日誌系統因爲其特殊性, 須要儘量早的初始化.

Since logging is initialized before the ApplicationContext is created, it is not possible to control logging from @PropertySources in Spring @Configuration files. The only way to change the logging system or disable it entirely is via System properties. 大意就是 logging system 初始化在 ApplicationContext 建立以前, 因此 @PropertySource 這種配置方式是沒法影響到日誌系統初始化的(畢竟事兒都幹完了)

此路不通

Command line arguments ?

順着配置順序往上找, 相對來說 命令行參數 能夠成本極低的應用上去.

e.g

public static void main(String[] args) throws UnknownHostException {
    System.out.println(new Date() + " loaded...");
    args = new String[1];
    args[0] =
      "--spring.config.location=/etc/conf/app/xxx/application.properties";

    ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
    ConfigurableEnvironment env = context.getEnvironment();

    log.info("\n----------------------------------------------------------\n\t" +
        "Application '{}' is running! Access URLs:\n\t" +
        "Local: \t\thttp://localhost:{}\n\t" +
        "External: \thttp://{}:{}\n\t" +
        "Profile(s): \t{}\n----------------------------------------------------------",
      env.getProperty("spring.application.name"),
      env.getProperty("server.port"),
      InetAddress.getLocalHost().getHostAddress(),
      env.getProperty("server.port"),
      env.getActiveProfiles());

    System.out.println(new Date() + " started...");
  }
複製代碼

如預期, 日誌系統使用了正確的指定配置.

告一段落

問題基本解決, 但並不優雅, hack 命令行參數, 而且存在必定的侷限性. 此處暫且擱置.

後記

  • 有沒有更優雅的解決此問題的方法?
  • 爲什麼 Spring Boot 的配置文件加載順序是這般定義?
  • Spring Boot 加載配置是如何實現的?
  • Spring Cloud Config 等配置中心的配置是如何結合到具體應用中的?
  • Spring Cloud Config 等配置中心的配置支持日誌系統配置文件位置的配置嗎? ...

待後續拆而析之.

REF

相關文章
相關標籤/搜索