logrotateの設定①

Linuxでは、特に設定をしなくてもログがローテーションされるようになっているため、設定を変更したことがない方もいるかもしれません。
なので今回は、ローテーションの間隔や、ログの保存期間などの変更の仕方について紹介していきます！

まずは、今回の要件を以下にまとめます。

・日次でローテーションする
・ログの保存期間は366日とする
・ローテーション時に圧縮する
・ログが空でもローテーションする

上記の要件を１つずつ設定していきます。

ログローテーションの設定ファイルには、`/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`の設定値が適用されます。
<font color="gray">（ゲシュタルト崩壊しそうな文章ですみません…）</font>

まず、`/etc/logrotate.d`配下に新しい設定ファイルを作成します。
デフォルトで作成されているファイルをコピーするのが良いと思いますが、今回は1から作成します。

ファイル名は任意ですが、何のログのローテーション設定か分かるような名前が良いと思います。
今回はrsyslog設定で受信したログをローテーションしたいので、**receivelog**にしておきます。

まず初めに、ローテーションしたいログファイルを記載します。複数のログファイルを同時に指定できます。
<font color="gray">※[rsyslogの設定](https://qiita.com/sugar_salt75/items/1d1980d5b66becc9f38f)で、ログの名前は日付にしない方が分かりやすいと記載しましたが、そもそも上手くローテーション出来なかったので、日付でも指定できるかはどなたかチャレンジしてみてください。。</font>

<font color="blue">（記載例）
/var/log/rsyslog/host1/host1.log
/var/log/rsyslog/host2/host2.log
/var/log/rsyslog/host3/host3.log</font>

次に、要件の設定をしていきます。

<font color="limegreen">・日次でローテーションする
・ログの保存期間は366日とする</font>
ローテーションの実行間隔には、`daily`(日次)、`weekly`(週次)、`monthly`(月次)、`yearly`(年次)があり、今回は日次でローテーションしたいので`daily`を指定します。

ログの保存期間は、ローテーションの実行間隔に関係なく、全て`rotate <数字>`で記載します。
`daily`の場合は保存期間の単位が日、`yearly`の場合は単位が年、という事になります。
要件にあるように366日分保存したい場合は、`rotate 366`になります。

ちなみにシスログに関しては、前述したsyslogファイルの中で指定されていないので、`logrotate.conf`内の設定が適用されます。
`weekly`と`rotate 4`が設定されているので、シスログは週次でローテーションされ、保存期間は4週間ということになります。
実際にシスログを確認してみると、そうなっているのが分かると思います。

`rotate`を指定しないと、`rotate 0`と解釈され、<font color="red">古いログが全て削除されてしまう</font>ので忘れずに設定しましょう！！！

<font color="limegreen">・ローテーション時に圧縮する</font>
古いログを圧縮したい場合は`compress`を指定します。
圧縮したくない場合は`nocompress`を指定しますが、何も指定しない場合も圧縮されないので指定しなくても良いと思います。

`logrotate.conf`内では、`compress`がコメントアウトされているので個別に設定しない限りは圧縮されません。
シスログのように保存期間が短い物や、過去のログも確認する可能性がある場合は圧縮しなくても問題ないと思いますが、ログのサイズが大きい物などは容量を逼迫するので、そのような場合は圧縮するのが望ましいと思います。

<font color="limegreen">・ログが空でもローテーションする。</font>
空のファイルをローテーションする場合は、`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つ気になることがあります。
それはログローテーションは一体いつ実行されているのか？ということです。

なので次回は、ログローテーションの実行時間について説明します！