Keycloak (Quarkus版) でアクセスログを出力し、任意の名前でローテートする
概要
Quarkus版のKeycloak (バージョン17からのデフォルト) にて、ログローテーションしながらアクセスログを出す方法を記載する。 本エントリでは、logrotateなどの外部プログラムを使用せず、Keycloakの設定のみで行う方法を扱う。
このエントリの結論としては、以下のことができた (できなかった)。
- アクセスログを任意のファイル名で出力する。
- ログファイルの日次ローテートを行い、任意のサフィックスを付けたファイル名で保存する。
- ローテートしたファイルについて、任意の世代数だけ保持する (古いものを削除する) ことはできなかった。
動機
Quarkus版のKeycloak (バージョン17からのデフォルト) にて、アクセスログを任意のログファイルに出力したい。 さらに、そのログファイルを日次でローテーションしたい、となったときに設定方法を探したところ、なかなか設定方法にたどり着かなかったため、書き残すことにした。
実行環境・前提条件
目次
アクセスログ周りの動作
以前のWildFly版Keycloakと同様に、ログの設定はアプリケーションサーバー側 (Quarkus) で設定することになる。
KeycloakはベースとなるQuarkusの機能を使ってログをファイルに出力するようになっている。 そのため、Quarkusでアプリケーションを構築するときと同様に、JBoss Loggingの設定を行うことになる。
蛇足だが、QuarkusはHTTPサーバーとしてundertowを使用しているのだと思っていたら、Vert.xというライブラリを使用するようになっているそうだ。アクセスログを出力しているのはHTTPサーバーの機能を持っている部分であり、そこに対しての設定を行うため少し触れた。
シンプルにアクセスログを出力しようとする場合は、以下の参考サイトで説明している、
下記の設定を行うことで、Keycloakの最上位のディレクトリで、quarkus.logという名称のファイルにアクセスログが出力される。
quarkus.http.access-log.enabled=true quarkus.http.access-log.log-to-file=true
これらのデフォルト値や設定できる項目は、以下の公式ドキュメントにて確認できる。アクセスログのファイル名は公式ドキュメントでも触れられており、簡単に指定できる。
アクセスログを出力したファイルのローテートを行う場合は、quarkus.http.access-log.rotate
をtrue
にすると良さそうだが、ローテートの細かい設定はできないようだ。
quarkus.http.access-log.rotate
をtrue
にすると、日次でローテートされ、以下のような名称のファイルが作られる (accessや.logは設定で変更可能)。また、調査をしていないが、公式ドキュメントには保持するログファイルの世代数が設定できるかは明記されておらず、できるかどうかが不明だった。
access2024-01-26.log
これだと以下のようなお決まりのことをやりたい場合は機能が足りない。
- 日次でローテートする。
- 保持する世代数を指定する (ある世代数を超える場合は古いファイルを削除する)。
- ログファイルのファイルサイズが一定を超えたらローテートする。
これらを設定するためには以下で説明があるロギングの機能と組み合わせが必要になる。次は具体的な設定方法を記載する。
設定方法
設定箇所 (設定ファイル等)
Quarkusの設定を行うため、以下のファイルに対して設定値を指定する。 ビルドして設定値を反映する以外にも、システムプロパティ(-Dオプション)などを指定することもできるようだ。
lib\quarkus\build-system.properties
設定後は以下のようにビルドを実施し、Keycloakを起動する。
bin\kc.bat build bin\kc.bat start
設定値
具体的な設定値は以下。
quarkus.http.access-log.enabled=true quarkus.http.access-log.log-to-file=false quarkus.http.access-log.rotate=false quarkus.log.category."io.quarkus.http.access-log".level=INFO quarkus.log.category."io.quarkus.http.access-log".use-parent-handlers=false quarkus.log.category."io.quarkus.http.access-log".handlers=access-log-handler quarkus.log.handler.file.access-log-handler.enable=true quarkus.log.handler.file.access-log-handler.path=logs/access.log quarkus.log.handler.file.access-log-handler.format=%s%n quarkus.log.handler.file.access-log-handler.rotation.file-suffix=.yyyy-MM-dd quarkus.log.handler.file.access-log-handler.rotation.rotate-on-boot=false
設定値の解説
アクセスログの設定
まず、一番のポイントはquarkus.http.access-log.log-to-file
にfalse
を指定するところ。
冒頭のシンプルにアクセスログを出そうとした場合はtrue
を指定していたが、この設定を行うとアクセスログ独自のファイル出力処理が動作し、そのあとで設定しているハンドラなどが動作に反映されなかった。
この部分は公式ドキュメントには書いてなく、Quarkusのソースコードを読んでみて分かった。以下の箇所の近辺で分岐している。ここは少し不親切だと思う。
また、HTTPサーバー機能側でのローテートは不要なのでquarkus.http.access-log.rotate
はfalse
にする。
カテゴリとハンドラの関連付け
次に以下のようにしてカテゴリとハンドラを関連付ける。ここでのポイントは、カテゴリにio.quarkus.http.access-log
を指定するところ。アクセスログ側のquarkus.http.access-log.category
の値と合わせる必要がある。
quarkus.log.category."io.quarkus.http.access-log".level=INFO quarkus.log.category."io.quarkus.http.access-log".use-parent-handlers=false quarkus.log.category."io.quarkus.http.access-log".handlers=access-log-handler
ちなみに公式ドキュメントのquarkus.http.access-log.category
の説明に、base-file-name
に何も設定されていない場合は標準ログメカニズムが使用されるとある。最初にそこを読んでbase-file-name
に何も設定しないよう試行錯誤したのだが、base-file-name
は空にできないというエラーが発生し、結局Keycloakを起動できなかった。
ハンドラの定義
最後に以下のようにハンドラを定義する。
quarkus.log.handler.file.access-log-handler.enable=true quarkus.log.handler.file.access-log-handler.path=logs/access.log quarkus.log.handler.file.access-log-handler.format=%s%n quarkus.log.handler.file.access-log-handler.rotation.file-suffix=.yyyy-MM-dd quarkus.log.handler.file.access-log-handler.rotation.rotate-on-boot=false
カテゴリとの関連付けで指定したハンドラaccess-log-handler
に対して設定を行う。
ここで説明しておくのはquarkus.log.handler.file.access-log-handler.format
だが、既にアクセスログとしてフォーマットされているため、ここでは%sだけを指定している。何も設定しないと日付が2重で付与されたりする。なお、アクセスログ側の設定でフォーマットを制御できるため、ここでは特に指定しないのが良いと思う。
また、quarkus.log.handler.file.access-log-handler.rotation.file-suffix
にて任意のサフィックスを指定することができる。
所感
ログに限らず全般的な設定だが、WildFlyの頃のXML形式での設定に比べれば分かりやすいと感じた。
そういえば、YAML形式などで書けるのだろうか。