🌟

Fluentdのoutput pluginを作ってみた

2025/01/22に公開

作ったもの

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 Developmentlib/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関数内で書き込めなかった際のエラー処理がよくわかってないのでわかったら記述したい

Plugin作成において参考にしたサイト

Discussion