Flume内置拦截器与自定义拦截器(代码实战)

官网上内置拦截器的表
在这里插入图片描述
由于拦截器一般针对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

猜你喜欢

转载自blog.csdn.net/gym02/article/details/111134106