天天看點

2. Fluentd事件的生命周期

事件(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 
           

這種效果可以實作一些特定的處理邏輯,讓事件快速到達指定目的地。