Linux の基礎知識

【Linuxの基礎知識】Linuxでログ肥大を防ぐlogrotateの基本と自作アプリ対応法

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はプレーンテキストで出力されるファイルを対象としており、任意の場所にあるログファイルを管理できます。

以下のように使い分けるのが一般的です。

ログ管理方式対象保存形式利点
journalctlsystemdサービス(標準出力)バイナリプロセス単位で統一管理できる
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.22回前にローテートされたログ
3世代前app.log.33回前にローテートされたログ
4世代前app.log.44回前にローテートされたログ
5世代前app.log.55回前にローテートされたログ(次回削除対象)

次回のローテート処理が行われると、以下のようにファイルが順番に繰り上がり、最も古い世代(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 出力を確認してください。

本サイトにて記載のすべてのスクリプト利用により発生した利用者の損害全てに対し、いかなる責任をも負わないものとし、損害賠償をする一切の義務はないものとします。また、この記事は、実際の案件対応を通じて得た知見をもとに筆者が作成したものであり、全コードと解説は著者本人による設計・検証結果に基づいています。

よく読まれている記事

1

「シェル」と「シェルスクリプト」という言葉を聞いたことがありますか?どちらもLinuxやMacのターミナルで使われるものですが、それぞれの役割や使い方には違いがあります。 本記事では、「シェル」と「シ ...

2

「私たちが日々利用しているスマートフォンやインターネット、そしてスーパーコンピュータやクラウドサービス――これらの多くがLinuxの力で動いていることをご存じですか? 無料で使えるだけでなく、高い柔軟 ...

3

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Linux の基礎知識