iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
Software Development

系統與服務雜談系列 第 27

Log Agent - Fluent Bit Input元件 與 Tail淺談

Fluent bit回顧
Log Agent - Fluent Bit 簡介
Log Agent - Fluent Bit 安裝與常見架構模式
Log Agent - Fluent Bit Service配置與內建 API

Input元件

Fluent bit提供了各式各樣的plugin來收集不同來源的Log file.
比如說從Log file來收集、從OS收集一些metric.
我們可以設定多個input設定,
每個設定其實都會在fluent-bit內創見一個instance, 也都有自己的配置設定.
https://docs.fluentbit.io/manual/pipeline/inputs

設定格式如下:

[INPUT]
    Name input元件類型名稱
    Tag 後面會介紹
    對應input元件property 對應的value

挑幾個玩一下

  • CPU Metrics
  • Disk I/O
  • Memory
  • Network I/O
    這幾個input設定方式都一樣.
    就是設定Interval_Sec 多久取得這些metric一次.
    預設都是1秒.
[SERVICE]
    flush 1
    Daemon off
    # 這裡先改成debug, 目的試看input啟動了哪些
    log_level debug
    health_check on
    hc_errors_count 5
    hc_retry_failure_count 5
    hc_period 5
    #開啟http server
    http_server on
    #監聽所有網卡
    http_listen 0.0.0.0
    #監聽導到port 2020的請求
    http_port 2020
    storage.metrics on

[INPUT]    
    Name cpu   
    Interval_Sec 5
    Interval_NSec 0
    Tag  my_cpu

[INPUT]
    Name          netif
    Interval_Sec  5
    Interval_NSec 0
    Interface     eth0
    Alias net_eth0
    Verbose true
    Tag my_net_eth0

[INPUT]
    Name          disk
    Interval_Sec  5
    Interval_NSec 0
    Tag my_disk

[INPUT]
    Name   mem
    Interval_Sec  5
    Tag    my_memory

[OUTPUT]
    Name stdout
    match *
    Format json

一開始啟動就會看到如下的畫面,
Inputs這裡剛好就是我們啟用的4個input

fluentd_1  | [2021/10/11 07:02:21] [ info] Configuration:
fluentd_1  | [2021/10/11 07:02:21] [ info]  flush time     | 1.000000 seconds
fluentd_1  | [2021/10/11 07:02:21] [ info]  grace          | 5 seconds
fluentd_1  | [2021/10/11 07:02:21] [ info]  daemon         | 0
fluentd_1  | [2021/10/11 07:02:21] [ info] ___________
fluentd_1  | [2021/10/11 07:02:21] [ info]  inputs:
fluentd_1  | [2021/10/11 07:02:21] [ info]      cpu
fluentd_1  | [2021/10/11 07:02:21] [ info]      netif
fluentd_1  | [2021/10/11 07:02:21] [ info]      disk
fluentd_1  | [2021/10/11 07:02:21] [ info]      mem
fluentd_1  | [2021/10/11 07:02:21] [ info] ___________
fluentd_1  | [2021/10/11 07:02:21] [ info]  filters:
fluentd_1  | [2021/10/11 07:02:21] [ info] ___________
fluentd_1  | [2021/10/11 07:02:21] [ info]  outputs:
fluentd_1  | [2021/10/11 07:02:21] [ info]      stdout.0
fluentd_1  | [2021/10/11 07:02:21] [ info] ___________

可以看到內容有出現input元件所採集到的內容
這裡出現cpu0-cpu11, 是因為我主機剛好就是12Thread
cpu_p 則是目前整個系統所使用的cpu使用率
user_p則是目前User mode底下所使用的cpu使用率
system_p則是Kernel mode底下所使用的cpu使用率

