iT邦幫忙

2023 iThome 鐵人賽

DAY 16
1
Cloud Native

時光之鏡:透視過去、現在與未來的 Observability系列 第 16

Fluent Bit — 資料收集界的萬能瑞士刀

  • 分享至 

  • xImage
  •  

Fluent Bit

資訊處理流程 生成 收集 儲存 使用
Fluent Bit

Fluent Bit 是資料收集器 Fluentd 的輕量化版本。在經歷了 Observability 的大爆發後,Fluent Bit 將自己重新定位成 「Telemetry Agent for Logs, Metrics and Traces」,將這三個 Telemetry Data 視為主要的資料來源。Fluent Bit 可以從不同來源收集 Logs、Metrics 或 Traces,並支援多種處理或儲存服務,如 Loki、Fluentd、Elasticsearch、DataDog、Kafka 以及各式雲端服務。

Pipeline

Fluent Bit 是由 Eduardo Silva 在 2014 年於 Treasure Data工作時建立的開源專案。Treasure Data 是由 Fluentd 的作者 Sadayuki Furuhashi 創辦,提供數據收集與分析平台。Fluent Bit 設計的最初目的是為了收集 IoT 設備 的 Log,這些設備大多使用 Embedded Linux 且硬體資源很少,因此資料收集器必須要盡可能的輕量化,使其能夠在資源有限的設備上運行。到了 2020 年,Eduardo 創立了 Calyptia,以提供與 Fluent Bit 相關的顧問與 SaaS 服務。

Concepts

Event

Fluent Bit 將每一筆收到的 Log、Metric 或 Trace 視為一個 Event,例如收到以下的 Log:

Jan 18 12:52:16 flb systemd[2222]: Starting GNOME Terminal Server
Jan 18 12:52:16 flb dbus-daemon[2243]: [session uid=1000 pid=2243] Successfully activated service 'org.gnome.Terminal'
Jan 18 12:52:16 flb systemd[2222]: Started GNOME Terminal Server.
Jan 18 12:52:16 flb gsd-media-keys[2640]: # watch_fast: "/org/gnome/terminal/legacy/" (establishing: 0, active: 0)

這四筆 Log 會被視為四個 Event,每個 Event 都會包含以下三個欄位:

  1. TIMESTAMP:時間戳記
  2. METADATA:從 2.1.0 版開始新增的資料,以 key/value 形式儲存
  3. MESSAGE:資料內容

在 2.1.0 版之後,Event 的資料格式表達為 [[TIMESTAMP, METADATA], MESSAGE],而在此版本之前則為 [TIMESTAMP, MESSAGE]。雖然兩者格式略有不同,但 2.1.0 版後的 Fluent Bit 仍然可以解析 2.1.0 之前的資料格式。

Config File

Fluent Bit 的 Config File 支援兩種格式:基於 INI 設計的格式與 YAML,以下為一個簡單的 Config File 範例:

[INPUT] # 中括號定義 Section
    Name        dummy # Key 與 Value 以空格分隔
    Tag         dummy
    Dummy       {"message": "hello world"}

其 YAML 格式如下:

input:
    name: dummy
    tag: dummy
    dummy: '{"message": "hello world"}'

Pipeline

在 Fluent Bit,資料會經過一連串的處理流程,稱為 Pipeline。主要元件包括:

  1. Input:資料的來源,例如讀取檔案、訂閱 Kafka Topic 等
  2. Parser:將資料轉換為 Fluent Bit 可以處理的結構化資料以便後續處理,例如解析 JSON 格式的資料
  3. Filter:對資料進行過濾、增加或刪除資訊等,例如排除 Level 為 Debug 的資料
  4. Buffer:暫存資料,當 Output 無法連線或是暫時無法處理資料時,會先將資料暫存起來,待 Output 可以處理時再送出
  5. Routing:根據 Input 的 Tag 與 Output 的 Match,決定資料要送往哪個 Output
  6. Output:資料的目的地,例如寫入檔案、送至 Loki 等

Fluent Bit Pipeline

Fluent Bit 官網提供了 SandBox 教學,可以在虛擬環境中學習如何使用 Fluent Bit。

SandBox

Tag & Match

在 Pipeline 中,Tag 用於 Input 識別資料來源,而 Match 則用於指定哪些資料需要經過特定的 Filter 或 Output 處理。了解 Tag 與 Match 對於理解 Fluent Bit 的運作非常重要,否則就會發現資料沒有按照你預想的 Pipeline 被處理。

