Help us understand the problem. What is going on with this article?

fluentdで不要なログを取り除くfilterプラグインを作った

More than 3 years have passed since last update.

概要

Fluentd v0.12から利用できるFilterの機能を利用して、ログから正規表現でマッチしたものを取り除くfluent-plugin-ignore-filterを作りました。

grep-filterと何が違うのか

Fluentd v0.12以降には grep Filter Plugin という @sonots さんの
fluent-plugin-grep を取り込んだフィルタが組み込まれています。

こちらはログから正規表現で「マッチしたものを抽出する」プラグインです。

grepフィルタにはexcludeオプションがあるため、こちらを利用することで不要なログを取り除くことは一応可能です。

しかし、こちらのプラグインは「マッチしたログを通す」ためのフィルタのため、
マッチしたものを除外する目的で利用しようとすると、パース済みのログに対しand条件で除外できないという問題がありました。

例えば、ELBからのヘルスチェックだけ取り除きたいときに、path:/healthcheck.txtかつ client_ip:10.0.0.0/16 のログのみを除外するといった記述ができません。

<filter access.nginx.**>
  @type grep
  exclude1 path ^/healthcheck\.txt$
  exclude2 client_ip ^10\.0\.
</filter>

と記述するとexcludeがor条件になってしまうため、path:/healthcheck.txt すべてと client_ip:10.0.0.0/16 すべてが取り除かれてしまいます。

私が作成したignoreフィルタは「マッチしたものを取り除く」ので、grepフィルタとは逆の動作になります。

grep-pluginはもともとmatch向けのため、必要なものを通すという記法が理解しやすかったのだと思います。
しかし、filterプラグインは何重にも掛けることが出来るため、「必要なものを通す」を1つ書くよりは「不要なものを除く」記述を複数書くほうが理解しやすくなると思い、作成しました。

使い方

インストール

# for fluentd
$ gem install fluent-plugin-ignore-filter

# for td-agent2
$ sudo td-agent-gem install fluent-plugin-ignore-filter

記法

記法はgrepフィルタとほぼ同じです。
regexpN <key> <pattern> 全てにマッチしたもののうち、
excludeN <key> <pattern> 全てにマッチしないもの
を除外します。

具体例

ELBからのヘルスチェックだけ取り除きたい

ELBはVPCの中なのでclient_ipがprivate_ipなになる。
(client_ipにはx_forwarded_forの最後の値か、なければremote_ipが入っている設定)

<filter access.nginx.**>
  @type ignore
  regexp1 path ^/healthcheck\.txt$
  regexp2 client_ip ^10\.0\.
</filter>

syslogから特定のメッセージ以外のinfo|noticeを除外したい

corosync使ってるとcrmdがnoticeレベルで結構重要な情報を出すので
level:notice でもident:crmdかつ message:process_lrm_event〜 は通したいとき。

<filter alert.messages.**>
  @type ignore
  regexp1 level info
</filter>
<filter alert.messages.**>
  @type ignore
  regexp1 level notice
  exclude1 ident crmd
</filter>
<filter alert.messages.**>
  @type ignore
  regexp1 level notice
  regexp2 ident crmd
  exclude1 message ^process_lrm_event
</filter>

Filterは何重にも書けられるので便利ですね!

補足

  • Fluentdのfilter_grep.rb をかなり参考にさせてもらっています。 @sonots さんありがとうございます。
    • grep Filterも併用してわかりやすい記述にするのが良さそうです。
  • Rubyは初めて書いたので変なところがあるかもしれません。Pull-request歓迎です!

その他

  • 同様のプラグインはあるかもしれません。
    • 名称をexclude-filterにしようとしたら既に存在していました。(ただしfilter pluginではないようです。)
  • Filterプラグインはまだ数が少ないので、ネーミングルールが分かりませんでした。
    • 名称がFilterでもout pluginが多いですね。
  • ignoreのexcludeって分かりにくい気はしています。
    • 仕方ないですかね...
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away