Fluentdの個人的なTips

# 1つのデータソースに対して複数の処理をしたい場合

[copy Output Plugin](https://docs.fluentd.org/v1.0/articles/out_copy)を使う
ひとつのcopyでエラーが発生した際に他のcopyにも影響が出るので、[fluent-plugin-copy_ex](https://github.com/sonots/fluent-plugin-copy_ex)の導入も検討しましょう

```config:td-agent.conf

<source>
  @type tail
  tag qiita.a
  path /var/log/hogehoge.log
</source>

<match **>
  @type copy
  <store>
    # 処理1
    @type file
    path /var/log/fluent/myapp1
    ...
  </store>
  <store>
    # 処理2
    @type s3
    ...
  </store>
  <store>
    # 処理3
    @type forward
    ...
  </store>
</match>
```

# 共通処理の振り分け
若干複雑になるが、ソースが2種類あって、タグが`qiita.a`だけに対して、特別な処理（@type file処理）をかけたい
それ以外は共通(s3, forward)で処理したい時に以下のように設定しがちですが、
残念ながら`qiita.a`は`match **`で処理されない

※[match順序](https://docs.fluentd.org/v0.12/articles/config-file#match-order)

```config:td-agent.conf

<source>
  @type tail
  tag qiita.a
  path /var/log/hogehoge.log
</source>
<source>
  @type tail
  tag qiita.b
  path /var/log/fugafuga.log
</source>

<match qiita.a>
  @type copy
  <store>
    # 処理1
    @type file
    path /var/log/fluent/myapp1
    ...
  </store>
</match>

# qiita.aにマッチングする処理は↓に来ない
<match **>
  @type copy
  <store>
    # 処理2
    @type s3
    ...
  </store>
  <store>
    # 処理3
    @type forward
    ...
  </store>
</match>
```

なので、めんどくさいですが、`match qiita.a`に処理2と処理3を定義するしかない
レコードをcopyしてからそれぞれに対してlabelを付ければ、冗長な設定しなくても済むのか？

```config:td-agent.conf

<source>
～省略～
</source>

<match qiita.a>
  @type copy
  <store>
    # 処理1
    @type file
    path /var/log/fluent/myapp1
    ...
  </store>
  <store>
    # 処理2
    @type s3
    ...
  </store>
  <store>
    # 処理3
    @type forward
    ...
  </store>
</match>

<match **>
～省略～
</match>
```

# Filterはmatchの前

filterの処理は各matchの前で定義すること
**matchのあとだと適用されない**

https://docs.fluentd.org/configuration/config-file#note-on-match-order

```config:td-agent.conf

# access
<filter myapp.access>
  @type record_transformer
  <record>
    host_param "#{Socket.gethostname}"
  </record>
</filter>
<filter myapp.access>
  @type record_transformer
  <record>
    host_param2 "#{Socket.gethostname}"
  </record>
</filter>
<match myapp.access>
  @type file
  path /var/log/fluent/access
</match>

# error
<filter myapp.error>
  @type record_transformer
  <record>
    host_param "#{Socket.gethostname}"
  </record>
</filter>
<match myapp.error>
  @type file
  path /var/log/fluent/error
</match>

```

# ログの種類によって保存先を変更したい

[fluent-plugin-forest](https://github.com/tagomoris/fluent-plugin-forest)を用いるか、[label](https://docs.fluentd.org/v1.0/articles/routing-examples#input--%3E-filter--%3E-output-with-label)を活用する

forestを用いたほうが、設定が簡素化してコードの可読性が高まります

## forest

sourceで設定されているタグ`qiita.ms`や`qiita.aws`がそれぞれ`tag_parts[0]=qiita`と`tag_parts[1]=(ms or aws)`になる
設定の簡素化が図れる

```config:td-agent.conf

<source>
  @type tail
  tag qiita.ms
  path /var/log/qiita/ms.log
</source>
<source>
  @type tail
  qiita.aws
  path /var/log/qiita/aws.log
</source>

<match qiita.**>
  @type forest
  subtype file
  <template>
    path /var/log/after/${tag_parts[0]}/${tag_parts[1]}.log
  </template
</match>

```


### forestを使わない場合

最新版(1.9.3)では、forestプラグインを使わずにタグをファイル名として利用できます
**[重要]bufferのチャンクキーを必ず設定しなければならない。ただし、buffer内のpathでは展開されない**ので、その場合はforestを使うしかないようです。
**\${tag_parts[n]} → \${tag[n]}**に変わっているので、ご注意！

https://docs.fluentd.org/configuration/buffer-section#tag

```config:fluentd.config

<match qiita.**>
  @type file
  path /hoge/${tag[0]}/${tag[1]}
  <buffer tag>
    
  </buffer>
</match>
```

## Label
sourceとmatchが一致するLabelで処理が行われる

```config:td-agent.conf

<source>
  @type tail
  @label @MS
  path /var/log/qiita/ms.log
</source>
<source>
  @type tail
  @label @AWS
  path /var/log/qiita/aws.log
</source>

<label @MS>
  <match **>
    @type file
    path /var/log/after/qiita/ms.log
  </match>
</label>
<label @AWS>
  <match **>
    @type file
    path /var/log/after/qiita/aws.log
  </match>
</label>
```


# タグによってパラメータ値を上書き

お馴染みの[fluent-plugin-forest](https://github.com/tagomoris/fluent-plugin-forest)を用いる
caseセクションでtemplate内のパラメータを上書きすることができる

```config:td-agent.conf

<source>
  @type tail
  @label @MS
  path /var/log/qiita/ms.log
</source>
<source>
  @type tail
  @label @AWS
  path /var/log/qiita/aws.log
</source>

<match qiita.**>
  @type forest
  subtype forward
  <template>
    send_timeout 60s
    recover_wait 60s
    require_ack_response

    <server>
      host 123.123.123.1
      port 2444
    </server>

    <case qiita.ms>
      <server>
        host 22.22.22.2
        port 2555
      </server>
    </case>
    <case qiita.aws>
      send_timeout 120s
      <server>
        host 33.33.33.3
      </server>
    </case>
  </template>
</match>

```

# 特定のログを削除する

アクセスログでELBからの死活監視ログをログ退避時に削除することで地味ながら容量削減につながります
[fluent-plugin-ignore-filter](https://github.com/bungoume/fluent-plugin-ignore-filter)を用います

`ELB-HealthChecker`が含まれていたなら、その行を削除する

```config:td-agent.conf

<filter **>
  @type ignore
  regexp1 message ELB-HealthChecker
</filter>
```