Tomcatのcatalina.outをログローテートして肥大化しないようにする
Linux環境でYellowfinを運用していると、catalina.outのサイズが数GBにまで膨れ上がってしまっていることがあるかと思います。catalina.outはローテートされない仕様なので、長期間Yellowfinを運用しているとその分のログが蓄積され続けてしまいます。長期間運用していなくても、初期の構築段階で作成するコンテンツが多かったり利用頻度が高かったりすると、その分出力されるログも多くなりますので、油断は禁物です。
今回は、RHEL系のディストリビューションであるRocky Linux 9.4でlogrotateを使用してcatalina.outのローテーションを設定してみたいと思います。
◎製品資料をCheck!Yellowfinについて理解を深めよう↓
目次
Logrotateの準備
まずは、下記のコマンドでlogrotateがインストールされているかを確認しましょう。通常はインストールされているのではないかと思います。
# yum list installed | grep logrotate logrotate.aarch64 3.18.0-8.el9 @anaconda |
もしlogrotateがインストールされていない場合は、下記のコマンドでインストールしてください。
# yum list installed | grep logrotate |
logrotateの設定
Yellowfinが出力するcatalina.out用に、logrotateの設定ファイルを作成します。/etc/loglotate.d/配下に任意の名前のファイルを作成してください。今回は、例としてyellowfinというファイルを作成します。
# cd/etc/logrotate.d/ # vi yellowfin |
logrotateには様々な設定がありますが、とりあえず下記の設定が記述されていれば十分ではないでしょうか。
<Yellowfinインストールディレクトリ>/appserver/logs/catalina.out {
rotate 10 # 10世代までローテーションする hourly # 1時間ごとにローテーションを実施する minsize 10M # ログファイルのサイズが10MB以上になったらローテーションする copytruncate # ログファイルをコピーしたあとで元のログファイルの中身を消す nodateext # ローテーションしたログに日付ではなく数字をつける missingok # ログファイルが存在しない場合でも処理を続ける |
例えば、Yellowfinのインストールディレクトリが「/usr/local/yellowfin/」の場合は、このようになります。
/usr/local/yellowfin/appserver/logs/catalina.out {
rotate 10 hourly minsize 10M copytruncate nodateext missingok } |
各種パラメーター(特に世代数(rotate)やサイズ(minsize))については、どのような設定にするのが良いのか運用と照らし合わせてよく検討するようにしてください。
logrotateを実行してみる
設定ができたら、logrotateの設定が正しくできているかどうかを確認します。
下記のコマンドでlogrotateをデバッグモードで実行(dry-run)してエラーが出ないことを確認します。
# logrotate -d /etc/logrotate.conf |
手動でlogrotateを動かす場合は、オプションの指定は必要ありません。設定したローテーションの条件を満たしていれば、下記のコマンドを実行することでローテーションしたログファイルが作成されます。
# logrotate /etc/logrotate.conf |
強制的にローテートする場合は、-fのオプションを指定しします。-vfを指定すれば詳細情報を確認することもできます。
# logrotate -vf /etc/logrotate.conf |
system-timerの設定
logrotateでログファイルがローテーションできることが確認できたら、logrotateの実行間隔を設定します。logrotateの実行感覚は、logrotate.timerで指定します。下記のコマンドを実行して、logrotate.timerの設定内容を確認してみましょう。
# cd /usr/lib/systemd/system/ # vi logrotate.timer |
おそらく、日ごとに実行する設定になっているのではないかと思います。
[Unit]
Description=Daily rotation of log files
[Timer] OnCalendar=daily #日ごとに起動する
[Install] WantedBy=timers.target |
このままですとlogrotateの設定をhourly(1時間ごと)に設定していても、daily(日ごと)にしか起動してくれないので、1時間ごとにlogrotateを起動するように設定を変更します。
AccuracySecの設定値も変更しておきましょう。AccuracySec=1sと指定すれば、正時(0分0秒)に起動してくれます。正時からずらして起動したい場合は、その間隔を指定するようにしてください。AccuracySec=1mと指定すれば、正時から1分以内に起動してくれます。
[Unit]
Description=Daily rotation of log files
[Timer] OnCalendar=hourly #1時間ごとに起動する
[Install] WantedBy=timers.target |
以上でsystem-timerの設定は完了です。下記のコマンドを実行して、設定ファイルの再読み込みして、loglotate.timerを有効にします。
# systemctl daemon-reload # systemctl enable logrotate.timer |
権限の付与
logrotateがcatalina.outを操作できるように、ディレクトリに読み込み/書き込みの権限を付与します。logrotate.serviceを編集して、[Service]セクションに、ReadWritePathsの指定を追記します。
# vi logrotate.service |
例えば、Yellowfinのインストールディレクトリが「/usr/local/yellowfin/」の場合は、下記を追記します。
ReadWritePaths=/usr/local/yellowfin/appserver/logs/ |
権限が付与できたら、下記のコマンドで設定ファイルを再読み込みします。
# systemctl daemon-reload # systemctl restart logrotate.service |
SELinuxの設定
SELinuxが有効になっているとログローテートに失敗することがあります。私の場合、ローカルのVMで検証する程度にしかLinuxを操作することはないので、普段であれば無効にしてお仕舞いなんですが、今回ばかりはそうもいかないだろうということで、少し調べてみました。
監査ログ(/var/log/audit/audit.log)を確認すると、下記のようなログが出力されていました。
type=AVC msg=audit(1716271200.073:1291): avc: denied { write } for pid=36749 comm=”logrotate” name=”catalina.out” dev=”dm-0″ ino=17404271 scontext=system_u:system_r:logrotate_t:s0 tcontext=unconfined_u:object_r:usr_t:s0 tclass=file permissive=1 |
scontextというのが操作元のコンテキスト、tcontextというのが操作先のコンテキストということで、つまるところ、logrotate_tからusr_tに対して書き込み(write)しようとしたら拒否された、ということのようです。
今回は、下記のコマンドを実行して、ログローテーションのみPermissiveモードで実行できるようにしました。
# semanage permissive -a logrotate_t |
下記のコマンドを実行して、登録できたかどうかを確認します。
# semanage permissive -l |
以下のように表示されれば、登録できています。
組み込み許容形式
mptcpd_t rshim_t
カスタム許容形式
logrotate_t |
動作確認
次の実行タイミングまで待って、catalina.outがログローテートされることを確認してください。下記のコマンドを実行すると、次にログローテートされるタイミングを確認することができます。次の正時が実行タイミングになっているのではないかと思います。
# systemctl list-timers |
実行タイミングを経過したら、Yellowfinのlogsディレクトリを確認してください。
ログローテートされていることを確認することができれば、設定完了です。
お疲れ様でした。
# ls -l catalina.out*
-rw-r—–. 1 root root 31260 5月 21 16:01 catalina.out -rw-r—–. 1 root root 12236642 5月 21 16:00 catalina.out.1 |
トラブルシューティング
ログローテーションがうまくいかない場合、下記のコマンドでステータスを確認してみてください。
# systemctl status logrotate.service |
読み込み専用ファイルシステムですと表示される
読み込み専用ファイルシステムです(Read-only file system)と表示された場合は、logrotate.serviceにReadWritePathsの指定が間違っている可能性が考えられます。logrotate.serviceの設定を確認してください。設定後は設定ファイルの再読み込みをお忘れなく。
許可がありませんと表示される
許可がありません(Permission denied)と表示された場合は、SELinuxのによってアクセス拒否されている可能性が考えられます。下記のコマンドでSELinuxの動作状況を確認してみてください。
# getenforce Enforcing #Enforcingと表示されたらSELinuxは有効になっています |
下記のコマンドで一時的にSELinuxを無効化することも可能です。
# setenforce 0 |
無効化した状態でログローテートが動作すればSELinuxがアクセス拒否していると考えて良いと思います。SELinuxの設定を見直してください。
エラーは表示されないがローテートされていない
catalina.outのサイズを確認してください。今回の設定は1時間ごとにlogrotateを起動して、ログファイルのサイズが10MB以上になっていた場合にローテーションを実施する。という設定です。catalina.outのサイズが10MB未満だとローテーションされません。サイズの指定は、maxsize、minsize、sizeによって動作が変わりますので注意してください。
以上、Tomcatのcatalina.outをログローテートして肥大化しないようにする方法についてでした。
【参考サイト一覧】
Red Hat Enterprise Linux 9でlogrotateを使ってログファイルを1時間ごとにローテーションさせてみた
https://dev.classmethod.jp/articles/rhel9-logrotate-every-hour/
ログローテートソフトウエア logrotate についてまとめ
https://qiita.com/shotets/items/e13e1d1739eaea7b1ff9
logrotateでのmaxsize、minsize、size設定の違い徹底深堀り
https://isleofhoso.com/linux-logrotate-size/
Read-only file systemでログローテートが失敗する
https://www7390uo.sakura.ne.jp/wordpress/archives/1375
SELinuxによるドメインに対する制限を無くす
https://tex2e.github.io/blog/selinux/selinux-permissive-process
◎製品資料をCheck!Yellowfinについて理解を深めよう↓