くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Fluent Bitに入門してみた

システムの一部をCloud RunからVPS化しようとしてるけど、
ログ周りどうしようと悩んでいたときに、
いろいろ試してみたときの備忘録(*´ω`*)

Fluent Bitを使って、VPS上のログを
GCPのCloud Loggingに送信したい。。

長くなったので、とりあえず、Fluent Bitの入門編

FluentdとFluent Bit

統合ログ基盤であるFluentdエコシステムのサブプロジェクト。

Fluent Bitのほうが軽量で必要な設定が少ないが、
Fluentdよりもプラグイン数やカスタマイズ性は下がるっぽい。

公式ドキュメントはこのあたり。

Fluent Bitとは

統合ログ基盤といわれるように、

  • ファイルにあるログの収集
  • 加工や絞り込み
  • ログの転送や別ファイルへの集約

などをしてくれる感じ。

今回は、以下のことをしたい感じ。

  • VPS上のログを収集して、
  • GCP Cloud Loggingに転送

Cloud RunやCloud Functions for Firebaseを使っているので、
VPS上のアプリケーションログも今までと同様に、
Cloud Logging上ですべてのログを確認できるようにし、
Cloud Monitoringでアラートを飛ばすとかをしたい。。

Fluent Bitの構成や仕組み

構成や仕組みを理解するにはこのあたり。
概念や用語とか説明されている。

用語

Event(or Record)

Fluent Bitが収集・受信するデータのこと。
ログファイルにある1行のログが1Eventに相当する。

Eventのformat的にはこんな感じで、

[[TIMESTAMP, METADATA], MESSAGE]
  • TIMESTAMP: 日時(SECONDS.NANOSECONDS形式)
  • METADATA: Eventのメタデータ
  • MESSAGE: Eventの中身(ログデータなど)

の3つの要素で構成されている。

Tag

ログの絞り込みなどに使われる、EventにつけるTag。
アプリ名とか処理名とかをタグにして、
特定のアプリのみ処理・転送をするとかに使う感じ。

処理の流れ

流れはこんな感じっぽい。
必須なのはInput/Outputの2つで、
独自のLogFormatならParserも必要な感じ。

  • Input ... 収集するログファイルの場所とかを指定
    • Parser ... ログを解析して日時とかの場所を指定
  • Output ... ログを転送する宛先を指定

それぞれ、Inputのプラグインみたいな感じで、
プラグインが用意されているので、設定などは各プラグインに従う。

Fluent Bitのインストール

いろんな環境へのインストールができるっぽい。

Ubuntuへのインストール

UbuntuへのインストールはこれだけでOK

curl https://raw.githubusercontent.com/fluent/fluent-bit/master/install.sh | sh

スクリプトの中身は手動と同じ感じのことをしている。

  • GPG keyの取得・保存
  • sources listsの更新
  • apt update & apt install fluent-bit

基本的な操作や設定ファイルはこんな感じ。
systemdなのでsystemctljournalctlを利用する。

# サービスの起動・停止・再起動
$ sudo systemctl start fluent-bit
$ sudo systemctl stop fluent-bit
$ sudo systemctl restart fluent-bit

# systemdのserviceの場所
$ cat /lib/systemd/system/fluent-bit.service

# 設定ファイルの場所: input/outputなど
$ cat /etc/fluent-bit/fluent-bit.conf 

# 設定ファイルの場所: parser
$ cat /etc/fluent-bit/parsers.conf 

# fluent-bit.serviceの状態を確認
$ journalctl status fluent-bit

# fluent-bit.serviceのログを表示
# -f: tailのようにログを開き続ける
$ journalctl -f -u fluent-bit

macOSへのインストール

macOSbrewコマンドが使えるっぽい。
ただ依存関係が多く、大量のパッケージがインストール&アップデートされた。。
Dockerコンテナが用意されてるので、そっちのほうがよかったかも。。

# macOSの場合
$ brew install fluent-bit

# dockerの場合
$ docker run -ti cr.fluentbit.io/fluent/fluent-bit

macOSでの実行方法とかはこんな感じ。

# 実行
$ fluent-bit -i dummy -o stdout -f 1

# 実行ファイルの場所
$ which fluent-bit
/opt/homebrew/bin/fluent-bit

# 設定ファイルの場所
$ ls /opt/homebrew/opt/fluent-bit/etc/fluent-bit/fluent-bit.conf 

macOSのはローカルでお試し実行するために利用する感じ。
CLIコマンドのオプションはこのあたり。

設定ファイルを指定できるので、ローカルのデバッグなどで便利。

$ fluent-bit -c my-app.conf

設定ファイルの中身

初期設定後の設定ファイル(fluent-bit.conf)はこんな感じ。
Classic modeで書かれている。

[SERVICE]
    # Flush: set an interval of seconds before to flush records to a destination
    flush        1
    
    # Daemon: instruct Fluent Bit to run in foreground or background mode.
    daemon       Off
    
    # Log_Level: Set the verbosity level of the service
    log_level    info
    
    # Parsers File: specify an optional 'Parsers' configuration file
    parsers_file parsers.conf
    
    # Plugins File: specify an optional 'Plugins' configuration file to load external plugins.
    plugins_file plugins.conf
    
    # HTTP Server: Enable/Disable the built-in HTTP Server for metrics
    http_server  Off
    http_listen  0.0.0.0
    http_port    2020

    # Storage: Fluent Bit can use memory and filesystem buffering based mechanisms
    storage.metrics on

[INPUT]
    name cpu
    tag  cpu.local

    # Read interval (sec) Default: 1
    interval_sec 1

[OUTPUT]
    name  stdout
    match *

CPU使用量のメトリクスを標準出力に出力するだけのサンプル。

設定ファイルは、
[SERVICE]のようなセクションと、
各セクションのkey-valueで構成されてる。

別ファイルのインポート

以下のような@INCLUDEコマンドがあるので、
他の設定ファイルをインポートすることもできる。

[SERVICE]
    Flush 1

@INCLUDE inputs.conf
@INCLUDE outputs.conf

環境変数の利用

また、こんな感じで環境変数を利用することもできる。

# $ export MY_OUTPUT=stdout
[OUTPUT]
    Name  ${MY_OUTPUT}
    Match *

ざっとの設定の仕方

[SERVICE]はFluent Bit全体の設定で1つ、
[INPUT]は収集する対象で複数、
[OUTPUT]は出力・転送する先で複数。

基本的には、[INPUT][OUTPUT]を増やしていき、
ログ形式によって[PARSER]を追加していくといい感じ。

各セクションの種類とドキュメント

基本的にDATA PIPELINEの章にまとまってる。

INPUT

INPUTはこのあたり。

CPUやメモリ、ネットワーク、syslogなど取りたいログを選んで設定していく感じ。

今回は特定のログファイルを読み込んでいくので、
tailを利用する。

OUTPUT

OUTPUTはこのあたり。

INPUTと同様に、転送先を選んで設定していく感じ。
ファイルや標準出力、AWS、Datadogなどなど広く用意されている。

今回は、GCPのCloud Loggingに送りたいので、
stackdriverを利用。オペレーションスイートの旧名称がStackdriverらしい。

PARSER

PARSERはこのあたり。

JSON正規表現など、基本的な形式を選んで、
細かく設定していく感じ。

parsers.confには、デフォルトのパーサーが用意されているので、
そこから選んでもOK。

[PARSER]
    Name   nginx
    Format regex
    Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] # ... 略
    Time_Format %d/%b/%Y:%H:%M:%S %z

今回は正規表現を使って独自のログ形式に対応する。
JSONとかのほうが扱いやすいかも。

スタックトレースなど複数行の場合は、
[MULTILINE_PARSER]を使うっぽい。

ただ、INPUTがtailの場合は、
tail側が複数行のサポートをしてくれるっぽい。


以上!! とりあえず、ここまで!
Fluent Bit、便利。。(*´ω`*)