fluent-bit には Lua スクリプトでfilterできるプラグインがあります。 これを使うと、下記のようなことができます。
- recordに情報を追加する
- 特定の条件にマッチしたrecordをフィルタする
- record内の特定の情報を削除する
[:contents]
fluent-bitにはLuaスクリプトのパスと、スクリプトに記載されている関数名を伝える必要があります。 たとえば、下記の例は、test.luaスクリプトをロードし、そこに含まれるtest_func関数を実行するという意味になります。
[INPUT]
Name dummy
Tag test
Dummy {"foo":"bar"}
[FILTER]
Name lua
Match *
script ./test.lua
call test_func
[OUTPUT]
Name stdout
Match *
Fluent-bitのLuaは数値型としてdoubleを使用しています。 そのため、下記のような問題が発生する可能性があります。
- 整数型のデータが浮動小数点型に変更される
- 丸め誤差が発生する
前者については、Type_int_key
というプロパティを指定することで、フィルタ後の値を再度整数型に変更してくれるようになります。
https://docs.fluentbit.io/manual/pipeline/filters/lua#number-type
後者については、良い解が思いついていません。パッチをお待ちしております。
下記のように引数と戻り値がそれぞれ3つずつ必要です。
function test_func(tag, timestamp, record)
-- something to do
return ret, timestamp, new_record
end
fluentdのeventを構成するtag, timestampとLuaの連想配列形式のrecordが与えられ、戻り値としてfilter結果を示すretとtimestamp、そしてrecordを返却します。 ここで、retはfilter結果に応じて、下記のいずれかを返す必要があります。
filter結果 | retの値 | 備考 |
---|---|---|
削除した | -1 | 不要なeventをフィルタリングする用途 |
何も変更しなかった | 0 | |
recordとtimestampを変更した | 1 | |
recordのみ変更した | 2 | v1.4.3より対応。timestampの丸め誤差を防止するための機能。 |
それでは使用例を紹介していきます。
フィルタした時刻を保持したい場合には下記のように行います。
test.lua:
function test_func(tag, timestamp, record)
new_record = record
new_record["filterd_time"] = os.time()
new_record["filterd_date"] = os.date()
return 2, timestamp, new_record
end
{"foo"=>"bar"}
{"filterd_date"=>"Sun May 31 09:10:59 2020", "foo"=>"bar", "filterd_time"=>1590883859.000000}
tagというkey名でtagの文字列を追加するスクリプトです。
test.lua:
function test_func(tag, timestamp, record)
new_record = record
new_record["tag"] = tag
return 2, timestamp, new_record
end
test.conf:
[INPUT]
Name dummy
Tag test
Dummy {"foo":"bar"}
[FILTER]
Name lua
Match *
script ./test.lua
call test_func
[OUTPUT]
Name stdout
Match *
{"foo"=>"bar"}
{"foo"=>"bar", "tag"=>"test"}
"tag"=>"test"
が付与されています。
record内の一部ペアを消去する例です。
test.conf:
[INPUT]
Name dummy
Tag test
Dummy {"important":"value", "drop":"value"}
[FILTER]
Name lua
Match *
script ./test.lua
call test_func
[OUTPUT]
Name stdout
Match *
test.lua:
function test_func(tag, timestamp, record)
if record["drop"] == nil then
return 0, timestamp, record
end
new_record = record
new_record["drop"] = nil
return 2, timestamp, new_record
end
{"important"=>"value", "drop"=>"value"}
{"important"=>"value"}
"drop":"value"
というペアが消えています。
例えば不要なデータ通信を行わないように、record内に特定のkeyが含まれていた場合にそのrecord全体を捨てるユースケースがあるかと思います。
下記は、"drop" というkeyが含まれている場合にrecord全体を捨てる例になります。
[INPUT]
Name dummy
Tag test
Dummy {"important":"value"}
[INPUT]
Name dummy
Tag test
Dummy {"drop":true}
[FILTER]
Name lua
Match *
script ./test.lua
call test_func
[OUTPUT]
Name stdout
Match *
test.lua:
function test_func(tag, timestamp, record)
key = "drop"
if record[key] ~= nil then
return -1, timestamp, record
end
return 0, timestamp, record
end
{"important"=>"value"}
{"drop"=>true}
{"important"=>"value"}
{"drop":true}
というrecordが出力されなくなるかと思います。
test.conf
[INPUT]
Name dummy
Tag test
Dummy {"foo":"bar"}
[FILTER]
Name lua
Match *
script ./test.lua
call test_func
[OUTPUT]
Name stdout
Match *
test.lua:
function test_func(tag, timestamp, record)
new_record = record
if record["foo"] == nil then
return 0, timestamp, new_record
end
new_record["hoge"] = record["foo"]
new_record["foo"] = nil
return 2, timestamp, new_record
end
{"foo"=>"bar"}
{"hoge"=>"bar"}
"foo"というkeyが"hoge"に変わっています。
http://nokute.hatenablog.com/entry/2020/05/31/095431 からミラーしました。