Tag 設定於 Input,作為識別該資料來源的標籤,供後續 Pipeline 配對使用。如果沒有設定 Tag,預設會使用 Input 的名稱加上 . 與流水號作為後綴,例如:dummy.0tail.1systemd.2 等。

Match 設定於 Filter 與 Output,作為篩選資料的條件,若有符合條件的就會被 Filter 與 Output 處理。相反的,如果沒有設定 Match,Filter 或 Output 就會不會處理任何資料。

以下面這組 INPUT 為例,其中的 Tag 為 my_first_dummy

[INPUT]
    Name        dummy
    Tag         my_first_dummy
    Dummy       {"message": "hello world"}

如果希望 Output 只處理 Tag 為 my_first_dummy 的資料,可以在 Output 中設定 Match:

[OUTPUT]
    Name        stdout
    Match       my_first_dummy

或者在 Output 中設定 Match 為萬用字元 *,表示所有資料都會被處理:

[OUTPUT]
    Name        stdout
    Match       *

如果想要讓 Output 只處理 Tag 為 my_ 開頭的資料,Match 可以設定為 my_*

[OUTPUT]
    Name        stdout
    Match       my_*

Input

Input 是資料的來源,支援多種不同來源,如:

  1. Tail:讀取檔案內容
  2. Systemd:讀取 Linux 系統的 Log
  3. Kafka:訂閱 Kafka Topic
  4. Dummy:測試用,生成固定的文字內容

每個 Input 都有各自對應的參數,例如 Tail Input 可以指定要讀取的檔案路徑、多行 Log 的 Parser 等,例如:

