Flume之实现和使用自定义Interceptor

冷暖自知 提交于 2020-03-06 00:12:49

前言

  • Flume Interceptor拦截器的作用在于能够在Event从Source传输到Channel过程中,修改或者删除Event的Header。多个拦截器Interceptor组成一个拦截器链,拦截器的执行顺序与配置顺序相同,上一个拦截器Interceptor处理后的Event List会传给下一个Interceptor
  • 在Flume中自定义Interceptor时,需要实现org.apache.flume.interceptor.Interceptor接口,以及创建静态内部类去实现org.apache.flume.interceptor.Interceptor.Builder接口
  • 更多详细内容可以参考《Flume构建高可用、可扩展的海量日志采集系统》

实现自定义Interceptor拦截器

1)根据使用场景创建Interceptor类

public class TypeInterceptor implements Interceptor {

    // 初始化时可以不做操作
    public void initialize() {
        // Do nothing
    }

    // 单个Event拦截
    public Event intercept(final Event event) {
        // 1.获取Event中的Header
        Map<String, String> headers = event.getHeaders();

        // 2.获取Event中的Body,将其转换成字符串String
        String body = new String(event.getBody());

        // 3.根据Body中数据向Header添加键值对,表明日志类型
        if (body.contains("cm")) {
            // 4.添加Header信息
            headers.put("type", "Startup");
        } else {
            // 4.添加Header信息
            headers.put("type", "Event");
        }
        return event;
    }


    // 批量Event拦截
    // 注意:既可以原Event集合进行修改,也可以创建新的Event集合作为成员变量,将此成员变量返回
    public List<Event> intercept(final List<Event> events) {
        for (Event event : events) {
            // 1.对每个Event采用单个Event拦截的方式进行处理,忽略其返回值
            intercept(event);
        }
        // 2.返回处理结果
        return events;
    }


    // 关闭时可以不作操作
    public void close() {
        // Do nothing
    }


    // 创建静态内部类实现Interceptor.Builder接口
    public static class Builder implements Interceptor.Builder {

        // 定义配置信息
        private Context context;

        // 定义Interceptor生成器
        public Interceptor build() {
            return new TypeInterceptor();
        }

        // 获取配置信息
        public void configure(Context context) {
            this.context = context;
        }
    }

}

2)将此Interceptor类打包,并将jar包放入flume/lib路径下

此路径在Flume运行时的ClassPath中,因而可以在flume配置文件中可以通过全类名指定使用的Interceptor.Builder类

Maven项目打包插件配置可以参考:《IDEA中配置Maven项目打包插件》


创建flume Agent配置文件

1)flume1.properties

# flume1:此配置用于监控单个或多个指定文件将其追加内容先通过自定义的TypeInterceptor
# 向Header中添加type字段,然后使用Multiplexing Channel Selector将不同type的Event
# 传输到不同的Channel中,最后分别输出到flume2和flume3的控制台
# a1:TailDir Source-> TypeInterceptor -> Multiplexing Channel Selector ->
#   Memory Channel -> Avro Sink

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

# Sources
# a1.sources.r1
a1.sources.r1.type = TAILDIR
# 设置Json文件存储路径(最好使用绝对路径)
# 用于记录文件inode/文件的绝对路径/每个文件的最后读取位置等信息
a1.sources.r1.positionFile = /opt/module/flume-1.8.0/.position/taildir_position.json
# 指定监控的文件组
a1.sources.r1.filegroups = f1
# 配置文件组中的被监控文件
# 设置f2组的监控文件,注意:使用的是正则表达式,而不是Linux通配符
a1.sources.r1.filegroups.f1 = /tmp/logs/^.*log$

