Linuxで運用中のシステムや自作アプリにおいて、ログファイルが肥大化するとディスク圧迫や解析遅延などの問題が発生します。
本記事では、ログローテート機構であるlogrotateの仕組みと設定方法を整理し、システム標準のログだけでなく、自作アプリケーションのログも安全に管理するための実践的な構成例を紹介します。
logrotateの役割と仕組み
Linuxを運用していると、ログファイルが時間とともに肥大化し、ディスク容量を圧迫したり、解析に時間がかかるといった問題が発生します。特にWebサーバやアプリケーションのログは、アクセス量に比例して増加するため、放置すると深刻なトラブルにつながりかねません。
このようなログの肥大化を自動的に防ぐ仕組みとして利用されているのが「logrotate」です。logrotateは、あらかじめ定義されたルールに基づいてログファイルを定期的にローテート(切り替え・圧縮・削除)することにより、ログのサイズ管理を自動化できます。多くのLinuxディストリビューションでは標準で導入されており、cronなどによって日次で実行されるよう構成されています。
ログローテート処理の基本的な流れ
logrotateは設定ファイルに記述されたルールに従って、対象ログのサイズやタイミングをチェックし、必要に応じてファイル名を変更(例:app.log → app.log.1)したり、圧縮(例:gzip形式)したりします。以下のような処理を自動で行います。
- 既存のログをバックアップ名へリネーム
- 元のログファイルを新規に生成
- バックアップログの世代管理(例:4世代保持)
- 必要に応じて古いログを削除または圧縮
- postrotateに定義された処理を実行(例:サービス再起動)
このようにlogrotateは、システムログだけでなく、自作アプリやサードパーティ製ソフトウェアのログにも柔軟に対応可能な管理機構です。
journalとlogrotateの違い

Linuxには、logrotate以外にも「journalctl(journald)」というログ管理の仕組みが存在します。これはsystemdによって標準的に提供されており、主にsystemdで起動されるサービスやプロセスの標準出力・標準エラー出力を収集・保存する役割を持ちます。
logrotateとjournalctlは役割が重複しているように見えますが、対象と運用方法に明確な違いがあります。使い分けを理解することで、ログ管理の設計がスムーズになります。
journalctlとlogrotateの使い分け
journalctlはバイナリ形式でログを保存し、journalctl コマンドで時系列にログを閲覧できます。一方で、logrotateはプレーンテキストで出力されるファイルを対象としており、任意の場所にあるログファイルを管理できます。
以下のように使い分けるのが一般的です。
ログ管理方式 | 対象 | 保存形式 | 利点 |
---|---|---|---|
journalctl | systemdサービス(標準出力) | バイナリ | プロセス単位で統一管理できる |
logrotate | ファイル出力型ログ全般 | プレーンテキスト | 個別制御・圧縮・削除が容易 |
また、自作アプリケーションの多くはファイル出力型のログ設計を取っているため、logrotateのほうが導入しやすく、設定の自由度も高いという特徴があります。
logrotateの基本設定構成
logrotateは、ログファイルの肥大化を防ぐために、一定条件でファイルをローテート(分割・圧縮・削除)する仕組みです。システム全体の設定とアプリケーションごとの設定は階層的に管理されており、構成の理解が非常に重要になります。
主に2種類の設定ファイルが存在し、それぞれが個別または全体のログ管理に関わっています。設定ファイルはcronによって定期的に読み込まれ、日次処理として自動で実行されます。
設定ファイルの配置場所と読み込み順
logrotateの設定は以下の2階層で構成されます。
- /etc/logrotate.conf(グローバル設定)
- /etc/logrotate.d/(個別アプリケーションの設定)
logrotateはまず /etc/logrotate.conf を読み込み、そこに記述された include ディレクティブによって /etc/logrotate.d/ 配下の各ファイルを順に読み込みます。
以下は、実際のlogrotate.confの冒頭部分の例です。
# see "man logrotate" for details
# rotate log files weekly
weekly
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
dateext
# include all files in logrotate.d
include /etc/logrotate.d
このように、logrotateの設定は階層的に処理され、必要に応じて柔軟に個別制御が可能です。
主なディレクティブと構文の意味
logrotate設定ファイルでは、多くのディレクティブが利用可能ですが、運用でよく使われる基本ディレクティブを以下にまとめます。
ディレクティブ | 説明 |
---|---|
weekly / daily / monthly | ローテートの周期を指定 |
rotate n | 保存するログファイルの世代数 |
compress | ローテート後にgzipで圧縮 |
create mode owner group | 新規ログファイルの権限・所有者を指定 |
missingok | ログファイルが存在しなくてもエラーにしない |
notifempty | ファイルが空ならローテートしない |
postrotate / endscript | ローテート後に実行するスクリプトを指定 |
これらのディレクティブを組み合わせることで、柔軟かつ安全なログ管理を実現できます。
cronによる定期実行とタイミング
logrotateは基本的に cron.daily の仕組みによって、日次で自動実行されます。該当のスクリプトは /etc/cron.daily/logrotate に配置されており、cronの仕組みで毎日呼び出されるよう設定されています。
以下はcron.dailyから実行された際に使用される実行コマンドです。
/usr/sbin/logrotate /etc/logrotate.conf
このコマンドによって /etc/logrotate.conf と logrotate.d/ のすべての設定が適用され、対象ログがローテートされます。もしログのローテートが実行されない場合は、cron自体の動作状況を確認することも重要です。
ログファイルのローテート処理の流れ

