1. 程式人生 > >全棧工程師開發手冊(原創)

全棧工程師開發手冊(原創)

最近開始轉行做大資料,大資料中很重要的一部分是資料的收集,我們公司主要用的資料收集工具是Fluentd,由於Fluentd的配置比較多,有可能配置過一次後就會忘了。我這邊在學習Fluentd配置的同時也對這些配置進行一些記錄,方便後面再用到時可以快速的查詢。

Fluentd簡介

Fluentd是一款完全免費且完全開源的日誌收集器,擁有“Log Everything”的體系結構,能夠與125種以上的系統對接。 在這裡插入圖片描述

配置檔案語法

Fluentd事件的生命週期
  1. 每個輸入的事件會帶有一個tag
  2. Fluentd通過tag匹配output
  3. Fluentd傳送事件到匹配的output
  4. Fluentd支援多個數據源和資料輸出
  5. 通過過濾器,事件可以被重新觸發
“source”: 定義資料來源

資料來源可以在source指令中定義,比如我們可以定義http和forward的資料來源。http資料來源可以通過http協議來接收資料,forward可以通過tcp協議來接收資料。

# Receive events from 24224/tcp
# This is used by log forwarding and the fluent-cat command
<source>
  @type forward
  port 24224
</source>

# http://this.host:9880/myapp.access?json={"event":"data"}
<source>
  @type http
  port 9880
</source>

所有source指令中必須包含@type引數,該引數用來指定使用哪個輸入外掛,比如我們還可以用tail外掛來讀取檔案的內容。

路由

source指令把事件提交到Fluentd的路由引擎。一個事件由三個實體組成:tag、time和record。tag是由’.’分割的字串組成,被內部路由引擎使用。time由input外掛指定,必須是Unix時間戳格式。record是一個Json物件。

強烈推薦使用小寫字母、數字和下劃線來命名tag,雖然其他的字元也是合法的。

“match”: 定義資料的輸出目標

match指令通過匹配tag欄位來將事件輸出到其他的系統。同樣match指令也必須指定@type引數,該引數用來指定使用哪個輸出外掛。在下面的例子中,只有myapp.access的tag能夠匹配到該輸出外掛。

<match myapp.access>
  @type file
  path /var/log/fluent/access
</match>
匹配模式

下面的這些匹配模式可以在中使用,用來匹配tag:

  • *用來匹配tag的一部分(比如:a.*可以匹配a.b,但是不能匹配a或者a.b.c)
  • **可以用來匹配tag的0個或多個部分(比如:a.**可以匹配a、a.b和a.b.c)
  • {X,Y,Z}匹配X,Y或者Z(比如:{a,b}可以匹配a和b,但是不能匹配c。他可以和*或者**結合起來一起使用。)
  • 如果有多個匹配模式寫在裡面,則可以用空格分開(比如:能夠匹配a和b。<match a.** b.* >能夠匹配a,a.b,a.b.c和b.d。)
匹配順序

Fluentd是按順序匹配的,先在配置檔案裡面出現的match會先匹配。下面的例子中myapp.access永遠都不會被匹配到。

# ** matches all tags. Bad :(
<match **>
  @type blackhole_plugin
</match>

<match myapp.access>
  @type file
  path /var/log/fluent/access
</match>
“filter”:事件處理管道

“filter”指令的語法和”match”指令的語法相同,但是”filter”能夠在管道中被連起來處理,如下所示:

Input -> filter 1 -> ... -> filter N -> Output

下面的例子展示了record_transformer fliter的用法。source首先會接收到一個{“event”:”data”}的事件,然後該事件會首先被路由到filter,filter會增加一個host_param的欄位到record中,然後再把該事件傳送到match中。

# http://this.host:9880/myapp.access?json={"event":"data"}
<source>
  @type http
  port 9880
</source>

<filter myapp.access>
  @type record_transformer
  <record>
    host_param "#{Socket.gethostname}"
  </record>
</filter>

<match myapp.access>
  @type file
  path /var/log/fluent/access
</match>
“system”:設定系統範圍配置

以下的配置能夠由”system”指令指定。也可以通過Fluentd的配置選項設定相同的配置:

  • log_level
  • suppress_repeated_stacktrace
  • emit_error_log_interval
  • suppress_config_dump
  • without_source
  • process_name (只能用”system”指令指定)

下面是一些例子:

<system>
  # 等價於-qq選項
  log_level error
  #等價於--without-source選項
  without_source
</system>
<system>
  process_name fluentd1
</system>

process_name用來指定Fluentd監控程序和工作程序的名字,通過ps可以看到

