LoginSignup
5
4

More than 1 year has passed since last update.

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内の設定が適用されます。
weeklyrotate 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つ気になることがあります。
それはログローテーションは一体いつ実行されているのか?ということです。

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

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4