官网上内置拦截器的表
由于拦截器一般针对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