トップページ > 保守運用 > サーバ > ログファイルを決まった時間に日別でローテートする方法

ログファイルを決まった時間に日別でローテートする方法

サーバには機能ごとに操作や処理の履歴をログに残すようになっている他、独自にプログラムして開発したアプリから出力したログは問題が発生した場合に確認する手段として欠かせない存在だが、常に同じファイルに出力し続けると保守運用に支障が出るためログファイルを決まった時間に日別でローテートする方法について紹介する。

ログファイルを決まった時間に日別でローテートする方法

1. ログローテートが必要な理由

ログファイルをローテートする必要な理由は、「ディスク容量の節約」と「保守運用の効率化」の 2 点が挙げられる。
1 つ目の「ディスク容量の節約」とは、ログをローテートせずに常に 1 つのファイルに出力をし続けていると調査時は楽になるが、ファイルサイズが大きくなりすぎることでディスクの空き容量が無くなるデメリットがある。
そのため、定期的にログをローテートすることでファイルを分割し、古いログファイルは自動的に削除するようにすればログファイルだけでディスク容量が足らなくなる事態は避けられる。

次に 2 つ目の「保守運用の効率化」とは、ログを見て調査するときは問題が発生した時点から少し前の日付程度の情報で済むことが多く、何か月、何年も古い日付のログを見る<ことは稀であり、不要な情報が多いほど調査の効率が悪くなる。
そこで、ログファイルを日別でローテートするようにすると問題発生した日のログファイルを参照すればよいので調査する効率が上がる。/p>

2. Apache のログを日別にローテートする方法

今回は Web サーバの Apache のログを日別にローテートすることにする。
Apache の初期状態はアクセスログとエラーログの 2 つをログファイルに出力するようになっており、RedHat7 及び CentOS7 以降は OS の機能でログがローテートされるようになっている。
ローテートの設定を変えていなければ、下記のように一週間ごとに 03:00 前後で自動的にローテートするようになっている。
また、ローテートしたファイルは残り続けることはなく、書き込み中のファイルとローテートした 4 世代分が残る設定である。

# ls -la /var/log/httpd
合計 308
drwx------   2 root root    253 10月 24 03:34 .
drwxr-xr-x. 13 root root   4096 10月 24 03:34 ..
-rw-r--r--   1 root root      0 10月 20 03:24 access_log
-rw-r--r--   1 root root  87199  9月 24 11:16 access_log-20210925
-rw-r--r--   1 root root   2876 10月  1 17:57 access_log-20211002
-rw-r--r--   1 root root 104758 10月  8 14:24 access_log-20211009
-rw-r--r--   1 root root  85165 10月 19 17:32 access_log-20211020
-rw-r--r--   1 root root    861 10月 24 03:34 error_log
-rw-r--r--   1 root root   3594 10月  3 03:50 error_log-20211003
-rw-r--r--   1 root root   4896 10月 10 03:22 error_log-20211010
-rw-r--r--   1 root root   1157 10月 17 03:20 error_log-20211017
-rw-r--r--   1 root root   3606 10月 24 03:34 error_log-20211024

Apache のログファイルは Apache の機能である rotatelogs を使ってサーバ自身でローテートさせることができるが、初期設定時より OS のローテートの機能(logrotate.d)のまま、設定変更して日別にローテートするようにする。
ローテートの設定ファイルは /etc/logrotate.d/httpd となり、変更と同時に反映されるため OS やサービスの再起動は不要である。

# vi /etc/logrotate.d/httpd 

