はじめに
サーバの運用作業を行っているとき、リリース作業を行っているときにログを監視するために tail -f コマンドを利用します。
tail -f でログを監視している時にログが急に止まってしまい、「ドキッ」としたことはないでしょうか。
実際にはログローテートされていたり、ログファイルがリネームされただけだった、というケースがあります。
さて、この ログファイルがリネームされた時に tail -f で監視していたログ出力が止まってドキッとしてしまう問題 をなんとかできないものでしょうか。
今回はこの問題に対する対処法を紹介します。
動画解説
動画でも解説しています。
検証環境
| |
問題の再現方法
説明文だけではわかりにくいので、実際に問題を発生させてみます。
今回はターミナルを 3 つ立ち上げる必要があります。
1 つ目のターミナル - ログファイルを監視
1 つ目のターミナルではログファイルを監視します。
| |
何も表示されません。まだログファイルに何も書き込んでいないためです。
2 つ目のターミナル - ログファイルに書き込み
ループをして、1 秒ごとに現在日時を one.log に書き込み続けます。
| |
このタイミングで「1 つ目のターミナル」に情報が表示され始めます。
| |
3 つ目のターミナル - ログファイルを mv する
ここで 3 つ目のターミナルで one.log をリネームします。
| |
すると、 one.log ファイルが有るにも関わらず 1 つ目のターミナルには何も表示されなくなってしまいます。
なぜ表示されないの? tail -f コマンドは何を監視しているの?
なぜ one.log を監視しているのに何も表示されなくなってしまったのでしょうか。
理由は tail -f コマンドのデフォルトの挙動に関係しています。
実は tail -f コマンドは tail --follow=descriptor というコマンドの省略形です。
このオプションを付与されていると、ファイル名が変更されても変更されたファイルを監視します。
以下のコマンドを実行すれば、「1 つ目のターミナル」にメッセージが表示されます。
| |
対処法
tail コマンドの他のオプションを利用してやることで対処できます。
--follow=name と --retry という 2 つのオプションを利用します。
--follow=name は -f / --follow=descriptor とは異なる挙動をさせるためのオプションです。ファイルがリネームされたり、別ファイルで上書きされたりした場合は新しいファイルに追従します。
--retry はほぼ必須だと思っていただければよいです。
実行してみます。
| |
ここで、「3 つ目のターミナル」でファイルをリネームします。 すると、以下のように途中でファイルが新しく作成し直されたため、新しいファイルを監視したというメッセージが表示されます。
| |
2 つのオプションをまとめた -F を使うと便利
--follow=name と --retry をあわせた -F というオプションがあります。
先程も言ったとおり、 --follow=name オプションと --retry オプションはほぼ一緒に使われることになりますので、これらをまとめた -F オプションが用意されています。
-F オプションを使うと、次のように書くことができます。
| |
このコマンドを実行すると、 one.log ファイルが一時的に削除やリネームされたとしても、再び one.log という名前のファイルが作られたら、そのファイルを追跡し続けます。
ひとこと
動画による解説も始めました。
ただ、花粉症がひどくて喋りづらいです。