SpringBootのログ設定でapplication.ymlだけでやろうとして一部うまくいかなかった話


概要

小ネタですが、SpringBootで、YAML形式の設定ファイルでうまくいかなかった話を書きます。

対象読者

  • 同じようなことをして同じ目にあった人
  • 2019年の時点で、SpringBoot 2.2.1などで開発している人

SpringBootにおけるログ設定

背景

SpringBootでは、スムースにアプリケーションを開発できるよう、様々な工夫がなされています。ログの設定においても、Javaの標準的なログインターフェースを上手に使えるような設定が、何もしなくても使えるように)準備されています。

2019年12月で、できることとできないこと

2019年12月時点の話です。この記事を読んだときに改善されていたらすみません。

筆者は、YAML形式でアプリケーションの設定ファイル(application.yml)を書くのが見やすくて好きなのですが、ログの設定に関して、エントリ執筆時点のバージョンではうまくいかない書き方がありました。

SpringBootでは、アプリケーションの設定ファイル(application.yml)に、ログに関する設定を書くことができ、外部のログライブラリのXMLファイルがなくても、ある程度コントロールすることができます。
これを用いると、通常であればlogbackやlog4jのXMLファイルを別に作成し指定しなければいけない内容について、ある程度、書かずに済む範囲があります。

例えば、アプリケーションのログレベルを決めるとき、下図のような書き方ができます。

logging:
  level:
    root: DEBUG

このとき、slf4jを使って出力したログに関する制御ができ、ログレベルがDEBUGのものについて、標準出力に表示されるようになります。

SpringBootでは、ログの出力先について、標準出力以外にも、ログファイルを指定することができます。下図では、「calc.log」というファイル名を指定しています。

logging:
  level:
    root: DEBUG
    org.springframework: DEBUG
  file: "calc.log"

ファイル名が指定できると、次にはファイルに関するあれこれも指定したくなります。

が、こうは書けません。(下図は動かない例。上記に加え、file:の行の後に、ファイルに関する設定を書きたいつもり。が、YAMLのフォーマットとして正しくない)

logging:
  level:
    root: DEBUG
    org.springframework: DEBUG
  file: "calc.log"
    max-size: 1000000
[main] ERROR com.hrkt.commandlinecalculator.CommandlineCalculatorApplication - Failed to load property source from location 'classpath:/application.yml'
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
(中略)

        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: org.yaml.snakeyaml.parser.ParserException: while parsing a block mapping
 in 'reader', line 13, column 3:
      level:
      ^
expected <block end>, but found '<block mapping start>'
 in 'reader', line 17, column 5:
        max-size: 1000000
        ^

        at org.yaml.snakeyaml.parser.ParserImpl$ParseBlockMappingKey.produce(ParserImpl.java:572)


同じようなことを考えた人が、SpringBootのIssueのところでも話をしていますが、現時点ではできない感じです。

仕方がないので、筆者は下記のように、ファイル名のところだけ別の行にして、このエラーを回避することにしました(下図)。

logging.file: "calc.log"
logging:
  level:
    root: DEBUG
    org.springframework: DEBUG
  file:
    max-size: 1000000

おわりに

SpringBootのお便利機能のうちのログ設定部分で、筆者がYAML形式を使ってうまくいかなかった例を紹介しました。

参考までに、SpringBootの起動時のバナー表示などを抑える設定と合わせて入れると、application.ymlは下図のような形になります。

spring:
  main:
    banner-mode: "off"
    log-startup-info: true

# logging. line is separated to 2 blocks because..
# https://github.com/spring-projects/spring-boot/issues/12510:
# https://github.com/spring-projects/spring-boot/issues/12596:

logging.file: "calc.log"
logging:
  level:
    root: DEBUG
    org.springframework: DEBUG
  file: "calc.log"
    max-size: 1000000