💨

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でそのバージョンをソースコードを簡単に見ることができます。

https://zenn.dev/masatoshi_tada/articles/ea4462b48b44b5

pom.xml

git-commit-id-maven-pluginを追加します。

pom.xml
<?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コミットハッシュ(短縮版)を表します。

git.properties
#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.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コミットハッシュが追加されます。

application.properties
# 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}

参考資料

Discussion