Amazon Web Services 資料一覧

Amazon Linux 2上でのanacronによるログローテーションの挙動、およびローテーション設定ファイルで指定可能なオプション

2021/05/28更新

対応バージョン: Amazon Linux 2

Amazon Linux 2上で動作するanacronによるログローテーションのデフォルトの挙動が複雑なので整理する。

また後半ではローテーション設定ファイルで指定可能なオプションを解説する。

なお、ここでは以下のカーネルバージョンを使用する。

$ uname -r
4.14.231-173.361.amzn2.x86_64

ログローテーションの実行タイミング

ログローテーションの実行タイミングは以下の通りである。

1日1回、3時〜22時の間の最初に訪れたxx時6分〜51分(起動がxx時1分 + ランダム遅延時間最大45分 + 固定遅延時間5分)

ログローテーション実行までの詳細な流れ

上記のタイミングを制御するために複数の設定ファイルにより以下のような流れでログローテーションが実行される。

/etc/cron.d/0hourlyの記述に従い毎時1分に/etc/cron.hourlyディレクトリ配下のスクリプトが起動する
$ ls -l /etc/cron.d
合計 16
-rw-r--r-- 1 root root 128  1月 16  2020 0hourly
-rw-r--r-- 1 root root 108  8月  2  2018 raid-check
-rw------- 1 root root 235 12月 17  2019 sysstat
-rw-r--r-- 1 root root 191 10月 16  2018 update-motd

$ cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
/etc/cron.hourlyディレクトリには0anacronスクリプトが格納されており、anacronが起動する(/var/spool/anacron/cron.dailyの中身は空である)
$ ls -l /etc/cron.hourly
-rwxr-xr-x 1 root root 392  1月 16  2020 0anacron

$ cat /etc/cron.hourly/0anacron
#!/bin/sh
# Check whether 0anacron was run today already
if test -r /var/spool/anacron/cron.daily; then
    day=`cat /var/spool/anacron/cron.daily`
fi
if [ `date +%Y%m%d` = "$day" ]; then
    exit 0;
fi

# Do not run jobs when on battery power
if test -x /usr/bin/on_ac_power; then
    /usr/bin/on_ac_power >/dev/null 2>&1
    if test $? -eq 1; then
    exit 0
    fi
fi
/usr/sbin/anacron -s
anacronの設定ファイルである/etc/anacrontabには以下の内容が記述されており、ログローテーションは/etc/cron.daily/logrotateスクリプトにて実行される

・起動すると最大遅延時間45分が設定される(RANDOM_DELAY=45)

・実行時間は3時〜22時の間(START_HOURS_RANGE=3-22)

・cron.dailyの実行は1日1回(period in daysが1)

・cron.dailyの開始時間はanacron起動から5分後(delay in minutesが5) + 上記RANDOM_DELAY

$ sudo cat /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

$ ls -l /etc/cron.daily
合計 12
-rwx------ 1 root root 219  7月 27  2018 logrotate
-rwxr-xr-x 1 root root 618  4月 29  2019 man-db.cron
-rwx------ 1 root root 208  7月 27  2018 mlocate
/etc/cron.daily/logrotateスクリプトは以下のようになっており、ログローテーションは/etc/logrotate.confの設定に従って実行される
$ sudo cat /etc/cron.daily/logrotate
#!/bin/sh

/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
/etc/logrotate.confは以下の内容になっており、ログローテーション全体の設定および以下のファイルのログローテーション設定が記述されている。それ以外のファイルのローテーション設定は/etc/logrotate.d配下に格納されている

・/var/log/wtmp

・/var/log/btmp

$ cat /etc/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

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
	minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# system-specific logs may be also be configured here.

$ ls -l /etc/logrotate.d
合計 20
-rw-r--r-- 1 root root  76  8月  2  2018 bootlog
-rw-r--r-- 1 root root 160  8月 19  2020 chrony
-rw-r--r-- 1 root root 408  8月  2  2018 psacct
-rw-r--r-- 1 root root 224  6月 16  2020 syslog
-rw-r--r-- 1 root root 100  2月 25 18:33 yum

例えばsyslogのログローテーション設定は以下のような内容になっている。

$ cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    missingok
    sharedscripts
    postrotate
	/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

これら既存の設定を必要に応じて修正したり、アプリケーションログなど任意のファイルを追加でログローテーションしたい場合はこの/etc/logrotate.d配下に新規にファイルを作成して目的に合った設定を行う。

