Fluentdのoutput pluginを作ってみた
作ったもの
fluent-plugin-arango-http-api
Fluentdを利用してArangoDBにログを流すためのout plugin。起動時にCollectionがなかったら作成&インデックスも作成する
作った経緯
環境原因
関わったプロジェクトでArangoDBにFluentを利用してデータを流してたのだけど、その環境作成時に依存関係がなかなかにややこしかった(私がたまたま作った環境?が奇跡的なものだった)ので、今後同じことをするときに楽したいため
※使ってたのはfluent-plugin-arango
容易さ
使ったライブラリのソース見たら簡単そうだったのでruby知らない私でもなんとかなりそうってことでいつかは作ろうとは思ってた(そして数年後なんですが)
ライブラリが非サポート?
ArangoDBのruby用driverが公式から提供されてたような気がしてたのだけどいつの間にか消えてたのでHTTP APIを使った実装で開発
※fluent-plugin-arangoが使ってたAshikawaCoreのが公式だったと思うんだけどGitHub消えてる
開発環境
Docker構築
FROM fluent/fluentd:v1.17-1
USER root
RUN apk update && apk add git
RUN gem install rake
RUN gem install test-unit
RUN gem install mocha
USER fluent
services:
fluentd:
build: .
container_name: arangodb-fluentd-fluentd
volumes:
- ./fluentd/plugins:/fluentd/plugins
- ./fluentd/etc:/fluentd/etc
environment:
- FLUENTD_CONF=fluentd.conf
- RUBYGEMS_API_KEY=APIキー
command: ["fluentd", "-vv", "-c", "/fluentd/etc/fluentd.conf", "-p", "/fluentd/plugins/fluent-plugin-arango-http-api/lib/fluent/plugin"]
arangodb:
image: arangodb:latest
container_name: arangodb-fluentd-arangodb
ports:
- "8529:8529"
environment:
ARANGO_ROOT_PASSWORD: "password"
ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY: "2G"
volumes:
- ./arangodb3:/var/lib/arangodb3
- ./arangodb3-apps:/var/lib/arangodb3-apps
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match arango.test>
@type arango-http-api
include_tag_key false
include_time_key false
server arangodb-fluentd-arangodb
collection test2
index_fields a,b
user root
password password
</match>
プロジェクト作成
cd /fluentd/plugins
fluent-plugin-generate output arango-rururu3
苦戦したところ
rubyそもそも知らない
AI(Copilot)さまさま(気軽に聞けるのでありがたい限り)
rbファイル
Plugin Developmentにlib/fluent/plugin/<TYPE>_<NAME>.rb
と書いているがこの<NAME>
のところに_は使ってはいけない(プロジェクト作成コマンドでは-が_に変換されたファイルができてたのでいいのだろうと思ってたけど作ったplugin読み込まねぇって思ったが結局はこの命名規則のせいだった
confファイル
動作確認のためecho '{"a":"foo","b":"bar"}' | fluent-cat arango.test
でやっていたのだけど、confファイルを
<match **>
っていう指定にして全部対象とかにしてしまったのでバッファ・オーバーフローするわログ流れまくるわ大変w
msgpack
to_msgpack
はあるけどmsgpack_each
がないっていうエラーが出てきたので何故ないんだーって悩んでた。AIに聞いて
chunk.open do |io|
MessagePack::Unpacker.new(io).each do |tag, time, record|
# 処理
end
end
こんな感じにすれば良いことがわかった
今後
write
関数内で書き込めなかった際のエラー処理がよくわかってないのでわかったら記述したい
Discussion