[INPUT]
    name              tail
    path              /var/log/python/*.log
    multiline.parser  python

Parser

Parser 負責將 Input 的資料轉為結構化資料。支援多種不同的方式,如:

  1. JSON:解析 JSON 格式的資料
  2. Logfmt:解析 logfmt 格式的資料
  3. Regular Expression:使用正規表達式解析資料

Parser 有一些通用的 Config 參數,如:

  1. Name:Parser 的名稱,用於在其他 Component 中引用
  2. Format:指定要使用的 Parser,如:jsonlogfmtregex
  3. Time_Key:如果 Log 中有時間資訊,可以指定要使用的 Key,覆寫 Fluent Bit 收集到的時間

以使用 JSON Parser 為例,若原始 Input 取得的 Log 如下:

{"key1": 12345, "key2": "abc", "time": "2006-07-28T13:22:04Z"}

Parser 的設定方式為:

# 獨立設定於 parsers.conf 中
[PARSER]
    Name        my_json_parser # 自訂的 Parser 名稱
    Format      json
    Time_Key    time
    Time_Format %Y-%m-%dT%H:%M:%S %z
# 設定於 fluent-bit.conf
[INPUT]
    Name        tail
    Path        /var/log/docker/*.log
    Parser      my_json_parser # 指定要使用的 Parser

解析出來的資料會變成:

[1154103724, {"key1"=>12345, "key2"=>"abc"}]

Filter

Filter 可以對資料進行過濾、增加或刪除資訊等,可以說是 Fluent Bit 最重要的功能,支援多種不同的方式,如:

  1. Grep:使用 grep 保留或排除資料
  2. Modify:加入或刪除 Property
  3. Nest:展開或是壓縮巢狀結構,例如:{"a": {"b": 1}} 轉換為 {"a.b": 1}
  4. Kubernetes:將 Kubernetes Pod 的 Metadata 加入到資料中,例如將 Pod 的 Label 加入到資料中

順序為 Config File 中 Filter 的順序,例如:

[FILTER]
    Name        grep
    Match       * # 所有 INPUT 都會被處理
    Regex       msg ^error

[FILTER]
    Name        Modify
    Match       * # 所有 INPUT 都會被處理
    Add         custom_key custom_value

會依序執行 Grep 與 Modify Filter,先保留資料 msg 欄位以 error 開頭的資料,再將 custom_key: custom_value 加入到資料中。

例如原始資料為:

{"msg": "error: something wrong"}
{"msg": "debug: pass"}
{"msg": "info: just info"}

處理後的資料會變成:

{"msg": "error: something wrong", "custom_key": "custom_value"}

Output

Output 是資料的目的地,支援多種不同的目的地,如:

  1. Standard Output:將資料輸出到標準輸出,通常用於測試
  2. File:將資料寫入檔案
  3. Loki:將資料送至 Loki
  4. Kafka:將資料送至 Kafka Topic

例如,將資料送至 Loki 的設定如下:

[OUTPUT]
    Name        loki
    Match       docker # 只有 Tag 為 docker 的 INPUT 才會使用此 OUTPUT
    Host        loki # 不用加入 Path loki/api/v1/push
    Port        3100 # 預設為 3100
    Labels      job=fluent-bit # Loki 儲存 Log 時使用的 Label

範例

以下是一個綜合範例,展示 Input、Parser、Filter 和 Output 的設定。

[INPUT]
    Name        dummy
    Tag         my_first_dummy
    Dummy       {"msg": "error: got error"}

[FILTER]
    Name        grep
    Match       my_first_dummy
    Regex       msg error

[OUTPUT]
    Name        stdout
    Match       my_first_dummy

這個配置檔會從 Dummy Input 讀取資料,使用 Grep Filter 過濾出包含 "error" 的訊息,最後將這些資料輸出到 Console。

Service

有時候在設定的範例會看到有一個 SERVICE section,它是 Fluent Bit 的一個特殊 section,用於設定 Fluent Bit 本身的參數,例如:FlushDaemonLog_Level 等,這些參數會影響到 Fluent Bit 的行為,而不是資料的處理流程。

[SERVICE]
    Flush           5
    Daemon          off
    Log_Level       debug

Lab

範例程式碼:16-fluentbit

Quick Start

Basic

  1. 啟動所有服務

    docker-compose up -d
    
  2. 檢視 fluent-bit Container log

    docker logs -f fluent-bit
    
  3. 關閉所有服務

    docker-compose down
    

Container Log with Loki

  1. 啟動所有服務

    docker-compose -f docker-compose.loki.yaml up -d
    
  2. 檢視服務

    1. Nginx: http://localhost:8080
      1. 瀏覽 Nginx 時會生成 Access Log
    2. Grafana: http://localhost:3000,登入帳號密碼為 admin/admin
      1. 點擊左上 Menu > Explore,左上 Data Source 選擇 Loki,在 Label Filter 中 Label 選擇 app,Value 選擇 nginx,即可看到 nginx Container 的 Log

      2. 若要生成更多 Log 也可以使用 k6 發送更多 Request

        k6 run --vus 1 --duration 300s k6-script.js
        
  3. 關閉所有服務

    docker-compose down
    

Container Log with Vivo

  1. 啟動所有服務

    docker-compose -f docker-compose.vivo.yaml up -d
    
  2. 檢視服務

    1. Nginx: http://localhost:8080
      1. 瀏覽 Nginx 時會生成 Access Log
    2. Vivo: localhost:8000
      1. 點選左側 Logs 可以看到 Fluent Bit 收集到的 Nginx Log
  3. 關閉所有服務

    docker-compose -f docker-compose.vivo.yaml down
    

Goals

Basic

  1. 建立 Fluent Bit,使用 DummyRandom Input,將資料送至 Standard Output 呈現

Container Log with Loki

  1. 建立 Fluent Bit,使用 Forward 作為 Input 搭配 Fluentd Logging Driver 接收 Container Log,使用 Loki 作為 Output 將資料送至 Loki
  2. 建立 Loki,負責收取 Fluent Bit 傳送的 Log
  3. 建立 Grafana,讀取 Loki 的資料
  4. 建立 Nginx,產生 Log

Container Log with Vivo

  1. 建立 Fluent Bit,使用 Forward 作為 Input 搭配 Fluentd Logging Driver 接收 Container Log,將資料透過 Forward 送至 Vivo
  2. 建立 Vivo,負責收取 Fluent Bit 傳送的 Log
  3. 建立 Nginx,產生 Log

小結

Fluent Bit,作為資料收集器 Fluentd 的簡化版本,擁有完整的 Plugin 生態系。不僅可以從多樣的資料來源中進行資料收集,而且能將資料推送至不同的目的地。同時,它還能與 Fluentd 無縫整合,延續既有的 Plugin 生態。類似於 Grafana,Fluent Bit 的目標是建立一個開放、多元的生態系,讓使用者能夠自由地將其整合進自己的系統之中。

隨著 Observability 領域的迅速發展,Fluent Bit 的創始人 Eduardo 所領導的公司 Calyptia 也推出了全新的開源專案 Vivo。這個專案專注於展示 Fluent Bit 所收集到的各類 Telemetry Data,並且能與 Fluent Bit 進行深度整合。

參考資料

  1. Fluent Bit Introduction
  2. Observability with Fluent Bit: Logs, Metrics & Traces - Eduardo Silva & Anurag Gupta, Calyptia

上一篇
Promtail — Loki 御用 Log 收集器
下一篇
Vector — 速度至上的資料收集界新星
系列文
時光之鏡:透視過去、現在與未來的 Observability30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言