[{"date":1633935975.657292,"cpu_p":4.633333333333334,"user_p":4.3,"system_p":0.3333333333333334,"cpu0.p_cpu":1.4,"cpu0.p_user":1.2,"cpu0.p_system":0.2,"cpu1.p_cpu":1.4,"cpu1.p_user":1.0,"cpu1.p_system":0.4,"cpu2.p_cpu":1.4,"cpu2.p_user":0.8,"cpu2.p_system":0.6,"cpu3.p_cpu":5.0,"cpu3.p_user":4.6,"cpu3.p_system":0.4,"cpu4.p_cpu":7.2,"cpu4.p_user":7.0,"cpu4.p_system":0.2,"cpu5.p_cpu":5.4,"cpu5.p_user":5.0,"cpu5.p_system":0.4,"cpu6.p_cpu":1.4,"cpu6.p_user":1.0,"cpu6.p_system":0.4,"cpu7.p_cpu":1.6,"cpu7.p_user":0.8,"cpu7.p_system":0.8,"cpu8.p_cpu":1.0,"cpu8.p_user":1.0,"cpu8.p_system":0.0,"cpu9.p_cpu":1.0,"cpu9.p_user":0.8,"cpu9.p_system":0.2,"cpu10.p_cpu":13.0,"cpu10.p_user":12.8,"cpu10.p_system":0.2,"cpu11.p_cpu":16.4,"cpu11.p_user":16.2,"cpu11.p_system":0.2}]

接著可以看到net interface相關的資訊

[{"date":1633935975.657417,"eth0.rx.bytes":0,"eth0.rx.packets":0,"eth0.rx.errors":0,"eth0.rx.drop":0,"eth0.rx.fifo":0,"eth0.rx.frame":0,"eth0.rx.compressed":0,"eth0.rx.multicast":0,"eth0.tx.bytes":0,"eth0.tx.packets":0,"eth0.tx.errors":0,"eth0.tx.drop":0,"eth0.tx.fifo":0,"eth0.tx.collisions":0,"eth0.tx.carrier":0,"eth0.tx.compressepd":0}]

disk目前的吞吐量throughput

[{"date":1633935975.657755,"read_size":0,"write_size":6356992}]

memory跟swap空間的使用情況

[{"date":1633935975.657776,"Mem.total":32813924,"Mem.used":16895336,"Mem.free":15918588,"Swap.total":2097148,"Swap.used":0,"Swap.free":2097148}]

然後回頭看一下設定檔, 這裡我們有給Alias,
像net interface這裡, 我們可以設定多個, 因為網卡可以有多張,
如果不給個alias, 則在某些情況則難以判別
回頭用上篇講的fluent REST API, 就能發現只有net_eth0是用alias做物件名稱
其他都是按照input 寫的順序從0開始, 加上input name, (cpu_0, disk_2這樣)

[INPUT]
    Name          netif
    Interval_Sec  5
    Interval_NSec 0
    Interface     eth0
    Alias net_eth0
    Verbose true
    Tag my_net_eth0
curl -s http://127.0.0.1:2020/api/v1/metrics/ | jq          
{
  "input": {
    "cpu.0": {
      "records": 14,
      "bytes": 11718
    },
    "net_eth0": {
      "records": 13,
      "bytes": 3624
    },
    "disk.2": {
      "records": 13,
      "bytes": 511
    },
    "mem.3": {
      "records": 14,
      "bytes": 1358
    }
  },
  "filter": {},
  "output": {
    "stdout.0": {
      "proc_records": 50,
      "proc_bytes": 15958,
      "errors": 0,
      "retries": 0,
      "retries_failed": 0,
      "dropped_records": 0,
      "retried_records": 0
    }
  }
}

Tail插件

通常Application不管有沒有以container方式運行, 大家應該都還是會寫Log到特定文件內.
有些是把Log寫到MessageQueue裡面, 讓Broker慢慢的寫入給Logstah、Fluentbit這類的.
但多一個服務就要多管理跟運維成本.
寫到本機的檔案還是簡單些, 只要做好rotate就好.
tail元件就是專門爬這些Log file用的