# Interceptor
# a1.sources.r1.interceptors
# 配置Interceptor链,Interceptor调用顺序与配置循序相同
a1.sources.r1.interceptors = typeInterceptor
# 指定使用的自定义Interceptor全类名,并使用其中的静态内部类Builder
# 要想使用自定义Interceptor,必须将实现的类打包成jar包放入$FLUME_HOME/lib文件夹中
# flume运行Java程序时会将此路径加入到ClassPath中
a1.sources.r1.interceptors.typeInterceptor.type = com.tomandersen.interceptors.TypeInterceptor$Builder

# Channels
# a1.channels.c1
# 使用内存作为缓存/最多缓存的Event个数/单次传输的Event个数
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100
# a1.channels.c2
a1.channels.c2.type = memory
a1.channels.c2.capacity = 1000
a1.channels.c2.transactionCapacity = 100

# Channel Selector
# a1.sources.r1.selector
# 使用Multiple Channel Selector
a1.sources.r1.selector.type = multiplexing
# 设置匹配Header的字段
a1.sources.r1.selector.header = type
# 设置不同字段的值映射至各个Channel,其余的Event默认丢弃
a1.sources.r1.selector.mapping.Startup = c1
a1.sources.r1.selector.mapping.Event = c2

# Sinks
# a1.sinks.k1
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = hadoop102
a1.sinks.k1.port = 4141
# a1.sinks.k2
a1.sinks.k2.type = avro
a1.sinks.k2.hostname = hadoop103
a1.sinks.k2.port = 4141

# Bind
# r1->TypeInterceptor->Multiplexing Channel Selector->c1->k1
# r1->TypeInterceptor->Multiplexing Channel Selector->c2->k2
a1.sources.r1.channels = c1 c2
a1.sinks.k1.channel = c1
a1.sinks.k2.channel = c2

2)flume2.properties

# flume2:此配置用于将来自指定Avro端口的数据输出到控制台中
# a2:Avro Source->Memory Channel->Logger Sink

# Agent
a2.sources = r1
a2.channels = c1
a2.sinks = k1

# Sources
a2.sources.r1.type = avro
a2.sources.r1.bind = 0.0.0.0
a2.sources.r1.port = 4141

# Channels
a2.channels.c1.type = memory
a2.channels.c1.capacity = 1000
a2.channels.c1.transactionCapacity = 100

# Sinks
# 运行时设置参数 -Dflume.root.logger=INFO,console 即输出到控制台实时显示
a2.sinks.k1.type = logger
# 设置Event的Body中写入log的最大字节数(默认值为16)
a2.sinks.k1.maxBytesToLog = 256

# Bind
r1->c1->k1
a2.sources.r1.channels = c1
a2.sinks.k1.channel = c1

3)flume3.properties

# flume3:此配置用于将来自指定Avro端口的数据输出到控制台中
# a3:Avro Source->Memory Channel->Logger Sink

# Agent
a3.sources = r1
a3.channels = c1
a3.sinks = k1

# Sources
a3.sources.r1.type = avro
a3.sources.r1.bind = 0.0.0.0
a3.sources.r1.port = 4141

# Channels
a3.channels.c1.type = memory
a3.channels.c1.capacity = 1000
a3.channels.c1.transactionCapacity = 100

# Sinks
# 运行时设置参数 -Dflume.root.logger=INFO,console 即输出到控制台实时显示
a3.sinks.k1.type = logger
# 设置Event的Body中写入log的最大字节数(默认值为16)
a3.sinks.k1.maxBytesToLog = 256

# Bind
r1->c1->k1
a3.sources.r1.channels = c1
a3.sinks.k1.channel = c1

Flume Agent a1至a3分别运行在主机hadoop101、hadoop102、hadoop103上

4)对应功能

Flume Agent a1监听本地指定文件,将监听到的数据组装成Event通过自定义的 TypeInterceptor 来根据其Body中的内容向Header中添加不同的type字段键值,然后通过 Multiplexing Channel Selector将不同type的Event发送给不同的Channel,并最终分别在Flume Agent a2和a3的控制台上输出


End~

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!