logrotate後にアプリがログを書かなくなる原因と確認手順
このページの目的
アプリが旧ログを開いたままなのか、新しいログを開けないのか、再オープン処理が失敗したのかを分けます。最終的なゴールは、アプリが現在どのinodeへ書いているかを確認し、安全な再オープン方法を決めることです。
最初にやること
最初に lsof と ls -li でアプリの書込み先を確認します。次に新しいログの所有者・権限、postrotateの実行結果を確認します。
このページの対象:このページは「ローテーション処理は行われたが、その後の書込み先がおかしい」場合が対象です。ログファイルがそもそも切り替わらない場合は、logrotateされないガイドを先に確認してください。
logrotate設定を実行前に確認
設定を貼り付けて、create、copytruncate、postrotate、保存世代、圧縮などの注意点を確認できます。
最初に現在の書込み先を確認する
見た目だけで判断せず、inodeと開いているファイルを確認します。
- 旧ログや削除済みファイルへ書いている:再オープン通知の失敗を確認
- 新しいログを開こうとして失敗:
create、所有者、権限、SELinuxを確認 - 新しいログは開いているが出力がない:アプリ側のログレベルや出力条件も確認
ls -li /var/log/example/app.log*
sudo lsof -p $(pidof example) | grep -F /var/log/example
よくある表示・症状から原因を絞る
表示された文言は原因そのものではなく、確認範囲を絞る手掛かりです。「考えられる原因」と「最初の確認方法」を対応させて確認します。
| エラー・症状 | 考えられる原因 | 最初の確認方法 |
|---|---|---|
Permission denied / failed to open log file | create後の所有者・グループ・モードがアプリの実行ユーザーと合っていない | ls -l で新規ログを確認し、アプリの実行ユーザーと照合 |
Unable to reopen log file | reload・HUP処理の失敗、またはアプリが参照するログパスの不一致 | postrotateの実行結果とアプリログを確認 |
No such file or directory | 新規ログが作成されていない、親ディレクトリがない、または設定パスが違う | create設定、対象ディレクトリ、アプリのログパスを照合 |
error running shared postrotate script | postrotate内のreload・HUPコマンドが非0で終了した | 同じコマンドを手動実行しjournalと終了コードを確認 |
新しいログが0バイト | アプリがローテーション前のファイル記述子を保持している | lsof +L1 と lsof 対象ログ で書込み先を確認 |
ローテーション済みの .1 へ書き続ける | アプリがログファイルを再オープンしていない | アプリのreload・HUP対応とpostrotateを確認 |
アプリ再起動後だけ復旧する | 再オープン通知が機能していない、または新規ログの権限設計が不適切 | postrotateの実行結果とcreate設定を確認 |
原因を切り分ける確認手順
新旧ログと書込み先を確認する
ls -li /var/log/example/app.log* sudo lsof -p $(pidof example) | grep -F '/var/log/example'inode番号とアプリが開いているファイルを比較します。
新しいログの所有者と権限を確認する
stat /var/log/example/app.log namei -l /var/log/example/app.logcreateで生成されたモード・所有者・グループが、アプリの実行ユーザーと整合するか確認します。postrotateの実行結果を確認する
sudo logrotate -v -s /tmp/logrotate-test.status /etc/logrotate.d/example systemctl status example.service --no-pager journalctl -u example.service --since '-10 min' --no-pagerreloadやHUPの対象PID・サービス名・権限が正しいか確認します。
アプリの再オープン方式を確認する
systemctl reload example.service sleep 1 sudo lsof -p $(pidof example) | grep -F '/var/log/example'対象アプリがreloadやシグナルでログを開き直す仕様か、公式ドキュメントや現在のUnitで確認します。
copytruncateへの変更要否を判断する
再オープン機能がない場合の代替ですが、コピーと切詰めの間に書かれたログが欠損する可能性があります。無条件に切り替えないでください。
確認結果から次の対応を決める
| 確認結果 | 主な対応 |
|---|---|
| 旧ローテーション済みファイルを開いている | 正しいreload・HUPでログを再オープンさせます。 |
| 新規ログの所有者が違う | createまたはsuを修正します。 |
| postrotateが失敗 | サービス名、PID取得、実行権限、コマンドの終了コードを確認します。 |
| 再オープン機能がない | アプリ仕様を確認し、copytruncateやアプリ側ローテーションを比較します。 |
この症状で多い原因
- postrotateのサービス名・PIDファイルが古い
- reloadがログ再オープンを行わない
createの所有者・グループ・モードが不適切- アプリが旧inodeを開いたまま書き続ける
- SELinuxや親ディレクトリ権限で新規ログを開けない
- copytruncateとrename方式の特性を取り違えている
再発防止
- アプリの推奨ローテーション方式を確認する
- 検証用状態ファイルでローテーションと再オープンを試す
- 新規ログの所有者・権限を監視する
- postrotateの失敗をログや監視で検知する
- ログ欠損が許されない場合はcopytruncateのリスクを明記する
copytruncateとpostrotateの違いでは、選択基準とリスクを詳しく比較しています。