fluentd の filter_grep を試してみました。
テスト環境は以下のとおり。
[root@node01 ~]# cat /etc/redhat-release CentOS release 6.7 (Final) [root@node01 ~]# cat /etc/sysconfig/i18n LANG="ja_JP.UTF-8"
試した fluentd の設定は以下のとおり。filter_grep に日本語を使用してみました。
"致命的" という文字列を含む行だけアウトプットするようにしています。
## File input <source> type tail format none path /tmp/dummy.log tag local.dummy </source> ## Filter <filter local.dummy> type grep regexp1 message 致命的 </filter> ## File output (/var/log/td-agent/td-agent.log) <match local.**> type stdout </match>
しかし、期待に反して、grep のキーワードに日本語を使用するとうまくいきません。
/var/log/td-agent/td-agent.log に以下のようなエラーがでます。
2016-03-12 12:43:59 +0900 [warn]: failed to grep events error_class=Encoding::CompatibilityError error="incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)"
これは、異なる文字コードの文字列で正規表現処理をしたことが原因のようです。
in_tail が使用する文字コードは、"ASCII-8BIT" ですが、grepのキーワードは "UTF-8" です。
in_tail と filter_grep の相性が悪いみたい。
しかし、どうしても、grep のキーワードに 日本語を使用したかったので、 filter_grep を修正してみました。
修正内容
- オリジナルの filter_grep を別名でコピーして修正し、新しいプラグインを作成する。
- 新しいプラグイン名は ngrep とする。
- 正規表現処理時の文字コードをUTF-8にする。
修正手順
オリジナルの filter_grep をコピーします。 コピー先のファイル名は filetr_ngrep.rb とします。
/etc/td-agent/plugin ディレクトリが存在しない場合は、作成しておきます。
[root@node01 ~]# cp /opt/td-agent/embedded/lib/ruby/gems/2.1.0/gems/fluentd-0.12.20/lib/fluent/plugin/filter_grep.rb /etc/td-agent/plugin/filter_ngrep.rb
filter_ngrep.rb を修正してプラグイン名を変更します。
module Fluent class NGrepFilter < Filter Fluent::Plugin.register_filter('ngrep', self)
filter_ngrep.rb を修正して in_tail で入力したデータを UTF-8 に変換します。
def filter(tag, time, record) result = nil begin catch(:break_loop) do @regexps.each do |key, regexp| throw :break_loop unless ::Fluent::StringUtil.match_regexp(regexp, record[key].to_s.force_encoding('UTF-8')) end @excludes.each do |key, exclude| throw :break_loop if ::Fluent::StringUtil.match_regexp(exclude, record[key].to_s.force_encoding('UTF-8')) end
filter_ngrep の動作確認
/etc/td-agent/td-agent.conf の設定は以下のとおり。
type で ngrep を指定します。
他の使い方は、filter_grep と同じです。
<filter local.dummy>
type ngrep
regexp1 message 致命的
</filter>
設定変更後、以下のようにして動作を確認しました。
/var/log/td-agent/td-agent.log に "致命的" を含む行だけ出力されたので、うまくいったようです。
[root@node01 ~]# service td-agent restart Restarting td-agent: [ OK ] [root@node01 ~]# echo "xxxxxxx" >> /tmp/dummy.log [root@node01 ~]# echo "xxxxxxx" >> /tmp/dummy.log [root@node01 ~]# echo "xxxx致命的xxxx" >> /tmp/dummy.log [root@node01 ~]# echo "xxxx致命的xxxx" >> /tmp/dummy.log [root@node01 ~]# echo "xxxxxxx" >> /tmp/dummy.log [root@node01 ~]# echo "xxxxxxx" >> /tmp/dummy.log [root@node01 ~]# tail /var/log/td-agent/td-agent.log type ngrep regexp1 message 致命的 </filter> <match local.**> type stdout </match> </ROOT> 2016-03-12 12:54:15 +0900 [info]: following tail of /tmp/dummy.log 2016-03-12 12:54:29 +0900 local.dummy: {"message":"xxxx致命的xxxx"} 2016-03-12 12:54:31 +0900 local.dummy: {"message":"xxxx致命的xxxx"} [root@node01 plugin]#