[2016-06-13-1] にも書いたとおり、こちらの PR で fluent-logger-ruby
を導入しました。
fluentd にも POST する by masutaka · Pull Request #40 · masutaka/masutaka-metrics

その時に、こんな問題に気づきました。

結論から言うと、Wrapper を作る必要はありません(一度作ってしまった
けど…
)。fluent-logger-ruby がいい感じに処理してくれます。

fluent-logger-ruby の基本的な使い方は、プログラム開始時に #new し
てインスタンスを保持し、あとは必要な時に #post を呼ぶだけです。

class Masutaka
  def initialize
    @fluent_logger = ::Fluent::Logger::FluentLogger.new
  end

  def hoge
    metrics = { 'field1' => 'hogehoge' }
    @fluent_logger.post('masutaka.metrics', metrics)
  end
end

プログラム稼働中に fluentd が restart または reload すると、
fluentd との接続は切れてしまいます。#post も false を返し送信して
くれません。でも、あまり気にする必要はありません。

なぜ気にする必要がないか、パターンをまとめました。登場するメソッド
は全て Fluent::Logger::FluentLogger class にあります。

プログラム稼働中に fluentd を再起動する

  1. プログラムが起動し、fluent-logger が new される
  2. fluentd が reload または restart される
  3. 直後に #post が呼ばれても、fluentd と通信ができず false を返す
  4. 再度 #post が呼ばれると、↑ここで送れなかったデータとともに fluentd に送信し、true を返す

コードはこちらになります(※)。
https://github.com/fluent/fluent-logger-ruby/blob/v0.5.1/lib/fluent/logger/fluent_logger.rb#L152-L181

fluent-logger は常にデータを @pending に入れて、fluentd に送信しま
す。失敗しても @pending は破棄されず、次回の #post に持ち越されます。

失敗したタイミングでコネクションを閉じる(@con.close)ため、次回
#send_data のこの条件に入り、fluentd と再接続されるという仕組みです。
https://github.com/fluent/fluent-logger-ruby/blob/v0.5.1/lib/fluent/logger/fluent_logger.rb#L185-L187

Monitor#synchronize で括ってあるので、マルチスレッドで同時実行
されないことも保証されてますね。

@pending にデータがある状態でプログラムを正常停止する

プログラム停止時に #close が実行されることが保証されているため、こ
ちらのケースも問題ありません。
https://github.com/fluent/fluent-logger-ruby/blob/v0.5.1/lib/fluent/logger/fluent_logger.rb#L88

Kernel.#at_exit は Ruby の組み込みメソッドです。正常終了時にブロッ
クが評価されます。

@pending にデータがある状態でプログラムを異常停止する

kill -9 などで異常停止したケースでは救えません。Kernel.#at_exit と
しても、UNIX プログラムとしても正しい動作です。

まとめ

これから fluent-logger-ruby をバリバリ使っていきます!