概要
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って本体だけでなくて、それを取り巻くツール類もすごいよ!