Flume-1.9.0安装、监听端口、监控本地文件并上传HDFS、监控目录新文件并上传HDFS、监控追加文件(断点续传)
自定义拦截器
使用Flume采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不同的分析系统。
在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。此时会用到Flume拓扑结构中的Multiplexing结构,Multiplexing的原理是,根据event中Header的某个key的值,将不同的event发送到不同的Channel中,所以我们需要自定义一个Interceptor,为不同类型的event的Header中的key赋予不同的值。
拦截器除了可以将不同类型的日志发往不同的地方,还可以过滤指定的事件。
下面Flume1监听端口,自定义一个拦截器,如果接收到的数据为字符串“hello”,则将其传给Flume2;否则将字符串改为“good morning”,并将其传给Flume3.
-
添加依赖
<dependency> <groupId>org.apache.flume</groupId> <artifactId>flume-ng-core</artifactId> <version>1.7.0</version> </dependency>
-
定义一个类并实现Interceptor接口,一定要记得写Builder内部类。然后打包放到flume目录下的lib目录。
package flume;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;
public class DIYInterceptor implements Interceptor {
public List<Event> list = null;
public void initialize() {
list = new ArrayList<Event>();
}
public Event intercept(Event event) {
Map<String, String> header = event.getHeaders();
String body = new String(event.getBody());
if (body.contains("hello")) {
header.put("isHello", "hello");
}else {
header.put("isHello", "other");
event.setBody("good morning".getBytes());
}
event.setHeaders(header);
return event;
}
public List<Event> intercept(List<Event> events) {
list.clear();
for (Event event : events) {
list.add(intercept(event));
}
return list;
}
public void close() {
}
public static class Builder implements Interceptor.Builder {
public void configure(Context context) {
}
public Interceptor build() {
return new DIYInterceptor();
}
}
}
-
编写配置文件flume1,flume2,flume3:
flume1的source的类型是netcat,监听端口。Channel Selector的类型是multiplexing,事件如果被设置为“hello”则选择c1这个channel,否则选择c2。注意拦截器interceptor的类型需要全类名以及内部类Builder。sink的类型是avro,对接另外两个Agent。# Name the components on this agent a1.sources = r1 a1.channels = c1 c2 a1.sinks = k1 k2 # Describe/configure the source a1.sources.r1.type = netcat a1.sources.r1.bind = master a1.sources.r1.port = 33333 # Describe the channel selector a1.sources.r1.selector.type = multiplexing a1.sources.r1.selector.header = isHello a1.sources.r1.selector.mapping.hello = c1 a1.sources.r1.selector.mapping.other = c2 # Describe the interceptor a1.sources.r1.interceptors = i1 a1.sources.r1.interceptors.i1.type = flume.DIYInterceptor$Builder # Describe the sink a1.sinks.k1.type = avro a1.sinks.k1.hostname = master a1.sinks.k1.port = 44444 a1.sinks.k2.ty