Linuxサーバーを運用していると、放置したログファイルがディスクを圧迫して障害につながることがあります。「ネットで調べればすぐ分かる」と思って検索しても、断片的な情報ばかりで結局うまく動かない、そんな経験はないでしょうか。
この記事では、logrotate(ログローテーション)の仕組みから設定ファイルの書き方、手動テスト、トラブル対処まで体系的に解説します。
この記事を読めば、ログ管理の不安を解消し、安定したサーバー運用ができるようになります。
実行環境:RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済み
この記事のポイント
・logrotateはログファイルの分割・圧縮・削除を自動で行うツール
・/etc/logrotate.d/ に設定ファイルを置くだけで独自ログも管理できる
・logrotate -d でドライランし、実際の動作を事前確認できる
・dateextを使うとローテーション後のファイル名に日付が付き管理しやすい
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜlogrotateが必要なのか
Linuxサーバーは稼働している限り、ログファイルを生成し続けます。Webサーバーのアクセスログ、メールサーバーのログ、認証ログなど、放置すれば際限なく肥大化します。ログが肥大化すると、以下の問題が発生します。
・ディスク容量の逼迫:/var/log が100%になるとサービスが停止する
・ログ解析の困難:数GBのファイルをgrepするのは現実的ではない
・バックアップの肥大化:不要な古いログまで毎回バックアップされる
logrotateは、これらの問題を自動的に解決する仕組みです。指定した条件(日数・サイズなど)に従ってログファイルを分割・圧縮・削除してくれます。
ほぼすべてのLinuxディストリビューションに標準でインストールされており、Apache、Nginx、syslogなど主要なサービスのログローテーション設定もパッケージに含まれています。
logrotateの仕組み(cronとの関係)
logrotateは常駐プロセス(デーモン)ではありません。cron(定期実行の仕組み)によって1日1回呼び出されて動作します。具体的な流れは以下のとおりです。
・cronが毎日 /etc/cron.daily/logrotate を実行する
・logrotateが /etc/logrotate.conf を読み込む
・/etc/logrotate.conf の中で /etc/logrotate.d/ 配下の個別設定を読み込む(include)
・各設定ファイルの条件に従ってローテーションを実行する
・実行結果を /var/lib/logrotate/logrotate.status に記録する
RHEL/CentOS 7以降では、cronではなくsystemdタイマー(logrotate.timer)で実行される場合もあります。以下のコマンドで確認できます。
# logrotateがインストールされているか確認する [root@web01 ~]# which logrotate /usr/sbin/logrotate # バージョンを確認する [root@web01 ~]# logrotate --version logrotate 3.21.0 # systemdタイマーの状態を確認 [root@web01 ~]# systemctl status logrotate.timer # 従来のcronで動いているか確認 [root@web01 ~]# ls -la /etc/cron.daily/logrotate -rwx------. 1 root root 130 Apr 1 2026 /etc/cron.daily/logrotate # cronからの呼び出し設定を確認する(RHEL系) [root@web01 ~]# cat /etc/cron.daily/logrotate #!/bin/sh /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
基本的な設定方法
1. 設定ファイルの場所を確認する
logrotateの設定ファイルは2つの場所にあります。・/etc/logrotate.conf:全体のデフォルト設定ファイル
・/etc/logrotate.d/:サービスごとの個別設定ファイルを格納するディレクトリ
まずは /etc/logrotate.conf の中身を確認してみましょう。
[root@web01 ~]# cat /etc/logrotate.conf # ローテーション周期(weekly = 週1回) weekly # 保持する世代数(4世代分を残す) rotate 4 # ローテーション後に新しい空ファイルを作成する create # ローテーション後のファイル名に日付を付ける dateext # 個別設定ファイルを読み込む include /etc/logrotate.d
/etc/logrotate.d/ には、RPMパッケージがインストール時に自動的に設定ファイルを配置します。
[root@web01 ~]# ls /etc/logrotate.d/ btmp chrony dnf firewalld rsyslog syslog wtmp # rsyslogの設定例を確認する [root@web01 ~]# cat /etc/logrotate.d/rsyslog /var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/cron { missingok sharedscripts postrotate /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true endscript }
2. 個別の設定ファイルを作成する
独自のアプリケーションログなど、自分で設定を追加したい場合は /etc/logrotate.d/ に新しいファイルを作成します。以下は、/var/log/myapp/ 配下のログを管理する設定例です。
# /etc/logrotate.d/myapp の設定例 /var/log/myapp/*.log { daily rotate 14 compress delaycompress missingok notifempty create 0640 myapp myapp }
設定のポイントは以下の3つです。
・パスにはワイルドカードが使える:/var/log/myapp/*.log のように指定すれば、ディレクトリ内の全.logファイルが対象になる
・create のパーミッションとオーナーはアプリに合わせる:アプリケーションがログを書き込むユーザー・グループに設定しないと、ローテーション後にログが書けなくなる
・postrotateが必要かどうかを確認する:アプリケーションがログファイルを開き直す仕組みを持っているかで判断する。copytruncateを使う方法もある(後述)
3. 主要なディレクティブを理解する
設定ファイルで使う主要なディレクティブ(設定項目)を解説します。ローテーション間隔
・daily:毎日ローテーション
・weekly:毎週ローテーション
・monthly:毎月ローテーション
・yearly:年1回ローテーションする
アクセスログのように増加が速いログは daily、変化の少ないログは weekly や monthly が適切です。
保持とサイズ
・rotate 数値:保持する世代数。rotate 7 なら7世代分を保持し、それより古いものは削除される
・size サイズ:指定サイズを超えた場合のみローテーション(例:size 100M)
・maxsize サイズ:daily/weeklyと併用し、指定サイズを超えたら間隔を待たずにローテーション
・minsize サイズ:daily/weeklyと併用し、指定サイズ未満ならローテーションしない
圧縮
・compress:ローテーション後のログをgzip圧縮する
・delaycompress:圧縮を1世代遅らせる。直前のログはすぐ参照したいことが多いため、実務ではcompressとセットで使うのが定番
・nocompress:圧縮しない
ファイル生成と権限
・create モード オーナー グループ:ローテーション後に指定した権限で新しい空ファイルを作成する(例:create 0640 root adm)
・nocreate:新しいファイルを作成しない
エラー制御
・missingok:ログファイルが存在しなくてもエラーにしない
・notifempty:ログファイルが空ならローテーションしない
4. dateextでファイル名に日付を付ける
dateextを指定すると、ローテーション後のファイル名に日付が付きます。連番(.1、.2、.3...)より直感的にわかりやすくなります。/var/log/myapp/app.log { daily rotate 30 compress dateext dateformat -%Y%m%d missingok notifempty }
# dateext有効時のファイル名の例 [root@web01 ~]# ls -la /var/log/myapp/ -rw-r----- 1 root root 245760 Apr 11 09:15 app.log -rw-r----- 1 root root 18432 Apr 10 23:59 app.log-20260410.gz -rw-r----- 1 root root 17920 Apr 9 23:59 app.log-20260409.gz -rw-r----- 1 root root 19456 Apr 8 23:59 app.log-20260408.gz
5. 手動でローテーションをテストする
設定ファイルを作成したら、いきなり本番で動かすのではなく、必ずテストしましょう。デバッグモード(-d オプション):実際にはローテーションせず、何が実行されるかを表示します。
# ドライラン(実際にはローテーションしない) [root@web01 ~]# logrotate -d /etc/logrotate.d/myapp reading config file /etc/logrotate.d/myapp Handling 1 logs rotating pattern: /var/log/myapp/*.log after 1 days (30 rotations) empty log files are not rotated, old logs are removed considering log /var/log/myapp/app.log log needs rotating rotating log /var/log/myapp/app.log, log->rotateCount is 30 dateext suffix '-20260411' dest: /var/log/myapp/app.log-20260411 compressing log with: /bin/gzip
強制実行(-f オプション):条件に関係なく即座にローテーションを実行します。
# 特定の設定ファイルを強制実行する [root@web01 ~]# logrotate -f /etc/logrotate.d/myapp # 実行後にローテーションされたか確認する [root@web01 ~]# ls -la /var/log/myapp/ -rw-r----- 1 myapp myapp 0 Apr 11 15:30 app.log -rw-r----- 1 myapp myapp 245760 Apr 11 15:30 app.log-20260411
詳細出力(-v オプション):-f と組み合わせると、実行中の詳細な情報が表示されます。
# 詳細情報を表示しながら強制ローテーション [root@web01 ~]# logrotate -vf /etc/logrotate.d/myapp
6. ステータスファイルでローテーション履歴を確認する
logrotateは最後にローテーションした日時をステータスファイルに記録しています。「本当にローテーションが実行されているのか」を確認するときに使います。# ステータスファイルを確認する [root@web01 ~]# cat /var/lib/logrotate/logrotate.status logrotate state -- version 2 "/var/log/messages" 2026-4-11-3:0:0 "/var/log/secure" 2026-4-11-3:0:0 "/var/log/maillog" 2026-4-11-3:0:0 "/var/log/cron" 2026-4-11-3:0:0 "/var/log/myapp/app.log" 2026-4-11-15:30:0
journalctl -u crond でcronの実行ログを確認してください。
応用・実務Tips
postrotateでサービスを再読み込みする
ログファイルをローテーションした後、サービスに「新しいログファイルに書き込んでくれ」と通知する必要がある場合があります。たとえばApache(httpd)は、起動時にログファイルを開いたまま書き込み続けます。ファイル名が変わっても古いファイルディスクリプタ(ファイルの参照情報)を使い続けるため、postrotateでサービスを再読み込みする必要があります。
# /etc/logrotate.d/httpd の設定例 /var/log/httpd/*log { daily rotate 14 compress delaycompress missingok notifempty sharedscripts postrotate /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true endscript }
sharedscriptsは重要なディレクティブです。ワイルドカードで複数のログファイルがマッチした場合、sharedscriptsがないとファイルごとにpostrotateが実行されてしまいます。sharedscriptsを指定すると、全ファイルのローテーション完了後に1回だけ実行されます。
Nginxの場合は以下のように設定します。
/var/log/nginx/*.log { daily rotate 14 compress delaycompress missingok notifempty create 0640 nginx adm sharedscripts postrotate /usr/bin/systemctl reload nginx >/dev/null 2>&1 || true endscript }
copytruncateを使う場面
postrotateでサービスを再読み込みできない場合や、アプリケーション側にログファイルを開き直す仕組みがない場合は、copytruncateが有効です。# copytruncateを使う設定例 /var/log/myapp/app.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate }
1. 元のログファイルをコピーしてバックアップを作成する
2. 元のログファイルの中身を空にする(truncate)
ファイル名やiノード(ファイルの識別番号)が変わらないため、アプリケーション側の対応は不要です。
ただし、コピーとtruncateの間に書き込まれたログが失われる可能性がゼロではありません。ミッションクリティカルなログには使わず、postrotateでの再読み込みを優先してください。
サイズベースでローテーションする
周期ではなくファイルサイズでローテーションしたい場合は、size ディレクティブを使います。/var/log/myapp/app.log { size 100M rotate 10 compress dateext missingok notifempty copytruncate }
maxageで古いログを日数指定で削除する
rotate は世代数で管理しますが、maxage は日数で管理します。「30日以上前のログは削除する」といった運用に使います。/var/log/myapp/app.log { daily rotate 90 maxage 30 compress dateext missingok notifempty }
ログの保存先を変えてディスクを分離する
ローテーション後のログファイルを別のディレクトリに保存したい場合は、olddir ディレクティブを使います。/var/log/myapp/app.log { daily rotate 30 compress dateext olddir /var/log/myapp/archive createolddir 0750 myapp myapp missingok notifempty }
・createolddir:移動先ディレクトリが存在しない場合に自動作成する(パーミッションとオーナーを指定)
dfコマンドで/var/logのディスク使用率が高い場合、olddirで別パーティションに退避させる運用が有効です。
独自アプリケーションのログをローテーションする
自作のアプリケーションやバッチ処理のログをlogrotateで管理する場合の設定例を紹介します。# /etc/logrotate.d/myapp-batch /var/log/myapp/batch_*.log { weekly rotate 12 compress delaycompress missingok notifempty create 0644 appuser appuser olddir /var/log/myapp/archive dateext dateformat -%Y%m%d }
トラブルシュート・エラー対処
「error: skipping」が出た時の対処法
logrotateを実行した際に以下のようなエラーが出ることがあります。error: skipping "/var/log/myapp/app.log" because parent directory has insecure permissions
対処法1:ディレクトリの権限を修正する
# 親ディレクトリの権限を確認 [root@web01 ~]# ls -ld /var/log/myapp/ # 権限を修正(他ユーザーの書き込みを禁止) [root@web01 ~]# chmod 755 /var/log/myapp/
アプリケーション専用のディレクトリで、あえてroot以外の権限にしている場合は、設定ファイルにsuディレクティブを追加します。
# suディレクティブで実行ユーザーとグループを指定 /var/log/myapp/*.log { su myapp myapp daily rotate 7 compress missingok notifempty }
「error: skipping - log entry is not a file」が表示された場合
指定したパスがファイルではない(ディレクトリやシンボリックリンクの場合など)ときに発生します。[root@web01 ~]# logrotate -d /etc/logrotate.d/myapp error: skipping "/var/log/myapp/app.log" because it is not a regular file. # ファイルの種類を確認する [root@web01 ~]# file /var/log/myapp/app.log /var/log/myapp/app.log: symbolic link to /dev/null # 正しいログファイルのパスを確認して設定を修正する
ローテーション後にアプリケーションがログを書き込めなくなった場合
createディレクティブのパーミッションやオーナーが正しいか確認してください。# ローテーション後のファイルのパーミッションを確認する [root@web01 ~]# ls -la /var/log/myapp/ -rw-r----- 1 root root 0 Apr 11 03:00 app.log -rw-r----- 1 myapp myapp 245760 Apr 11 03:00 app.log-20260411 # create行のオーナーが間違っている場合 # create 0640 root root ← rootで作成されているためmyappユーザーが書き込めない # create 0640 myapp myapp ← 正しい設定
ログがローテーションされない時の確認手順
「設定したのにログがローテーションされない」場合は、以下の手順で原因を切り分けてください。手順1:ステータスファイルを確認する
logrotateは前回の実行日時を /var/lib/logrotate/logrotate.status(ディストリビューションによっては /var/lib/logrotate.status)に記録しています。
# ステータスファイルで前回の実行日時を確認 [root@web01 ~]# cat /var/lib/logrotate/logrotate.status | grep myapp
手順2:デバッグモードで設定を検証する
# 設定ファイルの構文エラーを確認 [root@web01 ~]# logrotate -d /etc/logrotate.d/myapp
手順3:cronまたはsystemdタイマーが動いているか確認する
# 1. cronデーモンが動いているか確認する [root@web01 ~]# systemctl status crond Active: active (running) # 2. /etc/cron.daily/logrotate が存在するか確認する [root@web01 ~]# ls -la /etc/cron.daily/logrotate -rwx------. 1 root root 130 Apr 1 2026 /etc/cron.daily/logrotate # 3. 実行権限があるか確認する(xがないと実行されない) [root@web01 ~]# chmod +x /etc/cron.daily/logrotate # systemdタイマーの場合 [root@web01 ~]# systemctl status logrotate.timer [root@web01 ~]# systemctl list-timers | grep logrotate
logrotate.timerが inactive になっていたり、/etc/cron.daily/logrotate が存在しない場合は、logrotate自体が定期実行されていません。
手順4:ディスク容量を確認する
ディスクが100%の状態では、ローテーション(新しいファイルの作成や圧縮)が失敗します。
# ディスク使用量を確認 [root@web01 ~]# df -h /var/log/
手順5:手動で実行してエラーが出ないか確認する
# 手動で実行してエラーが出ないか確認する [root@web01 ~]# /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
本記事のまとめ
logrotateの設定方法とトラブル対処のポイントを整理します。| やりたいこと | コマンド・設定 |
|---|---|
| デフォルト設定を確認する | cat /etc/logrotate.conf |
| 個別設定ファイルの一覧を確認する | ls /etc/logrotate.d/ |
| 設定をテストする(実行しない) | logrotate -d /etc/logrotate.d/設定名 |
| 強制的にローテーションを実行する | logrotate -f /etc/logrotate.d/設定名 |
| 詳細表示で強制ローテーションする | logrotate -vf /etc/logrotate.d/設定名 |
| 前回の実行日時を確認する | cat /var/lib/logrotate/logrotate.status |
| ファイル名に日付を付ける | dateext + dateformat -%Y%m%d |
| サイズベースでローテーションする | size 100M |
| 古いログを日数指定で削除する | maxage 30 |
| ローテーション後のファイルを別ディレクトリに移動する | olddir /var/log/myapp/archive |
| systemdタイマーの状態を確認する | systemctl status logrotate.timer |
| ローテーション後にサービスを再読み込みする | postrotate ~ endscript で設定 |
| アプリ側の対応なしでローテーションする | copytruncate ディレクティブで設定 |
logrotateは「設定して放置」で動くツールですが、設定ミスに気づかないまま放置すると、ディスク満杯による障害を引き起こします。
新しいアプリケーションを導入したら /etc/logrotate.d/ に設定を追加し、
logrotate -d で動作確認するところまでをセットにしてください。関連するログ管理の記事も参考にしてください。
・crontabコマンドの設定と書き方|動かない時のログ確認まで
・dfコマンドでディスクの空き容量を確認する方法
ログが溢れて深夜に叩き起こされた経験はありませんか?
logrotateの設定を覚えても、「本番サーバーの運用設計をどう組み立てるか」は断片的な情報だけでは身につきません。現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます