../beginer-for-sb-logging-system-configuration

配置 SpringBoot, 从日志配置说起

Published:

spring springboot config

应用可以死, 日志必须活.

大小系统都需要打日志.

系统在不同环境下对日志的配置要求是不一样的

比如

开发本地: 直接输出到控制台

生产环境: 输出到文件或者额外的日志收集系统, 比如 graylog.

(本文不探讨具体日志系统的配置)

Spring Boot 官方方案

Profile-specific Configuration

1545102456.png Logback 专属, 各环境配置归于同一文件, 通过 Spring Profile 启用.

放弃.

配置 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 命令行参数, 并且存在一定的局限性. 此处暂且搁置.

后记

待后续拆而析之.

REF