Spring BootでログをJSONにしつつログにGitコミットハッシュを出力する
Spring Boot 3.4から、logback-logstash-encoderを使わずともログをJSON形式にできるようになったため、全面改訂しました。
実運用ではログに含めたい項目が多くあります。ログをJSON形式にすると、"項目名":"値"
の形式で出力されるため、ログが読みやすくなる他、機械的な処理がやりやすくなります。
AWSのCloudWatch Logsの場合、JSONのログは自動で改行やインデントを付けてくれますので、非常に読みやすいです。
ローカルではちょっと読みにくいですがw もしローカルではJSONでないログ、本番環境ではJSON形式のログを出力したい場合は、プロファイル(解説記事はこちら)を使って切り替えればいいでしょう。
環境
- Spring Boot 3.4
- JDK 21
- git-commit-id-maven-plugin
やりたいこと
本番環境のアプリがどのバージョンなのかを知るために、全ログにGitコミットハッシュを追加したいです。
{
"@timestamp":"2024-09-23T16:07:51.484848+09:00",
"@version":"1",
"message":"アクセスがありました。",
"logger_name":"com.example.HelloController",
"thread_name":"http-exec-01",
"level":"INFO",
"level_value":20000,
"git_hash":"1a2b3c4" <-- コレ!
}
ログでコミットハッシュを確認したら、IntelliJでそのバージョンをソースコードを簡単に見ることができます。
pom.xml
git-commit-id-maven-pluginを追加します。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>hello</artifactId>
<version>1.0.0</version>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- コレ! -->
<plugin>
<groupId>io.github.git-commit-id</groupId>
<artifactId>git-commit-id-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
git-commit-id-maven-pluginの効果
これを追加すると、ビルド時(Mavenだとmvn clean package
)にクラスパス直下(Mavenだとtarget/classes直下)にgit.propertiesというファイルが作られます。
このファイルには、その時点でのコミットハッシュなど、Gitに関する様々な情報が含まれています。今回は、その中のgit.commit.id.abbrev
を利用します。これはGitコミットハッシュ(短縮版)を表します。
#Generated by Git-Commit-Id-Plugin
...
git.commit.id.abbrev=1a2b3c4
...
ダミーのgit.propertiesの作成
git.propertiesはMavenでのビルド時に作成されますので、IDEでアプリケーションを実行する場合は作成されません。そうなるとgit.propertiesを見つけられずに起動時例外になってしまいます。
これを避けるために、src/main/resources直下にダミーのgit.propertiesを作成してきます。IDEでの実行ではこれが使われます。Mavenでビルドした場合は、git-commit-id-maven-pluginがダミーのgit.propertiesを上書きします。
# このファイルはビルド時に上書きされます
git.commit.id.abbrev=dummy
application.propertiesの設定
application.propertiesでは、git.propertiesを読み込むように設定します。これにより、git.propertiesの内容をapplication.propertiesから参照できるようになります。
併せて、標準出力とファイルへのログ出力をlogstash-logback-encoder形式にし、全ログにgit_hash属性を追加します。これにより、全てのログに"git_hash":"1a2b3c4"
のような形式でGitコミットハッシュが追加されます。
# git.propertiesを読み込む
spring.config.import=classpath:git.properties
# 標準出力へのログ出力をlogstach-logback-encoder形式にする
logging.structured.format.console=logstash
# ファイルへのログ出力をlogstach-logback-encoder形式にする
logging.structured.format.file=logstash
# 全ログにgit_hash属性を追加し、値としてgit.propertiesのgit.commit.id.abbrevを設定する
logging.structured.json.add.git_hash=${git.commit.id.abbrev}
参考資料
- Spring Boot公式リファレンス
Discussion