/var/log/httpd/*log {
    daily ← 追記
    rotate 31 ← 追記
    dateext ← 追記
    dateformat .%Y%m%d ← 追記
    missingok
#    notifempty ← コメント化(コメントすることでログファイルが空でもローテートする)
    sharedscripts
    delaycompress
    postrotate
        /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
    endscript
}

/etc/logrotate.d/httpd の設定変更の翌日、Apache のログファイルの状態を確認すると下記のようになっており、翌日にファイル名に日付が付与されてローテートしているのがわかる。

# ls -la
合計 16
drwx------   3 root root  114 10月 27 03:11 .
drwxr-xr-x. 13 root root 4096 10月 24 03:34 ..
-rw-r--r--   1 root root    0 10月 27 03:11 access_log
-rw-r--r--   1 root root 3448 10月 26 14:51 access_log.20211027
-rw-r--r--   1 root root  861 10月 27 03:11 error_log
-rw-r--r--   1 root root 1157 10月 27 03:11 error_log.20211027

3. ログローテートの動作確認

前述では Apache のログローテートの設定変更して翌日に動作確認したが、もし正常に動作していない場合は再設定してまた翌日確認するのは時間がかかりすぎるため、即座にローテートの動作確認する方法が下記のように logrotate コマンドで確認することができる。

# logrotate -dv /etc/logrotate.d/httpd

logrotate コマンドを実行すると実際にローテートされてしまうため、オプションで -d を付けるとデバッグモードで実行される。
また、-v を付けると実行の詳細情報が表示されるため -d と -v を合わせて利用すると状況がわかりやすくなる。
尚、上記のコマンドを実行すると次の詳細情報が表示され、内容より既に同日にローテートが実施されているためローテートしない旨が出ている。

(略)considering log /var/log/httpd/access_log
  Now: 2021-10-28 13:08
  Last rotated at 2021-10-28 03:46
  log does not need rotating (log has been rotated at 2021-10-28 3:46, that is not day ago yet)
(略)

4. Apache のログを決まった時間でローテートする方法

前述で Apache のログファイルを日別でローテートするようにしたが、ローテートされるのが翌日 03:00 前後のため、ある日の 00:00 から 23:59 までの当日分を調査したい場合はログファイルが 2 つに分かれてしまうデメリットがある。
そこで、ローテートのタイミングを 23:59 に実行するように設定することで日付が変わる 1 分前には新しいログに出力させることができる。

logrotate.d の動作は /etc/cron.daily/logrotate に設定ファイルに記載されており、定期的に動作する cron ではなく anacron で動作している。
anacron はサーバに負荷がかからないように一定範囲内でランダムな時刻に実行するとともに、実行時にサービスが停止していたなどで実行できなくても、復旧後の正常稼働状態になると実行される特徴がある。
まずは下記のように anacron で動作している日別の処理にコメントを入れて無効化する。

# vi /etc/anacrontab

# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days   delay in minutes   job-identifier   command
1       5       cron.daily              nice run-parts /etc/cron.daily → ここの冒頭に # を入れてコメント
7       25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly

anacron で /etc/cron.daily 内の処理は実行されなくなったので、決まった時刻で動作する cron で実行するように設定を追加する。

# vi /etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
59 23 * * * root run-parts /etc/cron.daily ← 追記

この状態で翌日にログファイルの状態を確認すると指定した時刻にローテートが実行されているのがわかる。

# ls -la /var/log/httpd
合計 296
drwx------   3 root root    220 10月 29 13:14 .
drwxr-xr-x. 13 root root   4096 10月 24 03:34 ..
-rw-r--r--   1 root root      0 10月 29 13:14 access_log
-rw-r--r--   1 root root   3448 10月 26 14:51 access_log.20211027
-rw-r--r--   1 root root 269266 10月 27 13:47 access_log.20211028
-rw-r--r--   1 root root   7407 10月 28 23:59 access_log.20211029
-rw-r--r--   1 root root    861 10月 29 13:14 error_log
-rw-r--r--   1 root root   1157 10月 27 03:11 error_log.20211027
-rw-r--r--   1 root root   3714 10月 28 03:46 error_log.20211028
-rw-r--r--   1 root root   1157 10月 29 23:59 error_log.20211029

関連記事