なお、ログローテーションの状況は対象ファイル毎に/var/lib/logrotate/logrotate.statusに記録され、次回ローテーション実行時に前回実行分との差を確認するために使用される。

$ cat /var/lib/logrotate/logrotate.status
logrotate state -- version 2
"/var/log/yum.log" 2021-5-26-8:0:0
"/var/log/boot.log" 2021-5-26-8:0:0
"/var/log/wtmp" 2021-5-26-8:0:0
"/var/log/chrony/*.log" 2021-5-26-8:0:0
"/var/log/spooler" 2021-5-26-8:0:0
"/var/log/btmp" 2021-5-26-8:0:0
"/var/log/maillog" 2021-5-26-8:0:0
"/var/log/secure" 2021-5-26-8:0:0
"/var/log/messages" 2021-5-26-8:0:0
"/var/log/cron" 2021-5-26-8:0:0
"/var/account/pacct" 2021-5-26-8:0:0

ローテーション設定ファイルで指定可能なオプション

主なオプションをざっと掲載する。

(*)印があるコマンドは先頭に「no」を付けると同オプションと反対の動きをする。(ただしifemptyだけは先頭に「not」が付いてnotifemptyになる)

より詳しくは「man logrotate」を参照のこと。

ローテーション時の挙動

compress (*)

古いログファイルをgzip圧縮する

delaycompress (*)

前のログファイルの圧縮を次のローテーション時に行う

compresscmd

compressオプションを指定した場合に圧縮に使うコマンド(デフォルトはgzip)

uncompresscmd

圧縮ファイルの解凍時に使うコマンド(デフォルトはgunzip)

compressext

圧縮ファイルで使用する拡張子(デフォルトはcompresscmdで指定したコマンドのデフォルト拡張子)

compressoptions

圧縮コマンドに指定するコマンドラインオプション(gzipコマンドの場合、デフォルトは-6(速度を犠牲にして圧縮率を高める))

copy (*)

ログファイルのコピーを作成するが、オリジナルは変更しない

このオプションを使用すると古いログファイルがそのまま残るため、create(ファイル作成時の指定)オプションは効果がなくなる

copytruncate (*)

元のログファイルをコピーして新しいファイルを作成する代わりに、コピーを作成したあと元のログファイルをトランケートする(中身を空にする)

copyオプションと同様、このオプションを使用すると古いログファイルがそのまま残るため、create(ファイル作成時の指定)オプションは効果がなくなる

create <モード> <オーナー> <グループ> あるいは create <オーナー> <グループ> (*)

ログローテーションの直後(ローテーション後のスクリプトが実行される前)にログファイルが作成される

ファイルの属性を省略すると元のログファイルのものが使われる

su <ユーザ> <グループ>

ローテーションされたファイルに設定するユーザとグループを指定する(デフォルトはroot)

olddir <ディレクトリ> (*)

ローテーションしたファイルを格納するディレクトリ

createolddir <モード> <オーナー> <グループ> (*)

olddirオプションで指定したディレクトリが存在しない場合は作成する

dateext (*)

ローテーションしたファイルの末尾に数字を追加するのではなく「YYYYMMDD」のような日付拡張子を追加する

拡張子のフォーマットはdateformatおよびdateyesterdayオプションで指定できる

dateformat <フォーマット文字列>

strftime(3)と同様の表記にてdateextオプションの拡張子を指定する

使用可能な表記は「%Y」「%m」「%d」「%H」「%s」のみである

デフォルトは毎時の場合は「-%Y%m%d%H」、それ以外は「-%Y%m%d」

dateyesterday

今日の日付の代わりに昨日の日付を使用してdateext拡張子を作成し、ローテーションされたログファイルの名前にタイムスタンプと同じ日付が含まれるようにする

extension <拡張子>

<拡張子>で指定した拡張子のついたファイルがログローテーション後も保持されるようにする

圧縮を有効化すると拡張子の後に圧縮の拡張子(通常は.gz)が続くが、例えば「mylog.foo」というファイルをローテーションした場合に「mylog.foo.1.gz」ではなく「mylog.1.foo.gz」いうファイル名になるようにする

ifempty (*)

ログファイルが空でもローテーションを行う

missingok (*)

ログファイルが見つからない場合でもエラーにせずに次のログファイルを処理する

rotate <回数>

指定した回数分ローテーションを行う

<回数>が0の場合、古いファイルはローテーションされるのではなく削除される

start <番号>

ローテーション時のファイル末尾に付与する番号の起点番号

例えば0を指定すると、ログは元のログファイルからローテーションされるため拡張子は「.0」となる

