この記事でわかること

  • logrotateがいつ・どの設定を読んで動いているか
  • 自作のアプリのログを回す設定の基本形と、copytruncateとcreateの違い
  • postrotateでアプリを起動し直す設定の落とし穴
  • 変更する前にlogrotate -dで確かめる方法と、対象から漏れたログの見つけ方
  • Claude Codeに確認を頼むときの頼み方

結論から書くと、ログを開き直せないアプリはcopytruncateで回し、postrotateでアプリを起動し直す設定は避けます。設定を変えたら、本物の状態ファイルを使ったlogrotate -dで、次に何が起きるかを確かめます。

logrotateが動く仕組み

logrotateは、自分で常に動いているプログラムではありません。このサイトのAlmaLinuxのサーバーでは、/etc/cron.daily/logrotateが1日に1回、/etc/logrotate.confを読んで動きます。/etc/logrotate.confの最後で/etc/logrotate.dの中のファイルを読み込むため、アプリごとの設定は/etc/logrotate.dに置きます。

毎日動いても、weeklyと書いたログは前回から7日たつまで回しません。ログごとの前回の日時は、状態ファイル(既定は/var/lib/logrotate/logrotate.status)に残っています。

【用途】アプリごとの設定の一覧と、前回ローテーションした日時を見る /【実行場所】サーバー /【状態変更】なし(ファイルを読むだけ)

ls -l /etc/logrotate.d/
grep myapp /var/lib/logrotate/logrotate.status

2026年10月18日にこのサイトのサーバーで確かめたとき、logrotateは3.14.0で、状態ファイルにはその日の朝4時36分にローテーションした記録がありました。サーバー全体の作り方はClaude CodeでAlmaLinuxサーバーを構築・運用する方法で紹介しています。

自作のアプリのログを回す設定の基本形

次は、1つのログを週に1回回し、12世代残す設定の例です。この記事の検証では、この例のファイルは作成していません。このサイトのアプリのログも、同じ形の設定で回しています。

【用途】アプリのログを回す設定の例を読む /【実行場所】/etc/logrotate.d/myapp(root権限が要る場所) /【状態変更】なし(例を示すだけ)

/home/your-user/apps/myapp/logs/app.log {
    su your-user your-user
    weekly
    rotate 12
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}
  • su: ログのある場所を一般のユーザーが持っているときは、そのユーザーとグループで回します
  • rotate 12: 12世代を超えた古いログを消します
  • compress・delaycompress: 古いログをgzipで圧縮します。直前の1世代だけは、次の回まで圧縮を待ちます
  • missingok・notifempty: ログが無くてもエラーにせず、空のログは回しません

このサイトのサーバーでは、/etc/logrotate.confにdateextがあるため、回したログはapp.log-20261018のように日付付きの名前になり、1週前のものが.gzになっていました。

copytruncateとcreateの違いと判断のポイント

ログを回す方法は2つあります。アプリがログのファイルを開いたまま書き続けるかどうかで選びます。表では、copytruncateを「空にする」、createを「作り直す」と書きます。

点 空にする 作り直す
元のファイル 残して空に 名前を変える
アプリ そのまま 開き直す
欠ける行 少しある なし
向く場面 開き直せない 開き直せる

logrotate(8)の説明では、copytruncateはコピーを作ってから元のファイルを空にする方法で、ログを閉じさせられないアプリに使えます。そのかわり、コピーしてから空にするまでのわずかな間に書かれた行が欠けることがあります。createは、名前を変えた直後に同じ名前の新しいファイルを作ります。アプリが古いファイルに書き続けないよう、開き直させる合図が要ります。

postrotateでアプリを起動し直す落とし穴

postrotateとendscriptの間に書いた処理は、ログを回した後に/bin/shで実行されます。ここでアプリを止めて起動し直す処理を書くと、ログを回すたびにアプリが起動し直します。dailyと組み合わせれば、毎日です。

同じサーバーで以前動かしていた管理画面のアプリは、この形でした。設定はdailyで、postrotateに停止と起動のスクリプトを書いていたため、毎朝ログを回すたびに起動し直していました。2026年10月3日にこのアプリを止める作業の前に確かめたとき、動いていたプロセスは、その日の朝4時30分にpostrotateで起動し直されたものでした。

このアプリを止めるときに、この設定も外しました。今のこのサイトの設定は、postrotateを使わず、copytruncateで回しています。

起動し直さずに済ませる方法は、次のどちらかです。

  • アプリにログを開き直させる合図を送る(Gunicornでは、USR1でログのファイルを開き直します)
  • 開き直させる方法がなければ、copytruncateで回す

アプリの起動の方法そのものはアプリを常駐させる方法|systemdとcron @rebootの比較で比べています。

logrotate -dで事前に確かめる

logrotate -dは、どのログをどう扱うかを表示するだけの動きです。logrotate(8)の説明では、-dではログも状態ファイルも変えません。一般のユーザーでも、設定と状態ファイルを読めれば実行できます。このサイトのサーバーでは、sudoなしで動きました。

