事件(Event)是Fluentd内部處理流程使用的資料結構,日志記錄一旦進入Fluentd便被封裝成一個event。Event由三部分組成:tag、time、record。
- tag: 辨別事件的來源,或者說類型,用于内部消息路由,即後續交由哪個插件處理;
- time: 是事件的發生時間;
- record: 為日志的實際内容,這是一個JSON對象。
Input插件負責将源資料封裝為event,比如input_tail插件從文本中生成event。對于下邊這行文本:
192.168.0.1 - - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777
将會産生下邊的event對象:
tag: apache.access #根據插件的tag參數來設定
time: 1362020400 # 28/Feb/2013:12:00:00 +0900
record: {"user":"-","method":"GET","code":200,"size":777,"host":"192.168.0.1","path":"/"} #根據input_tail插件中的parse項來決定如何解析單行日志記錄,并生成相應的JSON對象
通過一個具體的配置來講解事件的處理過程。
本例使用一個很基礎的配置片段來描述各插件是如何關聯到一起的,它包括了如何定義輸入源(或者說監聽器),以及如何設定通用的比對規則将event路由到輸出端。
我們使用input_http和output_stdout這兩個插件來描述event的循環過程。
<source>
@type http
@id input_http
port 8888
</source>
上邊的配置使用input_http插件定義了一個HTTP伺服器,監聽端口為8888。然後我們再定義一個比對(Match)規則,event路由引擎會根據這個規則将http請求派發到輸出端。這裡的輸出端是stdout,僅僅将http請求列印到螢幕上。
<match test.cycle>
@type stdout
@id output_stdout
</match>
Match的作用是設定一個比對規則test.cycle,對于每個進入Fluentd的event,如果其tag值和test.cycle相等(或者說比對,因為match可以使用通配符。這裡的tag是由input_http插件生成的。),那麼這個event就會進入此match定義的output插件,本例中的output插件就是output_stdout。
至此,我們定義了三個基本項:Input、Match和Output,雖然僅僅使用兩個配置段。這就是一個可以使用的采集配置了,可以通過以下指令進行測試:
curl -i -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.cycle
會看到如下輸出:
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: Keep-Alive
Content-Length: 0
在/var/log/td-agent/td-agent.log中會有如下輸出:
2020-11-03 14:34:09.624879668 +0800 test.cycle: {"action":"login","user":2}
下邊開始了解一下事件是如何被處理和改變的。
當你準備好一個采集配置後,Fluentd就生成了用以處理輸入資料的各種規則。日志事件會曆經一系列的處理流程,進而決定了事件的循環周期。
1.過濾器(Filters)
過濾器用于對事件進行篩選,決定是否接收或者丢棄事件。我們可以在上邊的示例中增加一個過濾器。
<source>
@type http
@id input_http
bind 0.0.0.0
port 8888
</source>
<filter test.cycle>
@type grep
<exclude>
key action
pattern ^logout$
</exclude>
</filter>
<match test.cycle>
@type stdout
@id output_stdout
</match>
添加過濾器之後,事件在路由到match之前必須經過過濾器的處理。過濾器根據事件的類型和過濾規則來決定是否接受此事件。
示例中使用的是grep過濾器,這個過濾器對test.cycle這類事件進行過濾,會排除http請求中action值為logout的事件。
是以,如果嘗試發送下邊的請求,在td-agent.log中是看不到任何輸出的。
curl -i -X POST -d 'json={"action":"logout","user":2}' http://localhost:8888/test.cycle
從示例中可以看到,事件是根據配置順序自上而下來被處理的。我們可以根據需要配置任意多個過濾器,這樣一來,配置檔案會變得很長很複雜。Fluentd提供了标簽來解決此問題。
2.标簽(Labels)
标簽的作用是用來定義一組配置項,這組配置項可以被其他配置項引用,進而實作事件路由跳轉。類似程式設計語言中的goto的功能。
還是上邊的示例,我們定義一個标簽來看一下效果。
<source>
@type http
@id input_http
bind 0.0.0.0
port 8888
@label @STAGING
</source>
<filter test.cycle>
@type grep
<exclude>
key action
pattern ^logout$
</exclude>
</filter>
<label @STAGING>
<filter test.cycle>
@type grep
<exclude>
key action
pattern ^login$
</exclude>
</filter>
<match test.cycle>
@type stdout
@id output_stdout
</match>
</label>
這個STARTING标簽将之前的filter和match封裝到了一起,然後在source中進行了引用。如此一來,事件由input插件生成後将會跳過那個獨立的filter,直接進入STARTING定義的處理流程中。
# 如下這個沒有輸出,因為跳過了獨立的filter
curl -i -X POST -d 'json={"action":"logout","user":2}' http://localhost:8888/test.cycle
# 如下這個有輸出,直接進入STARTING定義的處理流程中開始filter
curl -i -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.cycle
這種效果可以實作一些特定的處理邏輯,讓事件快速到達指定目的地。