td-agentで--use-v1-config


## v1とは何なのか

fluentdの0.10.50から導入された、新しい設定の書き方。

主な機能としては**rubyのコードが記述できる**というところに尽きるが、これが実に便利。
 
皆様使われているであろうと思われる、td-agentで使う際の方法をまとめる。

※旧設定をv0と呼ぶ

## td-agentのformatの互換性

--use-v1-configをサポートしているtd-agentは以下。(2014年12月17日現在)

|version|fluentdのversion|v0とのformat互換性|デフォルト|
|:---|:---|:---|:---|
|2.1.2 |0.10.57 |OK |v1 |
|2.1.1 |0.10.55 |OK |v1 |
|2.1.0 |0.10.53 |NG |v1 |
|1.1.21 |0.10.55 |OK |v0 |
|1.1.20 |0.10.50 |NG |v0 |


* td-agent2からはデフォルトがv1で起動
* v0互換性は完全互換ではないことに注意
* 1.1.1X系では対応していない(--use-v1-configは使えない)
* fluentd-0.10.55でv1でもv0との同じ設定で動作させることが出来るようになった。(それ以前のv1はリテラルのエスケープなど記述方法が異なっている。)

* が、[プラグインによっては](https://github.com/fluent/fluentd/issues/493)問題があるらしい(自分は今のところ遭遇していない)
* 余程の問題がない限りは2.1.2か1.1.21を使う方が無難だと思われる。


## td-agent2を使っていない場合の設定

td-agentが1.1.2X系を使っている場合、`/etc/sysconfig/td-agent`に以下のように記述するとv1で起動できる。

```/etc/sysconfig/td-agent
TD_AGENT_ARGS="${TD_AGENT_ARGS-/usr/sbin/td-agent --group td-agent --log /var/log/td-agent/td-agent.log --use-v1-config}"
```

group等は環境に合わせて設定する。

td-agentが1.1.1X系を使っている場合は使えないので[td-agent2にアップグレード](http://qiita.com/toyama0919/items/0859275b8635b2b64e08)しましょう。

## fluentdをv1で動かしたい

```bash
$ fluentd --use-v1-config
```

## よくありそうなユースケース、環境変数を設定ファイルの中に埋め込む

ちょっと何を言ってるかわからないと思うので、比較して実例を。

認証を伴う設定を書かなければいけない場合これまでは

```/etc/td-agent/td-agent.conf
<match hipchat.problem.**>
  type hipchat
  api_token hogehogetoken
  default_room 000000
  default_from fluentd
  default_color red
  default_notify 0
  default_format html
</match>
```

こう記述する必要があったが

```/etc/td-agent/td-agent.conf
<match hipchat.problem.**>
  type hipchat
  api_token "#{ENV['HIPCHAT_API_TOKEN']}"
  default_room 000000
  default_from fluentd
  default_color red
  default_notify 0
  default_format html
</match>
```

と記述できる。

hipchatのtokenを直接記述していたりするとソース管理がしにくいのはこれで解決！

## 認証情報、サーバー固有の設定等をどこに書くか？

認証情報の記述も`/etc/sysconfig/td-agent`に記述することで設定できる。
自分は認証情報の隠蔽はerbなどで生成を独自でやっていたが、

```/etc/sysconfig/td-agent
TD_AGENT_ARGS="${TD_AGENT_ARGS-/usr/sbin/td-agent --group td-agent --log /var/log/td-agent/td-agent.log --use-v1-config}"

export HIPCHAT_API_TOKEN="hogehogehogehogehogehogehogehogehogehogehogehogehogehoge"
export MYSQL_PASSWORD="fugafugafugafugafugafugafugafugafugafugafugafugafugafuga"
```

と書けば`td-agent.conf`から

```/etc/td-agent/td-agent.conf
<match hipchat.problem.**>
  type hipchat
  api_token "#{ENV['HIPCHAT_API_TOKEN']}"
  default_room 000000
  default_from fluentd
  default_color red
  default_notify 0
  default_format html
</match>
```

で環境変数を読み込める。

これは環境変数を読み込む一例だが、rubyのコードを記述できるので応用すれば色々出来る。

## rubyのコードを記述する例

↑で上げたrubyのコードを書けることを応用してみる。

文字列連結や簡単な条件分岐

```/etc/td-agent/td-agent.conf
<match hoge.file.**>
  type file
  path "#{ENV['HOME']}/test.log"
</match>

<match elasticsearch.**>
  type elasticsearch
  index_name "#{ENV['STAGE']}_index"
  type_name pageview
  host "#{ENV['STAGE'] == 'production' ? 'host01' : 'staging_host01' }"
  logstash_format false
  flush_interval 60s
  buffer_type file
  buffer_path /var/log/td-agent/buffer/elasticsearch.buf
</match>
```

極端な例だが以下の様なことも出来る。

```/etc/td-agent/td-agent.conf
<match hoge.file.**>
  type file
  path "#{require 'yaml'; YAML.load_file(ENV['RAILS_ROOT'] + '/config/config.yml')['path']}"
</match>
```

やり過ぎは程々に。

## plugin開発のv1

config_paramにArrayやHashが使えるようになっている。(v0でも使えるようになっていた！)


例えば以下の様なpluginが作ったとする。

```/etc/td-agent/plugin/out_hoge.rb
class Fluent::HogeOutput < Fluent::Output
  Fluent::Plugin.register_output('hoge', self)

  config_param :tags, :array
  config_param :user, :hash
  config_param :users, :array

  def initialize
    super
  end

  def configure(conf)
    super
    p @tags
    p @user
    p @users
  end

  def emit(tag, es, chain)
    es.each do |time, record|
    end
    chain.next
  end
end
```

config_paramの型がarrayとhashになっている。

設定はこんな感じ。

```/etc/td-agent/td-agent.conf
<match hoge.plugin.**>
  type hoge
  tags [ "java", "ruby" ]
  user { "id": 1, "name": "fuga", "mail_address": "test@gmail.com" }
  users [
    { "id": 1, "name": "fuga", "mail_address": "test@gmail.com" },
    { "id": 2, "name": "fuga2", "mail_address": "test2@gmail.com" },
    { "id": 3, "name": "fuga3", "mail_address": "test3@gmail.com" }
  ]
</match>
```

特筆すべきポイントは、
* 設定にjsonを記述している。(rubyの型ではない)
* 設定を改行して書くことが出来るためコードの見通しがよくなる。

あたりだろうか。

ただし、HashやArrayの中の値に変数は使えない(文字列として解釈された)

```/etc/td-agent/td-agent.conf
<match hoge.plugin.**>
  type hoge
  tags [ "#{ENV['LANGUAGE1']}", "#{ENV['LANGUAGE2']}" ]
  user { "id": 1, "name": "fuga", "mail_address": "test@gmail.com" }
  users [
    { "id": 1, "name": "fuga", "mail_address": "test@gmail.com" },
    { "id": 2, "name": "fuga2", "mail_address": "test2@gmail.com" },
    { "id": 3, "name": "fuga3", "mail_address": "test3@gmail.com" }
  ]
</match>
```

## まとめ
* v1最高

## 参考
* [The td-agent ChangeLog | Treasure Data](http://docs.treasuredata.com/articles/td-agent-changelog)
* [The td-agent2 ChangeLog | Treasure Data](http://docs.treasuredata.com/articles/td-agent2-changelog)
* [fluentd/ChangeLog at master · fluent/fluentd](https://github.com/fluent/fluentd/blob/master/ChangeLog)