【用途】設定を読ませ、次に何が起きるかを表示させる /【実行場所】サーバー /【状態変更】なし(表示するだけ。ログも状態ファイルも変えない)

logrotate -d /etc/logrotate.d/myapp

結果の見方:

  • 「log does not need rotating」の後の理由で、回さない理由が分かります(1週間たっていない・ログが空、など)
  • 最後にエラーの行が無ければ、設定の書き方は通っています

ここで1つ落とし穴があります。-sで空の状態ファイルを指定すると、logrotateはどのログも今ローテーションしたばかりとみなし、「回す必要はない」とだけ表示します。このサイトのサーバーで空の状態ファイルを指定して試したときも、すべてのログが「already rotated」でした。次に何が起きるかを見るには、-sを付けずに、本物の状態ファイルを読ませます。状態ファイルが変わっていないことは、実行の前後でSHA-256が同じことで確かめました。

設定を追加・変更する手順

設定のファイルを置く・書き換えるのは、root権限の作業です。変える前に控えを取り、変えた後にlogrotate -dで確かめ、問題があれば控えを戻します。

/etc/logrotate.confのincludeは、/etc/logrotate.dの中のファイルをほぼすべて読み込みます。控えを同じ場所に置くと、同じログを2回指定したことになるため、控えは別の場所に置きます。

【用途】変える前に、今の設定の控えを取る /【実行場所】サーバー(sudoの使える人) /【状態変更】あり(/etc/logrotate.dの外に控えを1つ作る)

sudo cp -p /etc/logrotate.d/myapp /home/your-user/myapp.logrotate.before

cpの-pは、元のファイルの権限・所有者・日時をそのまま写します。戻すときも同じ形で写せます。

設定を書き換えたら、上のlogrotate -dで確かめます。エラーが出たときや、思った扱いにならないときは、控えを戻します。

【用途】問題があったときに、控えを戻す /【実行場所】サーバー(sudoの使える人) /【状態変更】あり(設定のファイルを控えで上書きする)

sudo cp -p /home/your-user/myapp.logrotate.before /etc/logrotate.d/myapp

すぐに回して試したくなったときの-fは、実際にローテーションします。確かめるだけのときは-dにします。

対象から漏れたログを見つける

設定を入れた後に、新しい処理とそのログを足すことがあります。設定は自動では増えないので、ログを足したら設定も見直します。

このサイトでは、2026年10月18日に確かめたとき、設定を入れた翌日から足した処理の日付付きのログ(1日に1つ、約0.5KB)が、どの設定の対象にも入っていませんでした。量が小さいので急ぎではありませんが、直すかどうかは記録して、root権限の作業として決めることにしています。

【用途】ログの一覧と、設定の対象のパスを並べて見比べる /【実行場所】サーバー /【状態変更】なし(ファイルを読むだけ)

ls -l /home/your-user/apps/myapp/logs/
grep '^/' /etc/logrotate.d/myapp

一覧にあって設定に無いログが、回されずに増え続けるログです。ログが増えて困ったときの切り分けはサーバー障害の切り分けをClaude Codeと進める方法にまとめています。

Claude Codeに確認を頼む

今の設定とログの一覧を読ませて、問題点を出させるところまでは、Claude Codeに頼めます。設定のファイルを置く・書き換えるのはroot権限の作業なので、案を読んでから自分で決めます。

【用途】logrotateの設定を確かめさせる /【実行場所】Claude Codeに頼む文 /【状態変更】なし(結果と案を受け取るだけ)

myapp のログの logrotate の設定を確かめたいです。
- /etc/logrotate.d/myapp と、logs フォルダのファイルの一覧を読んでください
- logrotate -d を、-s を付けずに実行し、次に何が起きるかを説明してください
- 設定の対象から漏れているログ、postrotate でアプリを起動し直している所があれば教えてください
- 設定のファイルを書き換える・logrotate -f を実行するなどの変更は行わないでください
結果と直す案を示したところで止まり、私の返事を待ってください。

つまずきやすいところ

  • postrotateでアプリを起動し直している: dailyと組み合わせると、毎日の再起動になります
  • createなのに、アプリが古いファイルに書き続けている: アプリがログを開き直していません。合図を送るか、copytruncateにします
  • 空の状態ファイルでlogrotate -dを試した: どのログも「回す必要はない」と表示され、確かめたことになりません
  • 控えを/etc/logrotate.dに置いた: 控えも設定として読み込まれ、同じログを2回指定したことになります
  • ログを足したのに設定を見直していない: そのログは回されずに増え続けます

まとめ

  • logrotateは1日に1回動き、状態ファイルの前回の日時と設定を比べて、回すかを決めます
  • ログを開き直せないアプリはcopytruncate、開き直させる合図があるアプリはcreateで回します
  • postrotateでアプリを起動し直す設定は、ログを回すたびの再起動になります
  • 設定を変えたら、控えを取り、-sを付けないlogrotate -dで次に何が起きるかを確かめます
  • ログを足したら、logrotateの設定の対象に入っているかも確かめます