LoginSignup
4
5

More than 5 years have passed since last update.

fluent-logger-rubyのbufferingを調べてみたよ

Posted at

概要

SMTPでメッセージ転送していた時代では、localhostにSMTPサーバを立てて、そいつにスプール(=buffering)させてました
これはプログラムから直接SMTPサーバ接続する場合にSMTPサーバが落ちてるとそこで処理がブロックされてしまうため、擬似的な非同期化をするための古の知恵でした

Fluentdはlocalhostにfluentdを立てる必要があるのか?という素朴な疑問を調査していたら、結局fluent-logger-rubyの実装を調べるということになったので、それのメモ

TL;DR

  • fluent-logger-ruby自体にbuffering&retry機構が入っている
    下記の仕様でOKならlocalhostにFluentdは不要
  • bufferサイズは8MB (8,388,608)
  • オーバーフローするとbufferの中身はすべて削除
  • retryあるよ

※すべてのfluent-loggerを調べていません。なので、言語実装によってbuffering機構が入っていない・bufferサイズが違うといった事があるかも

Bufferオーバーフロー

Bufferオーバーフローするとbufferの中身は全て消えてしまいます

ただ、その前にFluent::Logger::FluentLogger.new 時に指定したbuffer_overflow_handler をinvokeできる機構があります

Bufferサイズ

Fluent::Logger::FluentLogger::BUFFER_LIMIT を上書きすればサイズ変更可能(Rubyがwarning出すけどね)

retry回数と間隔

(13回で打ち止め、右は間隔)

1   0.5s
2   0.8s
3   1.1s
4   1.7s
5   2.5s
6   3.8s
7   5.7s
8   8.5s
9   12.8s
10  19.2s
11  28.8s
12  43.2s
13  64.9s

検証コード

require "fluent-logger"
require "pp"
trap(:INT) { exit }

# すぐオーバーフローさせたかったので小さいサイズにしている(rubyにワーンって言われるよ)
Fluent::Logger::FluentLogger.const_set(:BUFFER_LIMIT, 100)

class BufferOverflowHandler
  attr_accessor :buffer
  def flush(messages)
    @buffer ||= []
    MessagePack::Unpacker.new.feed_each(messages) do |msg|
      @buffer << msg
    end
    pp @buffer
  end
end

handler = Proc.new { |messages| BufferOverflowHandler.new.flush(messages) }
logger = Fluent::Logger::FluentLogger.new("debug", host: "localhost", port: 24224, buffer_overflow_handler: handler)
loop {
  p Time.now.to_s
  logger.post("a", {any: "#{Time.now.to_s}"})
  sleep 1
}

結果

$ ruby testing-fluent-logger.rb 
fluent-logger.rb:7: warning: already initialized constant Fluent::Logger::FluentLogger::BUFFER_LIMIT
/home/ma2shita/f/vendor/bundle/ruby/2.3.0/bundler/gems/fluent-logger-ruby-c94649a8468f/lib/fluent/logger/fluent_logger.rb:27: warning: previous definition of BUFFER_LIMIT was here
E, [2016-05-10T14:19:34.987988 #6665] ERROR -- : Failed to connect fluentd: Connection refused - connect(2) for "localhost" port 24224
E, [2016-05-10T14:19:34.988044 #6665] ERROR -- : Connection will be retried.
"2016-05-10 14:19:34 +0900"
"2016-05-10 14:19:35 +0900"
"2016-05-10 14:19:36 +0900"
E, [2016-05-10T14:19:36.989794 #6665] ERROR -- : FluentLogger: Can't send logs to localhost:24224: Connection refused - connect(2) for "localhost" port 24224
[["debug.a", 1462857574, {"any"=>"2016-05-10 14:19:34 +0900"}],
 ["debug.a", 1462857575, {"any"=>"2016-05-10 14:19:35 +0900"}],
 ["debug.a", 1462857576, {"any"=>"2016-05-10 14:19:36 +0900"}]]
"2016-05-10 14:19:37 +0900"
"2016-05-10 14:19:38 +0900"
"2016-05-10 14:19:39 +0900"
E, [2016-05-10T14:19:39.993584 #6665] ERROR -- : FluentLogger: Can't send logs to localhost:24224: Connection refused - connect(2) for "localhost" port 24224
[["debug.a", 1462857577, {"any"=>"2016-05-10 14:19:37 +0900"}],
 ["debug.a", 1462857578, {"any"=>"2016-05-10 14:19:38 +0900"}],
 ["debug.a", 1462857579, {"any"=>"2016-05-10 14:19:39 +0900"}]]
"2016-05-10 14:19:40 +0900"
"2016-05-10 14:19:41 +0900"
"2016-05-10 14:19:42 +0900"

何が言いたいかというと

Fluentdって本体だけでなくて、それを取り巻くツール類もすごいよ!

4
5
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
4
5