logrotateを使う
はじめに
ログを日次や指定した時間でローテートすることができる、logrotate
を使ってみる。
アプリケーションのログや、自作のログなどはlogrotate
をすると良いので、この機会に覚えておきたい。
環境
|
|
準備
logrotate
が入っていることを確認する。
|
|
ない場合は下記で入れる。
|
|
logrotateの実践
設定ファイルの確認
まずは、logrotate
の大元の設定ファイルを確認する。
|
|
|
|
上記のようになっている、 /etc/logrotate.d
に Apache
での設定やら、 nginx
での設定など、アプリケーションごとの設定ファイルを入れるのが良い。
ちなみに、 /etc/logrotate.d
は下記のようになっている。
|
|
設定ファイルを作成する
/etc/logrotate.d
に 自分が作成するアプリケーションのログを設定する。
|
|
上記で作成を行う。
|
|
|
|
※設定の種類 (ChatGPTに出力してもらった。)
設定オプション | 説明 |
---|---|
compress | ローテーション後にログファイルを圧縮するかどうかを指定します。 |
copytruncate | ログファイルを切り詰めずにコピーしてから新しいファイルを作成します。 |
daily | ローテーションの間隔を日単位で指定します。 |
weekly | ローテーションの間隔を週単位で指定します。 |
monthly | ローテーションの間隔を月単位で指定します。 |
rotate <count> | ログファイルをローテーションする回数を指定します。 |
size <size> | ログファイルのサイズが指定したサイズに達した場合にローテーションを実行します。 |
maxsize <size> | ログファイルの最大サイズを指定します。ログファイルがこのサイズを超えた場合にローテーションを実行します。 |
notifempty | ログファイルが空の場合にはローテーションを実行しません。 |
create | ローテーション後に新しいログファイルを作成するかどうかを指定します。既存のログファイルは空にされます。 |
dateext | ローテーションされたログファイルに日付を追加します。 |
dateformat | ローテーションされたログファイルの日付のフォーマットを指定します。 |
postrotate | ローテーション後に実行するコマンドを指定します。 |
prerotate | ローテーション前に実行するコマンドを指定します。 |
sharedscripts | postrotate またはprerotate スクリプトを1回だけ実行します(すべてのローテーション対象のログファイルに対して)。 |
missingok | ローテーション対象のログファイルが存在しない場合でもエラーを発生させずに処理を続行します。 |
動作
- ログファイルが書き込まれる場所を作成する。
|
|
- cronで自動的にログファイルを書き込むように設定する。
|
|
- 1分置きに自動で書き込むようにする。
crontab
|
|
- 書き込まれているかの確認
|
|
ちゃんと書き込まれているっぽい。
|
|
- 設定ファイルでのローテートをさせる。
|
|
-d
・・・デバッグモード
-f
・・・強制的にローテートさせる。
下記のようにエラーが出た。 親ディレクトリの権限による問題みたい。
|
|
権限を適切なものに修正する。
|
|
また、これに伴い、crontab -e
を行い、下記のように修正する。
|
|
この状態で再度実行をする。
|
|
ログがローテートされている!
|
|
何回もローテートされることを確認。
10世代までだが、2世代まで確認する。
|
|
疑問に思った点
logrotate
はどのように行われるのか?
日次でログファイルを切りかえる際に、いずれかなのかと考えた。
- 既存のログファイルをリネーム→新しくログファイルを作成
- 既存のファイルをコピー+リネームし、古いログとして作成。既存のログファイルを
cp /dev/null
などで空にする。
どうやら調べると、1番目がデフォルトの動作で、2番目が copytruncate
を指定したときの動作とのこと。
ChatGPT
に聞いてみると、下記の回答を得られた。
copytruncateは、logrotateの設定オプションの1つです。このオプションが指定された場合、logrotateはログファイルを切り詰めずに、新しいファイルを作成します。
通常、logrotateは既存のログファイルをリネーム(または削除)して新しいログファイルを作成します。しかし、copytruncateオプションが指定されると、logrotateは既存のログファイルを切り詰めずにそのままの状態でコピーし、同じ名前の新しいログファイルを作成します。
これにより、アプリケーションがログファイルに直接書き込んでいる場合でも、ログの追加は中断されずに継続されます。なお、この方法では、元のログファイルの内容は失われますが、ファイルディスクリプタは変更されないため、アプリケーションはログの書き込みを続けることができます。
copytruncateは、特定のアプリケーションがログファイルを開いたままにする必要がある場合や、ログファイルを分割してもファイルディスクリプタを維持する必要がある場合などに便利です。ただし、注意点として、切り詰められたログファイルは一部のログエントリが欠落している可能性があるため、データの完全性が重要な場合には適切なオプションを選択する必要があります。
そのため、 1番目の方法の場合は、 ローテートする際に postscript
を書いてアプリケーションをリロードや再起動をして、ログファイルを新しいものに再度読み込ませる必要がある。
2番目の方法( copytruncate
)では、上記のような設定はいらないが、ログエントリが欠落する可能性があるとのことだ。
postscriptはcopytruncateを指定しない場合、必ず必要か?
1点目の疑問で思った、ローテートする際に postscript
を書いてアプリケーションをリロードや再起動をして、ログファイルを新しいものに再度読み込ませる必要がある。
の部分だが、これも ChatGPT
に聞いてみる。
copytruncateオプションを指定しない場合、logrotateは既存のログファイルをリネーム(または削除)して新しいログファイルを作成します。そのため、アプリケーションは新しいログファイルに対してファイルディスクリプタを持っていないため、再起動やリロードが必要になる場合があります。
多くのアプリケーションでは、ログファイルへの書き込みはファイルディスクリプタを介して行われます。logrotateによって既存のログファイルがリネームされると、アプリケーションは古いファイルディスクリプタを使用し続けることになります。新しいログファイルが作成された後、アプリケーションは新しいファイルディスクリプタを取得する必要があります。
したがって、アプリケーションがログファイルのリロードや再起動をサポートしていない場合、ログファイルの切り替え後にログの書き込みが正常に継続されない可能性があります。この場合、アプリケーションを再起動するか、ログの書き込みを再開するための特定の手順を実行する必要があります。
ただし、アプリケーションによっては、logrotateの信号を受け取ってログファイルを再オープンする機能を備えている場合もあります。この場合、特別な処理や再起動は不要であり、アプリケーションは新しいログファイルに対して正常にログの書き込みを続けることができます。
アプリケーションのドキュメントやログ関連の設定を確認し、logrotateの挙動に関するアプリケーション固有の要件や推奨事項を確認することをおすすめします。
ということなので、アプリケーションによっては、 postscript
で再起動、リロードがなくてもローテートしてくれるらしい。
参考
- 任意のログをlogrotateを使って管理する
https://qiita.com/Esfahan/items/a8058f1eb593170855a1 - logrotateの備忘録
https://qiita.com/may-bee-39/items/4fb6beb19c6f4fe8b587 - Logrotate | ArchLinux
https://wiki.archlinux.jp/index.php/Logrotate
おわりに
logrotate
を勉強した。
巨大な1個のログファイルとならないように、アプリケーションのログは適切にローテートする必要がある。
そのため、logrotate
を設定していないログがある場合については、使用することを検討したほうが良い。