logrotateのcopytruncateとpostrotateの違い|安全な選び方
ログを書き続けるアプリでは、ローテーション後に新しいログを開かせる方法が重要です。copytruncateとpostrotateは動作もリスクも異なります。
このページで分かること
- copytruncateの動作と欠損リスク
- rename+postrotateの基本
- アプリ別の選び方と確認方法
先に結論
このページの役割: このページは、ログを開き続けるアプリでどちらの方式を選ぶかという判断に特化しています。設定値全体はlogrotate設定ガイドを参照してください。
アプリがHUPやreloadでログを再オープンできるなら、通常はrename・create後にpostrotateで再オープンさせる方法を優先します。再オープンできない場合に限り、copytruncateの短い欠損区間を理解して検討します。
logrotate設定をレビューする
設定を貼り付けて、copytruncate、postrotate、create、su、圧縮設定の注意点を確認できます。
通常のローテーション動作
通常のlogrotateは、現在のログファイルをrenameして退避し、必要に応じてcreateで新しいログファイルを作成します。ただし、アプリが古いファイルディスクリプタを保持したままだと、rename後も退避済みファイルへ書き続けます。
copytruncateの仕組み
copytruncateは現在のログをコピーした後、元ファイルをその場で0バイトへ切り詰めます。アプリは同じファイルを開き続けられるため、ログ再オープン機能がないアプリでも使えます。
/var/log/example/app.log {
daily
rotate 14
compress
copytruncate
}
欠損の可能性: コピー完了からtruncateまでの短い間に書き込まれたログは、コピー先にも元ファイルにも残らない可能性があります。高頻度・重要ログでは影響を評価してください。
copytruncateでは元ファイルを使い続けるため、通常はcreateで新しいファイルを作る処理は意味を持ちません。
postrotateによる再オープン
アプリがシグナルやreload操作でログを再オープンできる場合は、通常のrename後にpostrotateで再オープンを依頼します。
/var/log/example/app.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 appuser appgroup
sharedscripts
postrotate
/bin/systemctl kill -s HUP example.service >/dev/null 2>&1 || true
endscript
}
この例では新しいログを作成し、サービスへHUPを送って新しいファイルを開かせます。実際にHUPへ対応しているかはアプリの公式仕様で確認してください。
違いの比較
| 観点 | copytruncate | rename+postrotate |
|---|---|---|
| アプリの再オープン対応 | 不要 | 必要 |
| 短時間のログ欠損 | 起こり得る | 正しく再オープンできれば避けやすい |
| 新規ファイルの権限 | 元ファイルを継続利用 | createで指定 |
| 失敗ポイント | コピー時間・欠損区間 | シグナル・reload・権限・サービス名 |
| 向くケース | 再オープン機能がないアプリ | 再オープン対応アプリ |
設定例を選ぶ基準
- アプリがログ再オープンに対応しているか公式資料で確認
- 対応しているなら、推奨されるシグナルまたはreloadコマンドを使う
- 新規ログの所有者・グループ・モードを確認
- 対応していない場合のみcopytruncateの欠損リスクを評価
- 高負荷時にテストし、書き込み継続先を確認
適用前の確認
sudo logrotate -d /etc/logrotate.d/example
sudo logrotate -f /etc/logrotate.d/example
ls -l /var/log/example/
lsof /var/log/example/app.log /var/log/example/app.log.1 2>/dev/null
強制実行:
-fは実際にローテーションします。本番では退避、ディスク容量、アプリの再オープン方法を確認してから実行してください。