% ps aux | grep fluentd1
foo      45673   0.4  0.2  2523252  38620 s001  S+    7:04AM   0:00.44 worker:fluentd1
foo      45647   0.0  0.1  2481260  23700 s001  S+    7:04AM   0:00.40 supervisor:fluentd1

“label”:用來組織filter和match

“label”指令用來降低tag路由的複雜度,通過”label”指令可以用來組織filter和match的內部路由。下面是一個配置的例子,由於”label”是內建的外掛,所以他的引數需要以@開頭。

<source>
  @type forward
</source>

<source>
  @type tail
  @label @SYSTEM
</source>

<filter access.**>
  @type record_transformer
  <record>
    # ...
  </record>
</filter>
<match **>
  @type elasticsearch
  # ...
</match>

<label @SYSTEM>
  <filter var.log.middleware.**>
    @type grep
    # ...
  </filter>
  <match **>
    @type s3
    # ...
  </match>
</label>

在上面的例子中,forward的資料來源的事件被路由到record_transformer filter和elasticsearch output中。tail資料來源被路由到@system裡面的grep filter和s3 output中。

@ERROR label

@ERROR label是內建的label,用來記錄emit_error_event錯誤事件的。如果在配置檔案裡面設定了

“@include”:重用配置

可以通過”@include”來匯入其他的配置檔案,配置檔案是按順序匯入的。如果使用模式匹配的話,檔案是按字母順序匯入的。

# If you have a.conf,b.conf,...,z.conf and a.conf / z.conf are important...
# This is bad
@include *.conf

# This is good
@include a.conf
@include config.d/*.conf
@include z.conf

如果匯入的檔案有順序的要求的話,最好自己主動寫匯入的語句,模式匹配匯入容易出錯。

支援的資料型別

每個外掛都需要一些引數。例如:in_tail外掛有rotate_wait和pos_file這兩個引數。每個引數都有對應的型別與其關聯。下面是這些型別的定義:

  • string 型別:該型別被解析成一個字串。string型別可以有三種形式:不帶引號的字串、帶單引號的字串和帶雙引號的字串。
  • integer 型別:該型別被解析成一個整數。
  • float 型別:該型別被解析成一個浮點數。
  • size 型別:該型別用來解析成有多少個位元組。可以在整數後面加上k/K、m/M、g/G、t/T,對應的是計算機學科的度量單位。比如:12k表示為12*1024後的數值。
  • time 型別:該型別被解析成時間。可以在浮點數後面加上s、m、h和d分別表示為秒、分、小時、天。可以用0.1表示100ms。
  • array 型別:該型別被解析成JSON陣列。這種型別還支援縮寫,比如:[“key1”, “key2”]可以縮寫成key1,key2。
  • hash 型別:該型別被解析成JSON物件。這種型別也支援縮寫,比如:{“key1”:”value1”, “key2”:”value2”}可以縮寫成key1:value1,key2:value2。

常見的外掛引數

這些引數是系統保留的並且帶有@字首。

  • @type: 指定外掛的型別。
  • @id: 指定外掛的id。
  • @label:用來指定標籤。
  • @log_level:用來指定每個外掛的log級別。

檢查配置檔案

通過–dry-run選項,可以在不啟動外掛的情況下檢查配置檔案。

$ fluentd --dry-run -c fluent.conf

格式建議

雙引號包起來的字串、陣列和雜湊型別支援多行
str_param "foo  # This line is converted to "foo\nbar". NL is kept in the parameter
bar"
array_param [
  "a", "b"
]
hash_param {
  "k":"v",
  "k1":10
}

如果想讓[或者{開頭的字串不被解析成陣列或者物件,則需要用’或者“把該字串包起來。

<match **>
  @type mail
  subject "[CRITICAL] foo's alert system"
</match>
<match tag>
  @type map
  map '[["code." + tag, time, { "code" => record["code"].to_i}], ["time." + tag, time, { "time" => record["time"].to_i}]]'
  multi true
</match>
嵌入Ruby程式碼

可以在”包住的#{}裡面執行Ruby程式碼,這可以用來獲取一些機器的資訊,比如hostname。

host_param "#{hostname}"  # This is same with Socket.gethostname
@id "out_foo#{worker_id}" # This is same with ENV["SERVERENGINE_WORKER_ID"]
在雙引號字串中,\是轉義字元

\被解釋為轉義字元。你需要用\來設定”,\r,\n,\t,\或雙引號字串中的多個字元。

str_param "foo\nbar" # \n is interpreted as actual LF character