fluentd まとめ (個人的備忘録)



#1.はじめに

fluentdを触ったので忘れないように備忘録として残しておきます。
*随時更新していくつもりでいます

#2. fluentdとは


- ログデータ収集管理ツール
- 多数のIoT機器からデータを収集し、処理を加えてS3などに保存することができる



#3.fluentdを使えるまでの設定

インストール

```
# td-agent 4
​​$ curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-bionic-td-agent4.sh | sh
```
バージョン確認

```
$ td-agent --version
```
設定ファイルの確認

```
$ sudo vim /etc/td-agent/td-agent.conf
```
起動

```
$ sudo systemctl start td-agent
```
状態確認

```
$ sudo systemctl status td-agent
```
ログの確認

```
$ curl -X POST -d 'json={"test":"hello fluentd"}' http://localhost:8888/debug.test
$ sudo vim /var/log/td-agent/td-agent.log 
or
$ sudo tail -n 1 /var/log/td-agent/td-agent.log
```
停止

```
$ sudo systemctl stop td-agent
```


#4.プラグイン

- fluentdでは、8つのプラグインがある。
- `Input`, `Parser`,`Filter`, `Output`, `Formatter`, `Storage`, `Service Discovery`, `Buffer`
- 「@type XXX」のXXXの部分だと思えば良い
- 以下で何個かピックアップする


###(1). Inputプラグイン


- `tail` : ファイルの末尾を読む

```
<source>
  @type tail
  path /var/log/httpd-access.log
  pos_file /var/log/td-agent/httpd-access.log.pos
  tag apache.access
  <parse>
    @type apache2
  </parse>
</source>
```


- `forward` : イベントストリームを受け取るためにTCPソケットをlistenする(他のfluentdからデータを受け付けるなど)

```
<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>
```


- `http` : HTTPリクエストを通してデータを受け取る

```
<source>
  @type http
  port 9880
  bind 0.0.0.0
  body_size_limit 32m
  keepalive_timeout 10s
</source>
```

- `sample` : テストイベントを生成、test, debugに役立つ
- `syslog` : UDP/TCPのsyslogプロトコル経由で取得する
- その他 `monitor_agent`, `exec`, `windows_eventlog`

###(2). Outputプラグイン
**■プラグインのタイプを指定(@type)**

- `file` : ログをファイルに書き出す

```
<match pattern>
  @type file
  path /var/log/fluent/myapp
  compress gzip
  <buffer>
    timekey 1d
    timekey_use_utc true
    timekey_wait 10m
  </buffer>
</match>
```

- `forward`: 他のfluentdに送信

```
<match pattern>
  @type forward
  send_timeout 60s
  recover_wait 10s
  hard_timeout 60s

  <server>
    name myserver1
    host 192.168.1.3
    port 24224
    weight 60
  </server>
  <server>
    name myserver2
    host 192.168.1.4
    port 24224
    weight 60
  </server>
  ...

  <secondary>
    @type file
    path /var/log/fluent/forward-failed
  </secondary>
</match>
```
*secondary : outputプラグイン内に記載することができ、リトライしても出力できなかったときに行う処理を記載
*例としては、サーバに接続できなかったため、ローカルファイルに書き込むなど


- `http`

```
<match pattern>
  @type http

  endpoint http://logserver.com:9000/api
  open_timeout 2

  <format>
    @type json
  </format>
  <buffer>
    flush_interval 10s  #ざっくりとした送信間隔だと思って良い(実際は違うが)
  </buffer>
</match>
```
*endpointでhttp postの先


- `copy` : 1つのソースを複数に送信するのに使用


```
<match pattern>
  @type copy
  <store>
    @type file
    path /var/log/fluent/myapp1
    ...
  </store>
  <store>
    ...
  </store>
  <store>
    ...
  </store>
</match>
```
*matchを2つ書いてしまうと先に記述した処理しか実行されないので、`copy` を使用する
*処理については、`<store> </store>`に記述
*fluentdは1つのイベントに対して、先にマッチするものがあると後のmatch句は効かない


- stdout:標準出力にログを吐き出す。デバックの処理に役立つ。
- s3 : 出力をAWSのS3に指定できる
- `kafka`, `exec`, `exec_filter`, `secondary_file`, `relabel`, `mongo`


###(3). Filterプラグイン

- `record_transformer` : ログを加工できる。JSONにデータ追加できる。

```
<filter foo.bar>
  @type record_transformer
  <record>
    hostname "#{Socket.gethostname}"
    tag ${tag}
  </record>
</filter>
```
*recordディレクティブの中に、フィールド名とその値をかく


- その他 : `parser`,`grep`




###(4). Parserプラグイン

- `regexp`
- `apache2`
- `apache_error`
- `nginx`
- `syslog`
- `json`
- `none`

###(5). Bufferプラグイン

- Bufferディレクティブは、Matchの中に記述する


- `memory` : バッファをメモリ上に保存。流量も流速も多い時に使用

```
<match pattern>
  <buffer>
    @type memory
  </buffer>
</match>
```

- `file`: バッファとしてファイルを使用。ログ欠損しないように


```
<match pattern1>
  <buffer>
    @type file
    path /var/log/fluent/foo.bar
  </buffer>
</match>
```
- `file_single`



#4.ディレクティブ



###(1).Sourceディレクティブ

- Inputの定義
- イベントの**受信方法**を指定
- 各source要素は、@typeパラメータでinputプラグインを指定
- 各sourceプラグインはfluentdのルーティングエンジンにイベントを投げている
- 複数の入力プラグインを指定できる






◆例①「localhostのTCPポート8888番からHTTPリクエストがきたら受信」

```
<source>
    @type http
    port 8888
    bind 0.0.0.0 #listenしているアドレス(bind 0.0.0.0 :すべてのアドレスから受け取る)
</source>
```




◆例② 「8888ポートにhttpリクエストきたデータにタグをつける」

```
<source>
    @type http
    port 8888
    bind 0.0.0.0
    tag test.error
</source>
```
◆例③「ファイルの末尾を読み込む」

```
<source>
  @type tail
  <parse>
    @type none
  </parse>
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/tmp/access.log.pos
</source>
```






###(2). Matchディレクティブ

- Outputの定義
- 受信したイベントをどのように処理するかを記述
- typeパラメータにoutputプラグインを設定
- インプットプラグインが出してきたJSONのデータをフィルタリングしたり、特定のキーの値を加工したり、別のファイルや標準出力へ出力したりする



◆例①「ログを標準出力に」

```
<match 条件式(tagの名前とか)>
    @type stdout 
</match>
```





###(3). Filterディレクティブ

- source要素とmatch要素の間に書く
- **matchの後だと適用されない**
- イベント処理をどのようにするか






##(4). Systemディレクティブ

このディレクティブで、fluentdのコアの部分の動作を決める
・`log_level`
・`suppress_repeated_stacktrace`
・`emit_error_log_interval`
・`suppress_config_dump`




##終わりに

メモ程度にまとめました。
fluentdを使用する機会は多いかと思うので使いこなせるようになりたいです。

##参考文献

- [Fluentdのバッファリングで抑えておくべき大事なポイント](https://zenn.dev/taisho6339/articles/b309562b0d4973)
- [fluentd公式ページ](https://docs.fluentd.org/)