9を指定すると、ログファイルの拡張子は「.9」で作成され、0〜8はスキップされる

ファイルはrotateオプションで指定された回数だけローテーションする

size <サイズ>

ログファイルが指定したサイズより大きくなるとローテーションする

サイズはバイト指定だが、k(KB)、M(MB)、G(GB)などの単位を付けて指定することもできる

サイズの指定方法は他のオプションも同一

maxsize <サイズ>

追加指定された時間間隔(日次、週次、月次、または年次)より前であっても、ログファイルが指定したサイズより大きくなった場合にローテーションする

minsize <サイズ>

ログファイルが指定したサイズより大きくなった場合にローテーションするが、追加指定された時間間隔(日次、週次、月次、または年次)より前にはローテーションしない

maxage <カウント>

<カウント>日よりも古いローテーションされたログを削除する

shred (*)

ログファイル削除時にunlink()ではなくshred -uを使用する(デフォルトは無効)

shredcycles <カウント>

ログファイルを削除する前にshredにログファイルを<カウント>回数上書きするように要求する

このオプションを指定しない場合、shredのデフォルト値が使用される

tabooext [+] <拡張子リスト>

ローテーションから除外される拡張子を指定する

「+」が拡張子リストの前にある場合、現在の拡張子リストが拡張され、「+」がない場合は現在の拡張子リストがここで指定したリストに上書きされる

デフォルトの拡張子リストは以下の通り

「.rpmsave」「.rpmorig」「~」「.disabled」「.dpkg-old」「.dpkg-dist」「.dpkg-new」「.cfsaved」「.ucf-old」「.ucf-dist」「.ucf-new」「.rpmnew」「.swp」「.cfsaved」「.rhn-cfg-tmp-*」

ローテーションタイミング

hourly

ローテーションを毎時行う

ただlogrotateはcronの設定で毎日行うように設定されているため、毎時ローテーションを行いたい場合はcronの設定を毎時実行するように変更する必要がある

daily

ローテーションを毎日行う

monthly

logrotateがその月に初めて実行された時にログローテーションを行う(通常それは月の初日になる)

yearly

ローテーションを毎年行う

weekly <曜日>

指定した曜日に1回ローテーションするか、最後のローテーションから少なくとも7日経ってローテーションする

曜日を表す数字は以下の通りで、特別な指定である7は7日毎を意味する(デフォルトは0)

0(日曜日)、1(月曜日)、2(火曜日)、3(水曜日)、4(木曜日)、5(金曜日)、6(土曜日)

スクリプト実行

prerotate 〜 endscript

ログファイルがローテーションされる前にこのオプションに囲まれたスクリプトが実行される

後述のsharedscriptsオプションが指定されている場合はパターン全体がスクリプトに渡される

postrotate 〜 endscript

ログファイルがローテーションされた後にこのオプションに囲まれたスクリプトが実行される

後述のsharedscriptsオプションが指定されている場合はパターン全体がスクリプトに渡される

firstaction 〜 endscript

ログファイルがローテーションされる前、かつprerotateスクリプトが実行される前に1回だけ実行される

ただし、少なくとも1つのログファイルがローテーションされる場合のみ実行される

スクリプトがエラーになった場合、以降の処理は行われない

lastaction 〜 endscript

ログファイルがローテーションされた後、かつpostrotateスクリプトが実行された後に1回だけ実行される

スクリプトがエラーになった場合、エラーメッセージのみが表示される(これが最後のアクションのため)

preremove 〜 endscript

ログファイルを削除する直前に1回だけ実行される

sharedscripts (*)

通常、prerotateとpostrotateで指定したスクリプトはローテーションされるログ毎に実行され、ログファイルへの絶対パスがスクリプトの最初の引数として渡される

このオプションが指定された場合、パターンマッチしたファイルの数に関係なくスクリプトは一回だけ実行される

ただしパターンマッチしたファイルのうちローテーションの必要なものが一つもない場合はスクリプトは実行されない

スクリプトがエラーになった場合、残りのアクションはどのログに対しても実行されない

メール通知

mail <メールアドレス> (*)

対象ログファイルが存在しない状態でローテーションされると指定したメールアドレスにメール通知を行う

mailfirst

メール送信時に期限切れ間近のファイルではなくローテーションしたばかりのファイルを送信する

maillast

メール送信時にローテーションしたばかりのファイルではなく期限切れ間近のファイルを送信する(これがデフォルト)

その他

include <ファイル> あるいは <ディレクトリ>

指定したファイルあるいはディレクトリ配下のファイルを設定ファイルとして追加使用する