Webサーバーやアプリケーションサーバーは、稼働しているあいだログファイルを書き続けます。放置すればファイルは際限なく大きくなり、ディスクの空き容量が尽きると、プロセスがログを書けなくなって異常停止したり、新規プロセスを起動できなくなったりします。Linux では logrotate を使うことで、ローテーションの周期・保持世代数・圧縮といった設定をファイルに書いて自動管理できます。この記事では、設定ファイルの書き方から動作確認、よくあるつまずきまでをまとめます。
ログを放置するとディスクはどうなるか
稼働率の高いサーバーでは、1日に数百MBのアクセスログが積み上がることがあります。パーティションの使用率が100%に達すると、次のような影響が出ます。
- アプリケーションがログを書き込もうとして I/O エラーで停止する
- tmpfs 上に作業ファイルを作れず、パッケージ更新や新規インストールが失敗する
- syslog・journald が新しいメッセージを記録できなくなり、障害調査が困難になる
次のコマンドでディスク使用率と、サイズが大きくなっているログファイルをそれぞれ確認できます。
df -h /var/log
du -sh /var/log/* 2>/dev/null | sort -rh | head
logrotate の仕組みを押さえる
logrotate は多くのディストリビューションにあらかじめ含まれているログローテーションツールです。設定ファイルに書いたルールに従い、指定したログファイルを別ファイルへ退避・圧縮・削除します。
実行タイミングは /etc/cron.daily/logrotate(cron 環境)または logrotate.timer(systemd 環境)によって1日1回制御されています。設定ファイルは次の2か所に置きます。
- /etc/logrotate.conf:全ログ共通のデフォルト設定です。ここに書いた値が個別設定の基点になります。
- /etc/logrotate.d/ ディレクトリ:アプリケーションごとの個別設定です。nginx・rsyslog・apache2 など多くのパッケージがインストール時に自動追加します。
logrotate は起動時に /etc/logrotate.d/ 以下のファイルをすべて読み込み、/etc/logrotate.conf と合わせて処理します。独自アプリや任意のパスへのログには、/etc/logrotate.d/ 以下にファイルを追加することで対応できます。
設定ファイルを書く
以下は、カスタムアプリのログを週次でローテーションする想定例です。/etc/logrotate.d/myapp というファイル名で保存します。
/var/log/myapp/app.log {
weekly
rotate 8
compress
delaycompress
missingok
notifempty
create 0640 myapp myapp
sharedscripts
postrotate
systemctl kill --signal=HUP myapp.service
endscript
}
各ディレクティブの意味は次のとおりです。
weekly:週1回ローテーションします(daily・monthlyなども指定できます)。rotate 8:8世代分を保持し、それより古いものは削除します。compress:古いログを gzip で圧縮します。delaycompress:直近1世代はまだ圧縮しません。プロセスが前のファイルを参照している可能性を考慮しています。missingok:対象ファイルが存在しなくてもエラーにしません。notifempty:ファイルが空のときはローテーションをスキップします。create 0640 myapp myapp:ローテーション後に指定した権限・所有者で空のファイルを新規作成します。sharedscripts:複数ファイルをまとめてローテーションするとき、postrotate スクリプトを1度だけ実行します。postrotate~endscript:ローテーション後に実行するコマンドを書きます。上の例では HUP シグナルを送ってプロセスにログファイルの再オープンを促しています。
設定をテストしてローテーションを確認する
設定ファイルを作成したら、まずドライランで内容を確認します。-d オプションをつけると実際にはファイルを変更せず、処理内容だけを標準出力に表示します。
sudo logrotate -d /etc/logrotate.d/myapp
出力に「error」がなく、対象ファイルと処理内容が表示されれば設定は正しく読み込まれています。エラーが出た場合は、ファイルパスの誤りや構文の間違いを見直してください。
問題がなければ、次のコマンドで強制的にローテーションを実行できます。
sudo logrotate -f /etc/logrotate.d/myapp
ローテーション後は次のコマンドでファイルの状態を確認できます。
ls -lh /var/log/myapp/
app.log.1(直前の世代、delaycompress のため未圧縮)や app.log.2.gz(2世代前、圧縮済み)のようなファイルが作成されていれば、ローテーションが機能しています。
よくあるつまずきと対処
圧縮ファイルがなかなか現れない
compress と delaycompress を同時に指定している場合、直近の1世代は圧縮されません。これは仕様で、次のローテーション後に初めて .gz ファイルが作成されます。早めに圧縮したい場合は delaycompress を外すことを検討してください。ただし、プロセスによっては前回のログファイルへの書き込みが残っているケースがあるため、外す場合はサービスの動作を確認した上で判断してください。
postrotate スクリプトが複数回実行される
1つのブロックに複数のログファイルを列挙している場合、sharedscripts を省略すると postrotate スクリプトがファイルごとに繰り返し実行されます。サービスへのシグナルを何度も送ると意図しない動作につながる可能性があるため、原則として sharedscripts を記述しておくことが一般的です。
create ディレクティブで権限エラーが出る
create ディレクティブに指定したユーザー・グループが存在しない場合はエラーになります。id <ユーザー名> で存在を確認してください。また、ログファイルの親ディレクトリへの書き込み権限がない場合も同様のエラーが発生します。ls -ld /var/log/myapp でディレクトリの権限と所有者を確認できます。
systemd ジャーナルは logrotate の対象外
/var/log/journal/ 以下に保存されるバイナリ形式のジャーナルは、logrotate では管理できません。ジャーナルのサイズ上限は /etc/systemd/journald.conf の SystemMaxUse= で設定するか、次のコマンドで即時削減できます。
sudo journalctl --vacuum-size=500M
ジャーナルの現在のディスク使用量は journalctl --disk-usage で確認できます。logrotate とジャーナルの両方を定期的に見直すことで、/var パーティションの枯渇を防ぎやすくなります。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
