これは、なにをしたくて書いたもの?
以前、少しFluentdを触っていたのですが、Fluent Bitも1度確認しておいた方がいいかな、と思いまして。
今回、軽く試してみることにしました。
Fluent Bit?
Fluent Bitのオフィシャルサイトは、こちら。
GitHub - fluent/fluent-bit: Fast and Lightweight Log processor and forwarder for Linux, BSD and OSX
Fluent Bitとは、オープンソースかつ、マルチプラットフォームで動作するログプロセッシングツールです。
様々なデータソース、様々なデータフォーマットを扱うことができ、データの保証やルーティングを行いつつ、複数の
出力先にデータを渡すことができます。
What is Fluent Bit ? - Fluent Bit: Official Manual
A Brief History of Fluent Bit - Fluent Bit: Official Manual
これらの特徴を、低リソースで行えるところがポイントです。
Fluentdと、Fluent Bitの違いは以下のページに書かれています。
Fluentd & Fluent Bit - Fluent Bit: Official Manual
| Fluentd | Fluent Bit | |
|---|---|---|
| 対象とする環境 | コンテナ/サーバー | 組み込みLinux/コンテナ/サーバー |
| 実装言語 | CおよびRuby | C |
| メモリ | 〜40MB | 〜650KB |
| パフォーマンス | ハイパフォーマンス | ハイパフォーマンス |
| 依存関係 | いくつかのRuby Gem | 依存なし |
| プラグイン | 1,000以上のプラグインが利用可能 | 70ほどのプラグインが利用可能 |
| ライセンス | Apache License 2.0 | Apache License 2.0 |
Fluentdに比べ、より軽量なプロダクトだと言えそうです。その代わり、利用可能なプラグイン数はだいぶ減ることになりますね。
キーコンセプトは、以下のドキュメントに書かれているので見ておくとよいでしょう。
Key Concepts - Fluent Bit: Official Manual
Buffering - Fluent Bit: Official Manual
Data Pipeline - Fluent Bit: Official Manual
Fluentdと同じように、ログをレコードとして扱ってタグを振ったり、バッファリングの仕組み、Input、Filter、Outputなどの
パイプラインを組み上げることができます。
説明はこのあたりにして、使っていってみましょう。
環境
今回の環境は、こちらです。Ubuntu Linux 18.04 LTS。
$ uname -srvmpio Linux 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic
Fluent Bitをインストールする
では、Fluent Bitをインストールします。サポートされているプラットフォームを確認。
Supported Platforms - Fluent Bit: Official Manual
Ubuntu Linuxの場合、aptリポジトリがあるので、こちらを使います。
Ubuntu - Fluent Bit: Official Manual
GPG鍵のインポート。
$ wget -qO - https://packages.fluentbit.io/fluentbit.key | sudo apt-key add -
リポジトリの追加。
$ sudo sh -c 'echo "deb https://packages.fluentbit.io/ubuntu/bionic bionic main" >> /etc/apt/sources.list'
更新。
$ sudo apt update
「td-agent-bit」をインストールします。
$ sudo apt install td-agent-bit
バージョンを確認。
$ /opt/td-agent-bit/bin/td-agent-bit --version Fluent Bit v1.4.2
この時点では、systemd上はまだ有効になっていません。
$ sudo systemctl status td-agent-bit ● td-agent-bit.service - TD Agent Bit Loaded: loaded (/lib/systemd/system/td-agent-bit.service; disabled; vendor preset: enabled) Active: inactive (dead)
設定ファイルは、こちら。
$ ls -l /etc/td-agent-bit total 16 -rw-r--r-- 1 root root 4659 Apr 2 00:58 parsers.conf -rw-r--r-- 1 root root 45 Apr 2 00:58 plugins.conf -rw-r--r-- 1 root root 1002 Apr 2 00:58 td-agent-bit.conf
デフォルトの設定ファイルの内容を、確認してみましょう。設定ファイルに関するドキュメントは、こちら。
Configuring Fluent Bit - Fluent Bit: Official Manual
Configuration File - Fluent Bit: Official Manual
まずは、本体の設定ファイル。
$ grep -v '#' /etc/td-agent-bit/td-agent-bit.conf
[SERVICE]
Flush 5
Daemon Off
Log_Level info
Parsers_File parsers.conf
Plugins_File plugins.conf
HTTP_Server Off
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name cpu
Tag cpu.local
Interval_Sec 1
[OUTPUT]
Name stdout
Match *
Parserの定義。
/etc/td-agent-bit/parsers.conf
[PARSER]
Name apache
Format regex
Regex ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name apache2
Format regex
Regex ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>.*)")?$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name apache_error
Format regex
Regex ^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])?( \[client (?<client>[^\]]*)\])? (?<message>.*)$
[PARSER]
Name nginx
Format regex
Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
# https://rubular.com/r/IhIbCAIs7ImOkc
Name k8s-nginx-ingress
Format regex
Regex ^(?<host>[^ ]*) - (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*) "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" (?<request_length>[^ ]*) (?<request_time>[^ ]*) \[(?<proxy_upstream_name>[^ ]*)\] (\[(?<proxy_alternative_upstream_name>[^ ]*)\] )?(?<upstream_addr>[^ ]*) (?<upstream_response_length>[^ ]*) (?<upstream_response_time>[^ ]*) (?<upstream_status>[^ ]*) (?<reg_id>[^ ]*).*$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name json
Format json
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
# --
# Since Fluent Bit v1.2, if you are parsing Docker logs and using
# the Kubernetes filter, it's not longer required to decode the
# 'log' key.
#
# Command | Decoder | Field | Optional Action
# =============|==================|=================
#Decode_Field_As json log
[PARSER]
Name docker-daemon
Format regex
Regex time="(?<time>[^ ]*)" level=(?<level>[^ ]*) msg="(?<msg>[^ ].*)"
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
[PARSER]
Name syslog-rfc5424
Format regex
Regex ^\<(?<pri>[0-9]{1,5})\>1 (?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>[-0-9]+) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|-)) (?<message>.+)$
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
Time_Keep On
[PARSER]
Name syslog-rfc3164-local
Format regex
Regex ^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$
Time_Key time
Time_Format %b %d %H:%M:%S
Time_Keep On
[PARSER]
Name syslog-rfc3164
Format regex
Regex /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
Time_Key time
Time_Format %b %d %H:%M:%S
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
[PARSER]
Name mongodb
Format regex
Regex ^(?<time>[^ ]*)\s+(?<severity>\w)\s+(?<component>[^ ]+)\s+\[(?<context>[^\]]+)]\s+(?<message>.*?) *(?<ms>(\d+))?(:?ms)?$
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
Time_Key time
[PARSER]
# https://rubular.com/r/3fVxCrE5iFiZim
Name envoy
Format regex
Regex ^\[(?<start_time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)? (?<protocol>\S+)" (?<code>[^ ]*) (?<response_flags>[^ ]*) (?<bytes_received>[^ ]*) (?<bytes_sent>[^ ]*) (?<duration>[^ ]*) (?<x_envoy_upstream_service_time>[^ ]*) "(?<x_forwarded_for>[^ ]*)" "(?<user_agent>[^\"]*)" "(?<request_id>[^\"]*)" "(?<authority>[^ ]*)" "(?<upstream_host>[^ ]*)"
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
Time_Keep On
Time_Key start_time
[PARSER]
# http://rubular.com/r/tjUt3Awgg4
Name cri
Format regex
Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<message>.*)$
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L%z
[PARSER]
Name kube-custom
Format regex
Regex (?<tag>[^.]+)?\.?(?<pod_name>[a-z0-9](?:[-a-z0-9]*[a-z0-9])?(?:\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace_name>[^_]+)_(?<container_name>.+)-(?<docker_id>[a-z0-9]{64})\.log$
プラグイン。こちらは、空っぽです。
/etc/td-agent-bit/plugins.conf
[PLUGINS]
# Path /path/to/out_gstdout.so
こちらを変更して、Fluent Bitを簡単に試してみましょう。
TCP Input/Standard Output
最初は、TCPで待ち受けるInputに対して、結果を標準出力してみましょう。
使用するプラグインは、こちら。
TCP - Fluent Bit: Official Manual
Standard Output - Fluent Bit: Official Manual
設定は、このように変更。
/etc/td-agent-bit/td-agent-bit.conf
[SERVICE]
Flush 5
Daemon Off
Log_Level info
Parsers_File parsers.conf
Plugins_File plugins.conf
HTTP_Server Off
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name tcp
Listen 0.0.0.0
Port 5170
Format json
Tag tcp
[OUTPUT]
Name stdout
Match tcp
TCPのリッスンポートは、ドキュメントのサンプルに習って5170とします。
デフォルトで定義してあるInput/Outputの定義は、今回は削除しました。
インストール直後なので、サービスを有効化して起動。
$ sudo systemctl enable td-agent-bit $ sudo systemctl start td-agent-bit
起動時のログ。Fluent Bit自体のログの設定をしていないので、今回はjournalctlで確認します。
$ sudo journalctl -u td-agent-bit -f 〜省略〜 Apr 24 13:36:56 ubuntu1804.localdomain td-agent-bit[1952]: [2020/04/24 13:36:56] [ info] [input:tcp:tcp.0] listening on 0.0.0.0:5170 Apr 24 13:36:56 ubuntu1804.localdomain td-agent-bit[1952]: [2020/04/24 13:36:56] [ info] [sp] stream processor started
ncコマンドで動作確認。
$ echo '{"message": "Hello Fluent Bit!!"}' | nc localhost 5170
すると、ログにこんな感じで現れます。
Apr 24 13:37:36 ubuntu1804.localdomain td-agent-bit[1952]: [0] tcp: [1587735451.980938391, {"message"=>"Hello Fluent Bit!!"}]
OKそうですね。
Tail Input/Parser Filter/Standard Output
次は、デフォルトで定義されているParserを使って、ApacheのアクセスログファイルをTailで読み込んでみましょう。
利用するプラグインは、こちら。Standard Outputは省略。
Tail - Fluent Bit: Official Manual
Parser - Fluent Bit: Official Manual
とりあえず、Apacheをインストール。
$ sudo apt install apache2
parsers.confに定義されていた、こちらの設定を使います。
/etc/td-agent-bit/parsers.conf
[PARSER]
Name apache2
Format regex
Regex ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>.*)")?$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
Parserの定義をしたファイルを、SERVICEのParsers_Fileで指定することで、Parserの定義を利用できるようですね。
[SERVICE]
...
Parsers_File parsers.conf
Parser - Fluent Bit: Official Manual
で、設定したのがこちら。
/etc/td-agent-bit/td-agent-bit.conf
[SERVICE]
Flush 5
Daemon Off
Log_Level info
Parsers_File parsers.conf
Plugins_File plugins.conf
HTTP_Server Off
HTTP_Listen 0.0.0.0
HTTP_Port 2020
[INPUT]
Name tcp
Listen 0.0.0.0
Port 5170
Format json
Tag tcp
[INPUT]
Name tail
Path /var/log/apache2/access.log
Db /var/log/td-agent-bit/apache_access_log.db
Tag apache.access_log
[FILTER]
Name parser
Match apache.*
Key_Name log
Parser apache2
[OUTPUT]
Name stdout
Match tcp
[OUTPUT]
Name stdout
Match apache.*
Format json_lines
Apacheログに関する設定を抜き出すと、こんな感じです。
[INPUT]
Name tail
Path /var/log/apache2/access.log
Db /var/log/td-agent-bit/apache_access_log.db
Tag apache.access_log
[FILTER]
Name parser
Match apache.*
Key_Name log
Parser apache2
[OUTPUT]
Name stdout
Match apache.*
Format json_lines
Apacheのアクセスログをどこまで読み込んだかを保存するために、Dbを指定。これを指定しない場合は、Fluent Bitを
再起動するとファイルを最初から読み込んでしまいます。
Dbの実体はSQLite3で、データベースファイルを置くディレクトリは先に作成しておく必要があります。
$ sudo mkdir /var/log/td-agent-bit
タグは、TCPの時と別にしました。また、OutputのFormatはjson_linesにしてあります。
パースする際の「Key_Name」を指定しないといけないのですが、TailのデフォルトのKey名が「log」なようなので、
こちらを指定。
[FILTER]
Name parser
Match apache.*
Key_Name log
Parser apache2
Tail - Fluent Bit: Official Manual
Fluent Bitを再起動。
$ sudo systemctl restart td-agent-bit
Apacheへアクセス。
$ curl localhost/index.html
Fluent Bit側には、このようにパースされたログが出力されます。
Apr 24 15:25:18 ubuntu1804.localdomain td-agent-bit[3788]: {"date":1587741916.000000,"host":"127.0.0.1","user":"-","method":"GET","path":"/index.html","code":"200","size":"11173","referer":"-","agent":"curl/7.58.0"}
フォーマットは、JSONな感じになっていますね。
TCPの方は、どうだったでしょうか?
$ echo '{"message": "Hello Fluent Bit!!"}' | nc localhost 5170
こちらは、Formatを未指定だったので「msgpack」形式になっています。
Apr 24 15:32:38 ubuntu1804.localdomain td-agent-bit[3788]: [0] tcp: [1587742357.360168161, {"message"=>"Hello Fluent Bit!!"}]
とりあえず、初歩としてはこんなところでしょうか。