flume自定义拦截器

1.背景介绍

鉴定Flume可以对数据进行简单处理,有一个需求是接收syslog格式的数据写入kafka,如果收到了非syslog数据,则分发到异常的kafka topic里做一个记录,或者对数据过滤完成初步的数据清洗。通过拦截器Interceptor实现不同的功能。Source将同一个事务的所有事件event传递给Channel处理器,进而依次可以传递给多个拦截器,直至从最后一个拦截器中返回的最终事件event写入到对应的Channel中。

2.架构图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rN2qJJVK-1595242271776)(http://www.luran.name/upload/9c290d5712554f20bbc21c7ec08f3fdc_77.png)]

3.官方拦截器

  • Timestamp Interceptor

    在event的header中添加一个key叫:timestamp,value为当前的时间戳。
    
  • Host Interceptor

    在event的header中添加一个key叫:host,value为当前机器的hostname或者ip。
    
  • Static Interceptor

    可以在event的header中添加自定义的key和value。
    
  • Regex Filtering Interceptor

    通过正则来清洗或包含匹配的events。
    
  • Regex Extractor Interceptor

    通过正则表达式来在header中添加指定的key,value则为正则匹配的部分
    

像很多java的开源项目如springmvc中的拦截器一样,flume的拦截器也是chain形式的,可以对一个source指定多个拦截器,按先后顺序依次处理。

4.自定义拦截器

本文主要介绍的自定义拦截器,基于实际业务来处理,对于大数据日志收集有很好的参考作用。

Event概念

flume的核心就是把数据从数据源(source)收集过来,再将收集到的数据送到指定的目的地(sink)。为了保证输送的过程一定成功,在送到目的地之前,会先缓存数据(channel),待数据真正的送到目的地(sink)后,flume再删除缓存中的数据(channel中的数据)。

一行文本内容被反序列化成一个event。event的最大定义为2048字节,超过会被切割放到下一个event中。

源码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ff9OqglD-1595242271779)(http://www.luran.name/upload/7fc0b71e73514a88bce20628c92c77d1_88.png)]

header是一个map,body是一个字节数组,body是真正传输的数据,header传输的数据不会被sink出去。通过header去区别对待不同的event,然后在sink端的时候,我们就可以通过header中的key来将不同的event输出到对应的sink下游去

具体实现

需要实现Interceptor接口

public interface Interceptor {
     
/* 任何需要拦截器初始化或者启动的操作就可以定义在此,无则为空即可 */
public void initialize();
/* 每次只处理一个Event */
public Event intercept(Event event){
     
    String msg = "";
    Map<String, String> headers = new HashMap<String, String>();
    try {
     
        msg = new String(event.getBody(), "UTF-8");
        JSONParser parser = new JSONParser();
        JSONObject msgJson = (JSONObject) parser.parse(msg);
    } catch (Exception e) {
     
        headers.put("topic", "flume_error");
        event.setHeaders(headers);
    }
    return event;
}
/* 量处理Event */
public List<Event> intercept(List<Event> events);
/*需要拦截器执行的任何closing/shutdown操作,一般为空 */
public void close();
/* 获取配置文件中的信息,必须要有一个无参的构造方法 */
public interface Builder extends Configurable {
     
public Interceptor build();
}
}

将工程打包成jar,放到flume的lib目录下,接着在agent配置文件中指定

syslog.sources.src-tcp-1.interceptors = i1
syslog.sources.src-tcp-1.interceptors.i1.type = xx.interceptor.SyslogInterceptor$Builder

测试

1、发送正常syslog数据:

<14>Dec 24 14:19:16 TIP {
     "log_type":"mdevice_info"}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nngwNdi0-1595242271783)(http://www.luran.name/upload/b490074356db4e72ad8335b76d1b64b0_1111.png)]

2、发送非syslog数据:

14>Dec 24 14:19:16 TIP {
     "log_type":"mdevice_info"}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rb6MHGLl-1595242271785)(http://www.luran.name/upload/384b5f99ae534b6c9d32ae1b7581498f_2222.png)]

5.总结

Flume能够在写入Channel之前对日志进行一次简单处理,比如加入时间戳、匹配字段、分流等,都是生产环境中常见的需求。


参考博文:
# flume学习(四):Flume Interceptors的使用
# flume拦截器及问题解决
# Flume–Event定义及源码解析

你可能感兴趣的:(Flume)