Linuxでは、特に設定をしなくてもログがローテーションされるようになっているため、設定を変更したことがない方もいるかもしれません。
なので今回は、ローテーションの間隔や、ログの保存期間などの変更の仕方について紹介していきます!
まずは、今回の要件を以下にまとめます。
・日次でローテーションする
・ログの保存期間は366日とする
・ローテーション時に圧縮する
・ログが空でもローテーションする
上記の要件を1つずつ設定していきます。
ログローテーションの設定ファイルには、/etc/logrotate.conf
と/etc/logrotate.d
配下にある個別の設定ファイルの2パターンがあり、/var/log/messeage
や/var/log/secure
などのシスログのローテーション設定も、/etc/logrotate.d
配下のsyslog
というファイルで設定されています。
今回のように新しくローテーションの設定を追加したいときも、/etc/logrotate.d
の配下に新しく設定ファイルを作成していきます。
ちなみに、/etc/logrotate.d
配下のファイルは、/etc/logrotate.conf
の中でログローテ実行時に読み込む設定がされており、ローテーションの周期などは/etc/logrotate.d
配下にある個別の設定ファイルの設定値が優先されます。
/etc/logrotate.d
配下の個別の設定ファイルに記載がなく、/etc/logrotate.conf
に記載がある項目に関しては、/etc/logrotate.conf
の設定値が適用されます。
(ゲシュタルト崩壊しそうな文章ですみません…)
まず、/etc/logrotate.d
配下に新しい設定ファイルを作成します。
デフォルトで作成されているファイルをコピーするのが良いと思いますが、今回は1から作成します。
ファイル名は任意ですが、何のログのローテーション設定か分かるような名前が良いと思います。
今回はrsyslog設定で受信したログをローテーションしたいので、receivelogにしておきます。
まず初めに、ローテーションしたいログファイルを記載します。複数のログファイルを同時に指定できます。
※rsyslogの設定で、ログの名前は日付にしない方が分かりやすいと記載しましたが、そもそも上手くローテーション出来なかったので、日付でも指定できるかはどなたかチャレンジしてみてください。。
(記載例)
/var/log/rsyslog/host1/host1.log
/var/log/rsyslog/host2/host2.log
/var/log/rsyslog/host3/host3.log
次に、要件の設定をしていきます。
・日次でローテーションする
・ログの保存期間は366日とする
ローテーションの実行間隔には、daily
(日次)、weekly
(週次)、monthly
(月次)、yearly
(年次)があり、今回は日次でローテーションしたいのでdaily
を指定します。
ログの保存期間は、ローテーションの実行間隔に関係なく、全てrotate <数字>
で記載します。
daily
の場合は保存期間の単位が日、yearly
の場合は単位が年、という事になります。
要件にあるように366日分保存したい場合は、rotate 366
になります。
ちなみにシスログに関しては、前述したsyslogファイルの中で指定されていないので、logrotate.conf
内の設定が適用されます。
weekly
とrotate 4
が設定されているので、シスログは週次でローテーションされ、保存期間は4週間ということになります。
実際にシスログを確認してみると、そうなっているのが分かると思います。
rotate
を指定しないと、rotate 0
と解釈され、古いログが全て削除されてしまうので忘れずに設定しましょう!!!
・ローテーション時に圧縮する
古いログを圧縮したい場合はcompress
を指定します。
圧縮したくない場合はnocompress
を指定しますが、何も指定しない場合も圧縮されないので指定しなくても良いと思います。
logrotate.conf
内では、compress
がコメントアウトされているので個別に設定しない限りは圧縮されません。
シスログのように保存期間が短い物や、過去のログも確認する可能性がある場合は圧縮しなくても問題ないと思いますが、ログのサイズが大きい物などは容量を逼迫するので、そのような場合は圧縮するのが望ましいと思います。
・ログが空でもローテーションする。
空のファイルをローテーションする場合は、ifempty
を指定します。
ローテーションさせたくない場合は、notifempty
を指定しますが、何も指定しない場合は空ファイルはローテーションされないと思います。
そして要件にはないですが、エラーを出力させたくないのでmissingok
のオプションも付けます。
このオプションを設定すると、ログファイルが存在しなくてもエラーを出力せずに処理を続行します。
以上を、ファイルに記載すると以下になります。
/var/log/rsyslog/host1/host1.log
/var/log/rsyslog/host2/host2.log
/var/log/rsyslog/host3/host3.log
{
daily
rotate 366
compress
ifempty
missingok
}
上記のように、オプションの最初と最後は{ }
で括ります。
ファイルの作成後は、ログローテーションの実行前に、以下のコマンドで設定ファイルに問題がないかをチェックします。
# logrotate -d /etc/logrotate.d/receivelog
※ファイル名は実際に作成したものに合わせてください
‐d
を付けることによりデバックモードで実行されるので、実際にログローテーションが実行された時の流れが画面上に出力されますが、ログのローテーション自体は行われません。
また、設定内容に不備があるとエラーが出力されるので、ファイルの作成後はこちらのコマンドを入力し確認するようにしましょう。
loglotate
はコマンドなので、ファイルを反映させるための再起動などは不要です。
あとは、ログローテーションが実行されるのを待ち、次の日にローテーションの確認をします。
これで設定は完了です!…と、言いたいところですが、
ディレクトリを確認したところ、ログのローテーション自体は行われていましたが、新しいログには何も出力されていないことが分かりました。
原因を調べたところ、compress
の設定を入れると起きる事象のようで、compress
では、古いログファイルを圧縮して別のファイル(別のi-node)を作成し、古いログファイルを削除するのですが、その古いログに対して書き込みを続けてしまうために、出力されていないようでした。(全てのサービスで起こる事象ではないようです)
他のオプションを調べてみると、1つ前のログファイルを圧縮するのを次回のローテーション時まで遅らせるdelaycompress
というオプションがあったのでこちらを設定してみたところ、ログは出力され続けましたが、新しいログに切り替わっておらず前日と同じログファイルに出力されてしまうようでした。
再度オプションを調べたところ、他のログのローテーションに使われているcopytruncate
というオプションを見つけました。
このオプションは元のログファイルを移動(mv)し、新しいログファイルを作成するのではなく、コピーを作成した後に元のログファイルを空にするものなので、何らかのプログラムに対しログファイルのクローズを要求できないために、前のログファイルに永久に書き込まれてしまう場合に便利です。
つまり、ローテーション後に書き込むのは新しいファイルではなく元々のファイルなので、このオプションを追加したところ無事に要件通りにログローテーション出来ました!
しかし、ここで1つ気になることがあります。
それはログローテーションは一体いつ実行されているのか?ということです。
なので次回は、ログローテーションの実行時間について説明します!