Parameters

  • Path

    用來指定要採集的log file的位子
    如果有多個可以用,來串接多個位子
    對於檔名或路徑, 支持*wildcard

  • Refresh_Interval

    設定秒數, 來監聽檔案
    預設是60秒

  • Rotate_Wait

    日誌文件被rotated後, 等待一段時間後, 再來繼續監控該文件
    當原有日誌數據被rotate到另一個檔名時, 很可能會被重新讀取
    預設5秒
    能參考File Rotation

  • Mem_Buf_Limit

    memory buffer size, 用來指定之前data pipeline中的Buffer區塊的大小
    如果buffer內還沒處理完成的資料size超過這限制, 則tail會暫停採集, 直到Buffer區塊內的資料被flush到Output區塊
    能避免記憶體胡亂增長
    預設是沒指定, 但建議還是指定

  • Path_Key

    這裡指定的是label的名稱, 描述log內關於這log資料來自哪個檔案
    如果這裡寫file_key, 輸出時這樣顯示"file_key"=>"/var/log/syslog"
    預設是不會輸出

  • Read_from_Head

    一個log file要不要從頭開始讀取
    預設是false

  • DB

    紀錄被監控的文件跟其offset偏移量的檔案
    Fluent bit使用SQLite作為數據庫引擎來紀錄

  • DB.Journal_Mode

    跟一些資料庫一樣, 就是log要寫入db時有什麼處理方式
    有DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
    預設是WAL (Write-Ahead-Log)
    能參考WAL and Memory Usage

  • Parser

    下篇聊
    主要就剖析日誌資料

  • Multiline.parser

    跟Parser同功能, 但針對的是Multiline log資料

來嘗試玩一下Tail
我直接來抓取syslog的資料

[SERVICE]
    flush 1
    Daemon off
    log_level info
    health_check on

[INPUT]
    name tail
    tag demo
    path /var/log/syslog #指定採集日誌的位子, 這裡指定syslog
    path_key file_key 
    db  /home/nathan/demo.db #指定db位子, 我是放自己的目錄下就是了

[OUTPUT]
    Name stdout
    match *

大概會看到像這樣的資料
其中"file_key"=>"/var/log/syslog",
file_key就是path_key file_key這裡的設置

tag是demo, 也看到了

Oct 11 23:45:32 nathan td-agent-bit[907186]: [157] demo: [1633967127.693605530, {"file_key"=>"/var/log/syslog", "log"=>"Oct 11 23:45:27 nathan td-agent-bit[907186]: #033[1mFluent Bit v1.8.7#033[0m"}]
Oct 11 23:45:32 nathan td-agent-bit[907186]: [158] demo: [1633967127.693605831, {"file_key"=>"/var/log/syslog", "log"=>"Oct 11 23:45:27 nathan td-agent-bit[907186]: * #033[1m#033[93mCopyright (C) 2019-2021 The Fluent Bit Authors#033[0m"}]

來看db資料, 在指定的路徑下會出現3個檔案
因為是使用SQLite, 加上我又開啟WAL模式,
所以出現例外兩個檔案, 別管它, 讓SQLite自己管理

-rw-r--r--  1 root   root      8192  十  11 23:48 demo.db
-rw-r--r--  1 root   root     32768  十  11 23:48 demo.db-shm
-rw-r--r--  1 root   root   4120032  十  11 23:48 demo.db-wal

來看看demo.db存的資料, 使用sqlite3來操作db文件

sqlite3 demo.db
sqlite> .headers on
sqlite> .mode column

# 查看有哪些table
sqlite> .tables
in_tail_files

# 只有一張in_tail_files
sqlite>  select * from in_tail_files;
id          name             offset      inode       created     rotated   
----------  ---------------  ----------  ----------  ----------  ----------
1           /var/log/syslog  7400014404  558         1633960199  0   

可以看到這裡面紀錄的欄位就這樣, 但其實也沒必要特別維護這文件, 讓fluent bit來維護就好

本日小結

Fluent bit真的提供很多input plugin, 甚至能跟Prometheus所提供的node exporter結合,
不知道能不能跟其他exporter相互應用就是了, 但我想應該是可以. 日後再來嘗試.

官網跟ELK的說明相比, 蠻多什麼描述跟範例真的有差距, 也許要等社團的力量慢慢補齊吧.
但基本功能, 官網都有教學. 也堪用了


上一篇
Log Agent - Fluent Bit Service配置與內建 API
下一篇
Log Agent - Fluent Bit Parser元件
系列文
系統與服務雜談32

尚未有邦友留言

立即登入留言