こんにちは。NMです。
「fluentdのログが肥大化してしまった!」
「でも、運用を止めることが出来ない。」
という問題についてと、fluentd 自身のログのローテートについて、うまくググれなかったので備忘録。
対象 fluentd
は、起動時に以下のようなオプションで起動させています。
fluentd -c config-file --log log-path -d pid-file
-c
で config を指定し、 -d
でデーモンとして起動しています。
(pid-file
には、起動したfluentdのPIDが書き込まれる)
くどいようですが、問題になっているのは、--log
で指定したログファイルの肥大化です。
一応試してみましたが、fluentd
を起動中にログファイルを退避しても、新しく生成されることはありませんでした。
やはり、古いファイルハンドルをつかんでいるのでしょうね。
ということで、どのようにログファイルを管理しているのかを見てみました。
目的の fluentd ソースコードは、lib/fluent/supervisor.rb になります。
47行 ~ 62行の init
メソッドで、ログファイルの指定があれば、ログファイルをOpenし、Fileオブジェクトを生成。
指定がなければ、デフォルト(標準出力)の Log
クラスを生成していることがわかります。
def init
if @path && @path != "-"
@io = File.open(@path, "a")
if @chuser || @chgroup
chuid = @chuser ? Supervisor.get_etc_passwd(@chuser).uid : nil
chgid = @chgroup ? Supervisor.get_etc_group(@chgroup).gid : nil
File.chown(chuid, chgid, @path)
end
else
@io = STDOUT
end
$log = Fluent::Log.new(@io, @level, @opts)
$log.enable_color(false) if @path
$log.enable_debug if @level <= Fluent::Log::LEVEL_DEBUG
end
ログファイルを退避してもログファイルが生成されなかった。ということは、
ここで生成したファイルハンドルをつかんだままなのでしょう。
しかし、68行~73行の reopen!
メソッドで、ログファイルを reopen しています。
def reopen!
if @path && @path != "-"
@io.reopen(@path, "a")
end
self
end
ということは、これを呼べばファイルハンドルを更新できるということになりますね。
では reopen!
はどこで呼ばれているのかというと、
install_main_process_signal_handlers
メソッドの、520行目。
trap :USR1 do
$log.debug "fluentd main process get SIGUSR1"
$log.info "force flushing buffered events"
@log.reopen!
USR1
シグナルを受け取った際に、reopen!
していました。
ということは、
運用を止めずにログをローテートしたい場合には、ログを退避後に、
test -s pid-file && kill -USR1 `cat pid-file`
というように、USR1シグナルでつついてやることでOK。