クロスプラットフォームで動作し、オープンソースであるデータ収集ソフトウェアとしてFluentdがあります。 Fluentdはさまざまな用途にあわせてプラグインにより機能を拡張できます。 多くのプラグインが開発されているのは、要件を満たすべく新規にプラグインが開発される事例があるためです。 これまでもお客様の要望にあわせて、クリアコードでプラグインを開発した実績があります。
今回は、RuboCopをまだ導入していないプロジェクトにおいて、コードのリファクタリングの観点から "小さく"Fluentdに適用してみた事例を紹介します。
RuboCopを適用してみるきっかけ
きっかけとなったプルリクエストは次のものでした。
Fluentdのメンテナンスに関わっているクリアコードの藤田さんによるものです。 RuboCopでパフォーマンスの問題を見つけたのでフィードバックしたとのことを聞いて、RuboCopをそのうち使ってみたいと思っていたのを覚えています。1
Fluentdの2025年7月時点の最新版はv1.18.0ですが、次期バージョンのv1.19.0のリリースを近々控えています。
また、Fluentdをさまざまな環境で使いやすいようにパッケージとして開発・配布しているfluent-package
の最新版であるv6(今年の8月リリース予定)
に同梱する予定もあることから、このタイミングで投入してみることにしました。
どのように適用することにしたのか
RuboCopは次のようなカテゴリでRubyのコードをチェックしてくれます。
- Lint
- Style
- Gemspec
- Naming
- Layout
- Metrics
- Security
これに加えて、RuboCop Performance2というRuboCopのプラグインを導入すると、 パフォーマンスの観点から問題のある書き方を検出できます。
Fluentdは長期に渡ってメンテナンスされ続けているプロジェクトです(現在はクリアコードが開発を主導しています)。 したがって、すべてのカテゴリでチェックを有効にすると指摘箇所が膨大となり追従していくのにもそれなりのコストがかかってしまいます。
そこで、次のような方針で適用してみることにしました。
- 適用するのは、
Security
とPerformance
の2つのみにする(将来的には増やしていくことも検討する) Performance
については、実際にマイクロベンチマークによって効果を確認する(修正コミットメッセージにその結果を記録しておく。具体例は後述のプルリクエストを参照のこと)- RuboCopによる不適切な指摘に関しては明示的に設定で除外する
lib
ディレクトリ配下のFluentd本体のコードを優先し、test
配下のテストコードの修正に関する優先度は下げる
RuboCopによる指摘事項の反映
指摘事項をもとに、1つずつ切り出して修正していった成果は以下の通りです。
- robocop: reduce string to symbol conversion for performance
- rubocop: reduce string to symbol conversion for performance
- rubocop: reduce hash literals in loops for performance
- rubocop: reduce string to symbol conversion for performance (define_singleton_method)
- rubocop: reduce a regex match for performance
- rubocop: reduce every regex evaluation for performance
- rubocop: use yield without block
- rubocop test: reduce redundant merge!
- rubocop test: fix Performance/RedundantEqualityComparisonBlock
- rubocop test: reduce times.map call
- rubocop test: reduce map method chain
RuboCopによって指摘されたなかには、鵜呑みにして修正しないほうがよい場合もいくつかありました。 その場合は、Fluentd向けのRuboCopの設定で明示的に除外するようにしました。
RuboCopの問題については、rubocop-jpなどでも議論がなされていることがあります。 参考にしてみるとよいかもしれません。
なお、一度修正済みだったものの、その後のプルリクエストで似たような誤りが再び混入した事例があったため、GitHubのアクションで プルリクエストをチェックするワークフローを導入しました。しくみで防ぐようにするのもとても大事ですね。
おわりに
今回はRuboCopを"小さく"適用したFluentdの事例を紹介しました。
より良いRuboCopの設定については、RubyKaigi 2022のThe Better RuboCop World to enjoy Rubyという セッションの動画が公開されているので、そちらを参考にするのがよいでしょう。
クリアコードはFluentdのサポートサービスを行っています。 Fluent Packageへのアップデート支援や影響のあるバグ・脆弱性のレポートなどのサポートだけでなく、 お客様の要望に応じて新規プラグインの開発も行っています。
詳しくはFluentdのサポートサービスをご覧いただき、お問い合わせフォームよりお気軽にお問い合わせください。
最近 Xアカウントfluentd_jpでFluentdのお役立ち情報の発信をはじめました。ぜひこれを機会にフォローしてください。
-
FluentdのissueでもRuboCopを導入しようという提案はありましたが、実際に手を動かしてルールを策定するプロセスは進んでいませんでした。 ↩
-
過去のククログでもOSS開発に参加する方法として言及があります。 ↩