症状
nginxのログファイルが肥大化し続け、ディスク容量が圧迫される。または df -h で /var/log が100%近くになっている。
結論:まずこれを確認
ls -lh /var/log/nginx/でログファイルのサイズを確認cat /etc/logrotate.d/nginxでlogrotate設定の存在を確認systemctl status logrotateまたは/var/lib/logrotate/statusで最終実行日時を確認
トラブルシューティングフロー
flowchart TD
A[ディスク容量が逼迫] --> B{nginxログが原因?}
B -->|No| Z[他のログを確認]
B -->|Yes| C{logrotate設定あり?}
C -->|No| D[logrotate設定を作成]
C -->|Yes| E{logrotateは実行されている?}
E -->|No| F[cronまたはtimerを確認]
E -->|Yes| G{ログは圧縮・削除されている?}
G -->|No| H[postrotateを確認]
G -->|Yes| I[rotateの世代数を確認]
H --> J[nginx再読み込みを確認]
よくある原因
- logrotate設定ファイルがない - パッケージインストール時に作成されないケースがある
- postrotateでnginx再読み込みが失敗 - nginxがログファイルを掴み続け、新しいファイルに書き込まれない
- logrotateのcron/timerが無効 - systemdのlogrotate.timerが停止している
- copytruncateとpostrotateの混在 - 設定の矛盾でローテーションが中途半端になる
- 権限の問題 - ローテーション後のファイルにnginxが書き込めない
- sharedscriptsの指定漏れ - 複数ログファイルで毎回postrotateが実行されエラーになる
- ディスクIOが高くローテーション処理がタイムアウト - 大容量ログで処理が完了しない
確認手順
ステップ1: ログファイルのサイズを確認する
ls -lh /var/log/nginx/
du -sh /var/log/nginx/
🔍 チェックポイント: access.logやerror.logが数GB以上ある場合は異常
ステップ2: logrotate設定ファイルを確認する
cat /etc/logrotate.d/nginx
🔍 チェックポイント: ファイルが存在し、以下の要素が含まれているか
- 対象パス(
/var/log/nginx/*.log) rotateの世代数daily/weeklyなどの頻度postrotateセクション
ステップ3: logrotateの最終実行日時を確認する
# Debian/Ubuntu系
cat /var/lib/logrotate/status | grep nginx
# RHEL/CentOS系
cat /var/lib/logrotate/logrotate.status | grep nginx
🔍 チェックポイント: 日付が古い(1日以上前)場合はlogrotate自体が動いていない可能性
ステップ4: logrotateを手動実行してテストする
# ドライラン(実際には実行しない)
logrotate -d /etc/logrotate.d/nginx
# 強制実行(テスト環境のみ)
logrotate -f /etc/logrotate.d/nginx
🔍 チェックポイント: エラーメッセージが出力されないか確認
ステップ5: postrotateの動作を確認する
# nginx設定テスト
nginx -t
# nginx再読み込み(postrotateで実行されるコマンド)
systemctl reload nginx
# または
kill -USR1 $(cat /var/run/nginx.pid)
🔍 チェックポイント: エラーなく完了するか。pidファイルのパスが正しいか
ステップ6: cronまたはsystemd timerを確認する
# systemdの場合
systemctl status logrotate.timer
systemctl list-timers | grep logrotate
# cronの場合
ls -la /etc/cron.daily/logrotate
🔍 チェックポイント: timerがactiveか、cronファイルに実行権限があるか
ステップ7: 緊急対応としてログを削除する
# ディスクが満杯で緊急の場合
# 注意: 削除前にnginxを再読み込みする必要がある
# 古いログを圧縮
gzip /var/log/nginx/access.log.1
# または現在のログを切り詰め(nginx再読み込み不要)
truncate -s 0 /var/log/nginx/access.log
🔍 チェックポイント: df -h で容量が回復したか確認
NG行動(やってはいけないこと)
- ログファイルを直接rm -fで削除する - nginxが削除されたファイルを掴み続け、ディスク容量が解放されない
- nginx停止中に大量のログを削除する - 再起動時にエラーログが書けずnginxが起動しない可能性
- logrotate設定を変更後にテストせずに放置 - 次回のローテーションまで問題に気づかない
- copytruncateを安易に追加する - ログの欠損が発生する可能性がある
よくある質問(FAQ)
Q1: ログローテーション後も古いファイルのディスク容量が解放されない
A: nginxプロセスがファイルを掴み続けている可能性がある。lsof | grep deleted で確認し、該当プロセスを再読み込みまたは再起動する。
Q2: copytruncateとpostrotateのどちらを使うべき?
A: postrotate(デフォルト)を推奨。copytruncateはコピー中のログが欠損する可能性がある。postrotateでnginxに kill -USR1 または systemctl reload を送る方式が一般的。
Q3: ログローテーションの頻度や保持世代数の目安は?
A: トラフィック量による。一般的には daily + rotate 14(2週間保持)+ compress が目安。ディスク容量と調査時に必要なログ期間のバランスで決定する。
関連するエラー・症状
- (関連記事準備中)
- (関連記事準備中)
- (関連記事準備中)
解決しない場合
- nginx公式ドキュメント: https://nginx.org/en/docs/control.html
- logrotate manページ:
man logrotate - 確認すべきログ:
/var/log/syslogまたは/var/log/messages(logrotateのエラー)journalctl -u logrotate(systemd環境)
- 次に調べるキーワード:
nginx log rotation not working,logrotate postrotate failed,lsof deleted files disk space