Docker:Fluentd收集容器日誌
快速啟動Fluentd
1、建立日誌檔案和配置檔案
mkdir/home/fluentd/container-logs/home/fluentd/conf/
2、編寫配置檔案
vi /home/fluentd/conf/fluent.conf
<source> @type forward </source> <match *> @type file path /fluentd/log/${tag}/${tag} append true <format> @type single_value message_key log</format> <buffer tag,time> @type file timekey 1d timekey_wait 10m flush_mode interval flush_interval 30s </buffer> </match>
3、啟動Fluentd
# docker run -d -p 24224:24224 -v /home/fluentd/container-logs:/fluentd/log -v /home/fluentd/conf/fluent.conf:/fluentd/etc/fluent.conf fluent/fluentd
此時會在宿主機的/home/fluentd/container-logs目錄下生成容器日誌,所有收集到的日誌檔案將儲存至此。
啟動其他容器時指定容器的logging driver
在啟動容器的時候執行使用fluentd作為logging driver,下面以啟動nginx容器舉例:
# docker run -d --log-driver fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag="nginx-test" --log-opt fluentd-async-connect --name nginx-test -p 8080:80 nginx
--log-driver: 配置log驅動 --log-opt: 配置log相關的引數
tag: fluentd-address: fluentd服務地址 fluentd-async-connect:fluentd-docker非同步設定,避免fluentd掛掉之後導致Docker容器也掛了
Fluentd配置
配置檔案用於讓使用者控制Fluentd輸入(input)和輸出(output)的行為:(1) 選擇輸入和輸出外掛,(2) 指定外掛引數。配置檔案要求必須存在以使Fluentd正常工作。
字元編碼
Fluentd假設配置檔案編碼為UTF-8或ASCII。
指令列表
配置檔案由下列指令組成:
- source 指令確定輸入源。
- match 指令確定輸出目的地。
- filter 指令確定事件處理管道。
- system 指令設定系統級配置。
- label 指令將output和filter分組以進行內部路由。
- @include 指令用於包括其它檔案。
配置示例 Step by Step
1. source: 所有資料的來源
選擇和配置Fluentd的輸入源,需要用source指令。Fluentd的標準輸入外掛包括http和forward。http監聽HTTP埠,並接受從HTTP來的日誌訊息。forward讓fluentd監聽TCP埠,並接受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 引數。@type 引數指定了何種輸入外掛將被使用。
插播一下:Routing
source 將事件提交到Fluentd的路由引擎。每個事件由3部分實體組成:tag, time 和 record。tag 是由’.'分隔的字串(如:myapp.access),並且作為Fluentd內部路由的指示。time欄位由 input 外掛指定,並且必須得是Unix時間格式。record 是一個JSON物件。
2. match: 告訴 fluentd 該幹什麼!
match 指令查詢所有具有匹配tag的事件,並且進行處理。match 指令最常見的用法是將事件輸出到其它系統(因此,對應於match指令的外掛被稱為"output"外掛)。Fluentd的標準輸出外掛包括 file 和 forward。現在來加入到配置檔案中。
# 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> # Match events tagged with "myapp.access" and # store them to /var/log/fluent/access.%Y-%m-%d # Of course, you can control how you partition your data # with the time_slice_format option. <match myapp.access> @type file path /var/log/fluent/access </match>
每個 match 指令必須包括一個匹配模板和一個 @type 引數。只有tag 匹配到模板的事件會被送到輸出目的地(在上述示例中,只有tag為"myapp.access"的事件會被匹配)。@type 引數指定了將要使用的 output 外掛。
3. filter: 事件處理管道
filter 指令與 match 有相同的語法,但 filter 可以將處理串成管道。 使用 filter 時事件流看起來會像這樣:
Input -> filter 1 -> ... -> filter N -> Output
現在新增一個標準的 record_transformer filter 到剛剛寫的 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>
收到事件 {“event”: “data”} 後,先扔到filter: record_transformer中,record_transformer 在事件中添加了"host_param" 欄位並且繼續向後傳,{“event”:“data”,“host_param”:“webserver1”},事件最終到達 file 輸出外掛。
match 模板
萬用字元和展開
下列 match 模板可以用於<match> 和<filter>中的tag:
- * 匹配單個tag部分。
- 例如:模板 a.* 匹配 a.b,但不能匹配 a 與 a.b.c
- ** 匹配0個或多個tag 部分
- 例如:a.** 匹配a, a.b 和 a.b.c
- {X,Y,Z} 匹配X, Y, 或 Z, 這裡 X, Y 和 Z都是匹配模板
- 例如:模板 {a,b} 匹配 a 和 b,但不匹配 c
- 這種方法可以用於組合 * 和 ** 模板。例如: a.{b,c}.* 和 a.{b,c.**}
- 當多個模板同時在單個tag中列出時(由一個或多個空格分隔),將匹配所列出的任意一個模板。例如:
- 模板 <match a b> 匹配 a 和 b
- 模板 <match a.** b.*> 匹配 a, a.b, a.b.c (匹配到前一個模板)和 b.d (匹配到後一個模板)
匹配順序
Fluentd 嘗試以模板在配置檔案中出現的順序進行匹配。所以看下面的例子:
# ** matches all tags. Bad :( <match **> @type blackhole_plugin </match> <match myapp.access> @type file path /var/log/fluent/access </match>
上面例子中,myapp.access 永遠都匹配不到。更寬鬆的匹配模板應定義在更嚴格的匹配模板之後。像這樣:
<match myapp.access> @type file path /var/log/fluent/access </match> # Capture all unmatched tags. Good :) <match **> @type blackhole_plugin </match>
當然,如果有兩個同樣的模板,後一個match將永遠無法匹配。如果你希望將事件傳送到多個輸出,應考慮使用 out_copy 外掛。
常見的陷阱是將<filter>放到<match>之後。由於前面說的原因,事件將無法到達filter,也就無法按預期的方式工作。
COPY 輸出外掛
out_copy 是Fluentd的核心外掛,無須另外安裝,out_copy 將事件複製多份,分別送到多個輸出外掛中去。直接來個例子:
<match pattern> @type copy <store> @type file path /var/log/fluent/myapp1 ... </store> <store> ... </store> <store> ... </store> </match>
下面的例子將事件存到本地資料夾/var/log/fluent/myapp下,同時傳送到Elasticsearch例項的fluentd.test 集合中。具體請參見out_file和out_elasticsearch外掛的細節說明。
<match docker.*> @type copy <store> @type file path /var/log/fluent/myapp compress gzip <format> localtime false </format> <buffer time> timekey_wait 10m timekey 86400 timekey_use_utc true path /var/log/fluent/myapp </buffer> <inject> time_format %Y%m%dT%H%M%S%z localtime false </inject> </store> <store> @type elasticsearch host 192.168.198.46 port 9200 index_name fluentd type_name test </store> </match>
啟動一個docker,並將log-driver指向fluentd,即可將日誌輸出到fluentd,再轉發至elasticsearch,同時本地留有日誌備份。
docker run --rm --log-driver fluentd --log-opt fluentd-address=192.168.198.46:24224 --log-opt tag=docker.test alpine date
out_copy 引數
-
@type - 此值必須為"copy"
-
deep_copy - 深度複製,預設為false,out_copy在各store外掛間共享事件記錄。當此值為true時,out_copy為每一store外掛複製一份事件記錄。
-
<store> 欄位 - 指定儲存目的地。格式與<match>指令一致。此欄位必須至少出現一次。
-
ignore_error - 忽略錯誤。當某一store出現錯誤時,這個引數將作用於其餘store,例如:
<match app.**> @type copy <store> @type plugin1 </store> <store> @type plugin2 </store> </match>
-
若plugin1出現錯誤時,plugin2將不會被執行。若希望忽略不重要的store出現的錯誤時,可以指定該store的ignore_error引數。
<match app.**> @type copy <store ignore_error> @type plugin1 </store> <store> @type plugin2 </store> </match>