多くのFluentdのプラグインを見てきて知見が増えてきたのでまとめます。
config_sectionを使っていない
Fluentdのプラグインでは、configure
メソッド内で設定を自力で解釈することによりconfig_section
やconfig_param
で定義していない設定値も扱えるようになっています。
以下のような設定ファイルを
<source>
@type sample
user hoge
pass secret_passowrd
<pattern>
name foo
</pattern>
<pattern>
name bar
</pattern>
</source>
次のコードで自力で解釈することができます。
def configure(conf)
super
@patterns = conf.select {|element| element.name == "pattern" }
@user = conf["user"]
@pass = conf["pass"]
end
このように自力で解釈すると、テストも書かなければならないし、間違いも発生しやすくなるので以下のように、Fluentdの本体でよくテストされているconfig_section
とconfig_param
を組み合わせて使いましょう。config_section
とconfig_param
を使うと設定を宣言的に書くことができて、とてもわかりやすくなります。その上、fluent-plugin-config-formatというコマンドでMarkdownやJSONで出力することができます。desc
を使って説明も加えておくと、fluent-plugin-config-formatでも説明が出力されて便利です。
config_section :pattern, param_name: "patterns", multi: true do
desc "name for pattern"
config_param :name, :string
end
desc "user name for login"
config_param :user, :string
desc "password for login"
config_params :pass, :string, secret: true
def configure(conf)
super
# 何か追加の処理
end
config_paramのarrayを使っていない
<source>
@type github-activities
users ashie,cosmo0920,kenhys,kou
</source>
上記のような設定を以下のようなコードで、配列化して使っているプラグインがありました。
desc "user names e.g. user1,user2,user3"
config_param :users, :string, default: ""
def configure(conf)
super
@users = @users.split(",").map(&:strip)
end
これは以下のように書き換えることができます。
desc "user names e.g. user1,user2,user3"
config_param :users, :array, default: [], value_type: :string
def configure(conf)
super
end
config_paramのenumを使っていない
<source>
@type groonga
protocol http
# ...
</source>
上のような設定を次のようなコードでパースして使用しているプラグインがありました。
config_param :protocol, default: :http do |value|
case value
when "http", "gqtp", "command"
value.to_sym
else
rails Fluent::ConfigError, "must be http, gqtp or command: <#{value}>"
end
end
def configure(conf)
super
# @protocol を使う
end
これは以下のように書き換えることができます。
config_param :protocol, :enum, list: [:http, :gqtp, :command], default: :http
def configure(conf)
super
# @protocol を使う
end
書き換えることで、コードがすっきりしました。
秘密の値をsecretにしていない
<match dummy.log>
@type honeycomb
writekey very-secret-key
# ...
</match>
パスワードやAPIキーなどの秘密にしておきたい情報を設定ファイルに書かせるときは、secret
オプションを付けましょう。
secret
オプションをtrue
にするとFluentdの起動時に表示されるダンプなどで値がマスクされます。
config_param :writekey, :string, secret: true
以下のようにsecret
オプションを忘れてしまうと、Fluentd起動時のダンプなどにそのまま出力されてしまうので、バグ報告などのときにユーザーが自分でマスクしなければなりません。
config_param :writekey, :string
必須チェックを自分でしている
config_param :tag, :string, default: nil
def configure(conf)
super
raise Fluent::ConfigError, "tag is required" unless @tag
end
上のように必須の値のデフォルト値をnil
にして、自分でチェックしているコードをたまに見かけます。
下のようにデフォルト値を省略するとその設定は必須になり、Fluentd起動時にチェックが実行されます。
config_param :tag, :string
def configure(conf)
super
end
desc を書いていない
config_param :tag, :string
desc
を書くとfluent-plugin-config-formatというコマンドで、説明を見やすくフォーマットしたものを出力することができます。これはREADMEに設定の説明を書くときに使うととても便利です。
desc "tag for records"
config_param :tag, :string
まとめ
Fluentdで用意されている機能を活用して、メンテナンスを続けやすいプラグインを開発しましょう。