前回(loglotateの設定①)の続きです。
loglotateの動作について
まず、logrotate
は何の設定をしなくても毎日実行されるようになっていることは前回の記事にも書きましたが、動作自体はcron
ではなくanacron
で動作しています。
anacron
はサーバに負荷がかからないように一定範囲内でランダムな時刻に実行するとともに、実行時にサービスが停止していたなどで実行できなくても、復旧後の正常稼働状態になると実行される特徴がある…らしいです。
ローテーションされたログのタイムスタンプを確認すると分かりますが、特に何も設定していない場合はログローテが3時頃に実行されていることが分かります。
それはつまり、今のままだと3:00~翌日の3:00の2日間にまたがったログになってしまっている、という事になります。
このままだと、必要なログを見たいときに探しにくくなってしまうので、今回はログローテの実行時間も変更したいと思います。
既存の設定の無効化
まずは/etc/anacrontab
ファイルを編集し、下記のようにanacron
で動作している日次の処理だけコメントを入れて無効化します。
#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
logrotate
は何の設定をしなくても毎日実行されるようになっていると前述しましたが、それはloglotate
の実行ファイルが/etc/cron.daily
配下に格納されていて、かつ、/etc/cron.daily
配下のファイルが毎日実行されるようにこの/etc/anacrontab
に元々記載されているからになります。
コメントアウトすることにより、anacron
で/etc/cron.daily
内の処理は実行されなくなったので、次にcron
で決まった時刻に実行するように設定を追加します。
実行時間の設定
/etc/crontab
を編集し、一番下に以下の1行を追加します。
0 0 * * * root run-parts /etc/cron.daily
23:59に設定するのが定番(?)ですが、ログの量が多く、処理に時間がかかってしまうと日付が変わってしまうので今回は0:00に設定します。
/etc/crontab
を保存し、crond
を再起動したら、再びログローテが実行されるのを待ちます。
これで、ログローテが0時に実行されるようになりましたが、ここでもう1つオプションを紹介します。
ファイル名に付く日付について
ログローテでは、ログがローテーションされる時に古いファイルに日付を付けるdateext
というオプションが/etc/logrotate.conf
の中でデフォルトで設定されているのですが、このオプションではログを取得した日付ではなく、ログローテが行われた日付が付いてしまいます。
今回、ログローテの実行時間を0時に設定したので、例えば中身は12月31日のログなのに、ファイル名には1月1日の日付が付いてしまい、少しややこしくなってしまいます。
そんな時にピッタリなのがこちらのオプション!!(通販みたいになってしまった…)
dateyesterdayです!!!
オプションの名前から気付いた方もいると思いますが、このオプションを指定するとdateext
で付与される日付に昨日の日付が使われるので、これにより、ローテーションされたファイルのタイムスタンプとファイル名の日付が一致し、管理がしやすくなります。
最終的に設定した内容は以下になります。
/var/log/rsyslog/host1/host1.log
/var/log/rsyslog/host2/host2.log
/var/log/rsyslog/host3/host3.log
{
daily
rotate 366
compress
ifempty
missingok
copytruncate
dateyesterday
}
これで設定は完了ですが、今回登場しなかった他のオプションについてもいくつか説明します。
■create { mode owner group | owner group }
ローテーションが行われた直後すぐに新しいログファイルを作成します。(ローテーションされた元のファイルと同じ名前で作成されます。)
同時にログのパーミッションや、所有者を指定する事も出来ます。
i-node
が変わるため、アプリケーションによってはこのオプションは使用できず、今回の要件でも使用できませんでした。
ちなみに、このオプションは/etc/logrotate.conf
の中で指定されているので、個別に設定しない限りは全てのログローテの設定に適用されます。
copytruncate
が設定されている場合はこのオプションは適用されません。
■size [size]
日次、週次などの間隔ではなく、更新中のログファイルが[size]
で指定した Byte数を超えた場合にローテーションします。
この設定をした場合、daily
、weekly
等の設定を入れたとしても、無効とみなされます。
■maxsize [size]/minsize [size]
先ほどのsize
オプションと同様に、更新中のログファイルが[size]
で指定したByte数を超えた場合にローテーションします。
size
オプションとの違いは、追加で実行間隔を指定した場合に、そのタイミングを考慮してローテーションするかどうかになります。
代表的なオプションは以上になりますが、他にもまだあるので良ければ調べてみてください!
===番外編==========================================
番外編というより、知らなかった…という話なのですが、
前述した内容で設定し、結果無事にローテーションされたのですが、次の日に確認したときにローテーションされていない時がありました。
まだ設定内容に不備があるのかと思いましたが、色々調べてみたところ、どうやら新規のログファイルは初日はローテーションされないと書いてあるサイトを見つけました。。
logrotate
には、前回のログローテートを行った時刻を記載している/var/lib/logrotate/logrotate.status
というファイルが存在するのですが、新規ログファイルの場合はlogrotate.status
に何も記載がないので、初回処理時に新規ログファイルの情報をlogrotate.status
に書き込みます。
次回logrotate
が実行された時にlogrotate.status
に記載のある時刻を元に1日後(daily
)、1週間後(weekly
)、1ヶ月後(monthly
)のローテートを行うようです。
初回の処理としてはその書き込む作業だけで終わってしまうので、ローテーションはされていなかったようでした。
なので、もう1日待って次の日に確認したら無事にローテーションされてました。
………知らなかった。
ログローテを手動実行して一度書き込んでしまえば、次の日にローテーションされるんじゃないかと思ったんですが、logrotate.status
に記載のある時刻を元に、ということは手動実行した時間が基準になっちゃうんですかね…
でもcronで実行時間指定してますしね…誰か試してみてください!(他力本願)
また今回、初めに設定した内容だと上手くローテーション出来なかったと記載しましたが、受信したシスログを出力しているのも、サーバのシスログを出力しているのと同じrsyslogd
なので、じゃあサーバのシスログのローテーションはどう設定されているかというと以下のような設定が入っています。
postrotate
/usr/bin/systemctl kill -HUP rsyslog.service > /dev/null 2>&1 || true
endscript
ここで、一度rsyslog
のサービスをkill
しているので、ログローテしてもログの切り替えが出来ているようです。知らなかった。
初めからこの設定をそのままコピーすれば良かったような気もしますが、まあ今回は別パターンの設定方法の紹介という事で…
==================================================
以上、loglotateの設定編でした!
これで自在にログローテーションができるようになりましたね!!!
それでは、皆さんも素敵なlogrotateライフを!!!