Flume內建攔截器與自定義攔截器(程式碼實戰)

gym02發表於2020-12-13

官網上內建攔截器的表
在這裡插入圖片描述
由於攔截器一般針對Event的Header進行處理,這裡先介紹一下Event在這裡插入圖片描述

  • event是flume中處理訊息的基本單元,由零個或者多個header和body組成。
  • Header 是 key/value 形式的,可以用來製造路由決策或攜帶其他結構化資訊(如事件的時間戳或事件來源的伺服器主機名)。你可以把它想象成和 HTTP 頭一樣提供相同的功能——通過該方法來傳輸正文之外的額外資訊。
  • Body是一個位元組陣列,包含了實際的內容。
  • flume提供的不同source會給其生成的event新增不同的header。

flume內建的攔截器

- timestamp攔截器

Timestamp Interceptor攔截器就是可以往event的header中插入關鍵詞為timestamp的時間戳。

//先在flume安裝目錄下建立 job/interceptors/ 資料夾
//也可任意目錄執行
[root@flume0 job]# mkdir interceptors
[root@flume0 job]# cd interceptors/	
[root@flume0 interceptors]# touch demo1-timestamp.conf

#檔案內容如下
a1.sources = r1
a1.channels = c1
a1.sinks = k1

a1.sources.r1.type = netcat
a1.sources.r1.bind = flume0
a1.sources.r1.port = 44444

#timestamp interceptor
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = timestamp

a1.channels.c1.type = memory

a1.sinks.k1.type = logger

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

測試

[root@flume0 interceptors]# nc flume0 44444

測試結果

2020-04-11 03:54:14,179 (SinkRunner-PollingRunner-DefaultSinkProcessor) [INFO - org.apache.flume.sink.LoggerSink.process(LoggerSink.java:95)] Event: { headers:{timestamp=1586548451701} body: 68 65 6C 6C 6F

- host攔截器

該攔截器可以往event的header中插入關鍵詞預設為host的主機名或者ip地址(注意是agent執行的機器的主機名或者ip地址)

[root@flume0 interceptors]# touch demo2-host.conf

#檔案內容如下
a1.sources = r1
a1.channels = c1
a1.sinks = k1

a1.sources.r1.type = netcat
a1.sources.r1.bind = flume0
a1.sources.r1.port = 44444

#host interceptor
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = host

a1.channels.c1.type = memory

a1.sinks.k1.type = logger

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

測試

[root@flume0 interceptors]# nc flume0 44444

測試結果

	2020-04-11 04:04:09,954 (SinkRunner-PollingRunner-DefaultSinkProcessor) [INFO - org.apache.flume.sink.LoggerSink.process(LoggerSink.java:95)] Event: { headers:{host=192.168.150.61} body: 61 61 61   

- Regex Filtering Interceptor攔截器 (重要)

Regex Filtering Interceptor攔截器用於過濾事件,篩選出與配置的正規表示式相匹配的事件。可以用於包含事件和排除事件。常用於資料清洗,通過正規表示式把資料過濾出來。

[root@flume0 interceptors]# touch demo3-regex-filtering.conf

#檔案內容如下
a1.sources = r1
a1.channels = c1
a1.sinks = k1

a1.sources.r1.type = netcat
a1.sources.r1.bind = flume0
a1.sources.r1.port = 44444

#host interceptor
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = regex_filter
#全部是數字的資料
a1.sources.r1.interceptors.i1.regex = ^[0-9]*$
#排除符合正規表示式的資料  exclude排除   include包含
a1.sources.r1.interceptors.i1.excludeEvents  = true

a1.channels.c1.type = memory

a1.sinks.k1.type = logger

a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

Regex Filtering 實戰開發引用場景:排除錯誤日誌

測試結果

2007-02-13 15:22:26 [com.sms.test.TestLogTool]-[INFO] this is info
2007-02-13 15:22:26 [com.sms.test.TestLogTool]-[ERROR] my exception  com.sms.test.TestLogTool.main(TestLogTool.java:8)

多個攔截器可以同時使用,例如:

# 攔截器:作用於Source,按照設定的順序對event裝飾或者過濾

a1.sources.r1.interceptors = i1 i2 i3
a1.sources.r1.interceptors.i1.type = timestamp
a1.sources.r1.interceptors.i2.type = host
a1.sources.r1.interceptors.i3.type = regex_filter
a1.sources.r1.interceptors.i3.regex = ^[0-9]*$

自定義攔截器

概述:在實際的開發中,一臺伺服器產生的日誌型別可能有很多種,不同型別的日誌可能需要傳送到不同的分析系統。此時會用到 Flume 拓撲結構中的 Multiplexing 結構,Multiplexing的原理是,根據 event 中 Header 的某個 key 的值,將不同的 event 傳送到不同的 Channel中,所以我們需要自定義一個 Interceptor,為不同型別的 event 的 Header 中的 key 賦予不同的值。

案例演示:我們以埠資料模擬日誌,以數字(單個)和字母(單個)模擬不同型別的日誌,我們需要自定義 interceptor 區分數字和字母,將其分別發往不同的分析系統(Channel)。

實現步驟
1.建立一個專案,並且引入以下依賴

<dependency>
    <groupId>org.apache.flume</groupId>
    <artifactId>flume-ng-core</artifactId>
    <version>1.9.0</version>
</dependency>

2.自定義攔截器,實現攔截器介面

//示例程式碼中是區分測試資料子母和數字
public class MyInterceptor implements Interceptor {
    @Override
    public void initialize() {

    }

    @Override
    public Event intercept(Event event) {
        byte[] body = event.getBody();
        if (body[0] >= 'a' && body[0] <= 'z'){
            event.getHeaders().put("type","letter");
        }else if (body[0] >= '0' && body[0] <= '9'){
            event.getHeaders().put("type","number");
        }
        return event;
    }

    @Override
    public List<Event> intercept(List<Event> list) {
        for (Event event : list) {
            intercept(event);
        }
        return list;
    }

    @Override
    public void close() {

    }

    public static class Builder implements Interceptor.Builder{

        @Override
        public Interceptor build() {
            return new MyInterceptor();
        }

        @Override
        public void configure(Context context) {

        }
    }

}

3.將專案打成jar包,上傳到flume安裝目錄的lib目錄下
4.編寫agent,在flume安裝目錄下(可自行新建一個資料夾),可命名為demo01.conf

a1.sources = r1
a1.channels = c1 c2
a1.sinks = k1 k2

a1.sources.r1.type = netcat
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 44444

a1.sources.r1.interceptors = i1
#此處為類方法的全類名
a1.sources.r1.interceptors.i1.type = com.demo.MyInterceptor$Builder

a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = type
a1.sources.r1.selector.mapping.letter = c1
a1.sources.r1.selector.mapping.number = c2
a1.sources.r1.selector.default  = c2

a1.channels.c1.type = memory
a1.channels.c2.type = memory

#輸出的路徑
a1.sinks.k1.type = file_roll
a1.sinks.k1.sink.directory  = /root/t1
a1.sinks.k1.sink.rollInterval = 600

#輸出的路徑
a1.sinks.k2.type = file_roll
a1.sinks.k2.sink.directory = /root/t2
a1.sinks.k1.sink.rollInterval = 600


a1.sources.r1.channels = c1 c2
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c2

5.在/root目錄下建立t1、t2資料夾(與配置檔案中配置的路徑相符,可根據情況自行修改)
6.測試

[root@flume0 apache-flume-1.9.0-bin]# bin/flume-ng agent --conf conf --name a1 --conf-file job/interceptors/my.conf -Dflume.roogger=INFO,console

相關文章