Y-Ken Studio

新しもの好きのデータエンジニアが四方山話をお届けします。

Fluentdのタグ書き換えが捗る「tag_parts」プレースホルダを使ってみよう

Fluentdでログのちょっとした加工をする際に、タグの付け替えが必要です。
新しいタグを指定するか、先頭文字列の付け替えを行う手法が良く使われます。
しかしそれだけではかゆいところに手が届かず、もどかしい思いをされたことでしょう。
そんな時、タグをドットで分解した要素毎に分解して使えるプレースホルダが大活躍します。

この記事を読めば、これがなぜ今まで無かったのか不思議に感じる程です。
そう思えるほど便利な新機能、それでは早速紹介します。

プレースホルダとは

プレースホルダとは、一部のfluentdプラグインの設定値の中で使える変数です。
良く使われるプレースホルダとして次のようなものがあります。

  • ${tag}
  • __TAG__
  • {$tag_parts[n]}
  • __TAG_PARTS[n]__
  • ${hostname}
  • __HOSTNAME__

これはFluentdに届いたログを次のように加工する際にも活用できます。

  • ログを保存する際のファイルパスに使う
  • タグをドット区切りで分解した要素の一部でタグを再構成する

対応プラグイン

このプレースホルダに対応したプラグインは3つあります。

ユースケース紹介

プレースホルダの便利さはお分かりいただけたでしょうか。
それでは次に、具体的な例と共に解説します。

事例1:タグの順番変更

次のようにタグの順番を入れ替える際の設定例を紹介します。

  • 変更前: app.service1.action → 変更後: click.action.service1
  • 変更前: app.service2.action → 変更後: click.action.service2
# 設定例
<match app.*.*>
  type record_reformer
  tag click.${tag_parts[2]}.${tag_parts[1]}
</match>

さらに条件分岐付きで書き換えたいケースでは、次のようにします。

# 設定例
# member_typeの値がfooというレコードを捨てて、それ以外のレコードのタグの入れ替えを行う
<match app.*.*>
  type rewrite_tag_filter
  rewriterule1 member_type foo null
  rewriterule2 member_id .+ click.${tag_parts[2]}.${tag_parts[1]}
</match>

<match null>
  type null
</match>

事例2:タグの一部をファイル名に使う

次のようなタグの一部をディレクトリやファイル名に利用する例を次に説明します。
この時は、time_slice_outputオプションが使えるfluent-plugin-file-alternativeプラグインが便利です。

  • 変更前: app.service1.member_action → 変更後: /var/log/service1/action.20131217_18.log.gz
  • 変更前: app.service1.visitor_action → 変更後: /var/log/service2/action.20131217_18.log.gz
# 設定例
<match app.*.*>
  type forest
  <template>
    type file_alternative
    path /var/log/${tag_parts[1]}/${tag_parts[2]}.*.log
    time_slice_output %Y%m%d_%H
    compress gzip
  </template>
</match>

事例3: タグ毎にElasticsearchの書き込み先を分ける

ElasticsearchではMySQLで言うデータベースとテーブルのことをindex, typeと呼びます。
ここで行いたいことは、タグを元に書き込む先のindex, typeの分岐を行うことです。
https://github.com/tagomoris/fluent-plugin-forestを利用します。

  • 元のタグ: app.service1.member_action

    • 利用するindex: service1
    • 利用するtype: member_action
  • 元のタグ: app.service1.visitor_action

    • 利用するindex: service1
    • 利用するtype: visitor_action

これを行う設定例は次の通りです。forestプラグインプレースホルダを使えば簡単ですね。
remove_prefixでapp.を取り除いた後に、ドットで区切った要素の0番目をindexに、1番目をtypeに利用しています。

# 設定例
<match app.*.*>
  type forest
  subtype elasticsearch
  remove_prefix app.
  <template>
    host  localhost
    port  9200
    index_name ${tag_parts[0]}
    type_name  ${tag_parts[1]}
    flush_interval 5s
  </template>
</match>

なお、同様のことはfluent-plugin-forest + fluent-plugin-mysqlという組み合わせでも出来ます。

まとめ

プレースホルダの便利さは伝わりましたでしょうか。
未対応プラグインであっても、https://github.com/tagomoris/fluent-plugin-forestを挟めば全て対応するのが良いですね。
とても便利なので、是非お試しください!

以上、tag_partsプレースホルダの紹介でした。