logrotateは、設定ファイルで定義されたルールに従って、ログファイルを定期的に処理します。処理は通常、cronの仕組みによって自動で起動され、ログのサイズや日付を基準にローテート対象を判定します。
処理は大きく以下のような流れで進みます。
処理の流れ
- ログファイルの存在チェックと条件判定
- 対象ファイルのリネーム(例:app.log → app.log.1)
- 必要に応じた圧縮処理(例:gzip)
- 古いログの削除(rotate数による管理)
- ログファイルの再作成(空ファイル)
- postrotateスクリプトの実行(アプリ再起動など)
この一連の処理を通じて、ログの容量と世代を自動で管理することが可能になります。
ローテート時の世代番号とファイル名の推移
ログローテートの設定に rotate 6 を指定した場合、ログファイルは最大で6世代まで保持されます。ファイル名の付番規則は以下の通りです。
世代 | ファイル名 | 内容 |
---|---|---|
最新 | app.log | 現在出力中のログ |
1世代前 | app.log.1 | 前回ローテートされたログ |
2世代前 | app.log.2 | 2回前にローテートされたログ |
3世代前 | app.log.3 | 3回前にローテートされたログ |
4世代前 | app.log.4 | 4回前にローテートされたログ |
5世代前 | app.log.5 | 5回前にローテートされたログ(次回削除対象) |
次回のローテート処理が行われると、以下のようにファイルが順番に繰り上がり、最も古い世代(app.log.5)は削除されます。
app.log.5 → 削除
app.log.4 → app.log.5
app.log.3 → app.log.4
app.log.2 → app.log.3
app.log.1 → app.log.2
app.log → app.log.1
(新しい app.log が生成される)
このように、ローテートされたログは番号が付与され、設定された世代数を超えると古いログから順に削除されます。常に .1 が最新の過去ログとなり、番号が大きいほど古い世代を意味します。
ローテート対象ファイルの判定方法
ローテートの対象となるかどうかは、主にサイズ・更新日・世代保持数といった設定に基づいて判断されます。これらはlogrotate設定ファイルで柔軟に定義できます。
例えば以下のような設定は、毎週ローテートし、最大4世代を保持し、圧縮も行う定義です。
/var/log/myapp/app.log {
weekly
rotate 4
compress
missingok
notifempty
}
このように、ローテートの頻度や方法は各ログファイルごとに個別に制御可能です。
postrotateスクリプトの活用
logrotateは、ログのローテート後に任意のスクリプトを実行することができます。この機能を活用すると、例えばWebサーバやアプリケーションに対して「ログファイルの再オープン」を指示することが可能です。
以下は、Apacheのログローテート後にプロセスへシグナルを送る例です。
/var/log/httpd/access_log {
weekly
rotate 5
compress
postrotate
/bin/kill -HUP $(cat /var/run/httpd.pid)
endscript
}
このpostrotateブロックの中に記述されたコマンドは、ローテート処理の直後に実行されるため、ログファイルを出力し続けるプロセスとの連携に非常に有効です。
権限や所有者によるトラブル防止設計
ログファイルのローテートにおいて最も多いトラブルのひとつが、ファイルの所有者や権限の変更による書き込みエラーです。logrotateはrootユーザーで実行されることが多いため、ローテート後の新規ファイルに対して、アプリケーションが書き込みできない事態が発生します。
このようなトラブルを防ぐためには、createディレクティブで明示的にパーミッションと所有者を指定しておく必要があります。
/var/log/myapp/app.log {
weekly
rotate 3
compress
create 644 myuser mygroup
}
この例では、ローテート後に新規に作成されるログファイルに対して、myuser:mygroupという所有者を設定し、パーミッション644で作成されます。これにより、アプリケーションがエラーなくログ出力を継続できます。
自作アプリのログをローテート対象に含める方法
logrotateはシステムログだけでなく、自作アプリケーションのログにも柔軟に対応できます。ただし、そのためには出力先や設定ファイルの配置に一工夫が必要です。ここでは、実際の活用方法を3つのステップに分けて紹介します。
シンボリックリンクを使った/var/log連携構成
logrotateは基本的に /var/log/ 配下のログを対象として想定しています。そのため、自作アプリのログを /opt/myapp/logs/app.log のような任意パスに出力している場合でも、シンボリックリンクを使って /var/log に接続することで簡単に対応できます。
以下のコマンドで、ログファイルのシンボリックリンクを作成します。
ln -s /opt/myapp/logs/app.log /var/log/myapp.log
このようにしておけば、あとは /var/log/myapp.log に対してlogrotateの設定を行うだけで、自作アプリのログも一元的に管理できます。
logrotate.dに個別設定ファイルを設置する例
自作アプリごとのローテート設定は、/etc/logrotate.d/ 配下にファイルを追加することで対応します。以下は、/var/log/myapp.log を対象にした設定例です。
/var/log/myapp.log {
daily
rotate 7
compress
missingok
notifempty
create 644 root root
postrotate
/bin/systemctl reload myapp.service > /dev/null 2>&1 || true
endscript
}
この設定により、ログは毎日ローテートされ、最大7世代分保持されます。また、ローテート後に対象サービスの再読み込みも可能です。
ファイルローテート結果の確認方法とテストコマンド
設定したlogrotateが正常に動作しているかを確認するには、以下の2つの方法があります。
まず、手動でテストを行うには以下のコマンドを使用します。
logrotate -d /etc/logrotate.conf
この -d はデバッグモードで実行し、実際には処理を行わずにシミュレーションだけを表示します。
実際に処理を強制的に実行する場合は、次のように記述します。
logrotate -f /etc/logrotate.d/myapp
実行後、指定されたログファイルの隣に .1, .2.gz などのローテートファイルが作成されていれば正常に動作しています。
また、ローテート対象のログがロックされている場合や、権限の問題があると処理に失敗することがあります。必要に応じて logrotate のログやサービスの journalctl 出力を確認してください。