鉴定Flume可以对数据进行简单处理,有一个需求是接收syslog格式的数据写入kafka,如果收到了非syslog数据,则分发到异常的kafka topic里做一个记录,或者对数据过滤完成初步的数据清洗。通过拦截器Interceptor实现不同的功能。Source将同一个事务的所有事件event传递给Channel处理器,进而依次可以传递给多个拦截器,直至从最后一个拦截器中返回的最终事件event写入到对应的Channel中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rN2qJJVK-1595242271776)(http://www.luran.name/upload/9c290d5712554f20bbc21c7ec08f3fdc_77.png)]
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指定多个拦截器,按先后顺序依次处理。
本文主要介绍的自定义拦截器,基于实际业务来处理,对于大数据日志收集有很好的参考作用。
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)]
Flume能够在写入Channel之前对日志进行一次简单处理,比如加入时间戳、匹配字段、分流等,都是生产环境中常见的需求。
参考博文:
# flume学习(四):Flume Interceptors的使用
# flume拦截器及问题解决
# Flume–Event定义及源码解析