案例七:Flume自定义拦截器
在此案例中,实现:将小写字母转换成大写字母
一、配置Pom.xml文件
<dependencies> <!-- flume核心依赖 --> <dependency> <groupId>org.apache.flume</groupId> <artifactId>flume-ng-core</artifactId> <version>1.8.0</version> </dependency> </dependencies> <build> <plugins> <!-- 打包插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass></mainClass> </manifest> </archive> </configuration> </plugin> <!-- 编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf-8</encoding> </configuration> </plugin> </plugins> </build> |
二、自定义实现拦截器-代码实现
1.首先,在java包里创建一个Package--flume,再在这个包里创建一个类-MyInterceptor(自定义拦截器)
2.代码实现
1 package flume;
2
3 import org.apache.flume.Context;
4 import org.apache.flume.Event;
5 import org.apache.flume.interceptor.Interceptor;
6
7 import java.util.ArrayList;
8 import java.util.List;
9
10 public class MyInterceptor implements Interceptor {
11
12 @Override
13 public void initialize() {
14
15 }
16
17 /**
18 * 拦截器实现方法
19 * @param event 一个事件 ,封装一行的数据 ,有header和body(具体的数据)
20 * @return
21 */
22 @Override
23 public Event intercept(Event event) {
24 //获取数据body
25 byte[] oldbody = event.getBody();
26 //将数据转换为大写
27 byte[] bytes = new String(oldbody).toUpperCase().getBytes();
28 //封装-setBody()没有返回值,所以不能在return里面写
29 event.setBody(bytes);
30 // 返回
31 return event;
32 }
33
34 @Override
35 public List<Event> intercept(List<Event> list) {
36 ArrayList<Event> eventArrayList = new ArrayList<>();
37 //循环将每个事件的数据转换成大写
38 for(Event event:list){
39 eventArrayList.add(intercept(event));
40 }
41 return eventArrayList;
42 }
43
44 /**
45 * 关闭资源
46 */
47 @Override
48 public void close() {
49
50 }
51
52 //定义一个内部类
53 public static class Builder implements Interceptor.Builder{
54
55 @Override
56 public Interceptor build() {
57 return new MyInterceptor();
58 }
59
60 @Override
61 public void configure(Context context) {
62
63 }
64 }
3.目前还不能运行,因为要调用flume的底层配置。
所以接下来要对该代码进行打包:
1)使用Maven做成Jar包:
(1)点击右侧竖条的Maven--》选择里面的Lifecycle中的clean
(2)然后再点击下面的package进行打包
(3)包打完之后看log找到包的所在位置:
[INFO]Buildingjar:D:\idealC\JavaProject\zookeeper\target\zookeeper-1.0-SNAPSHOT.jar
或者看IDEA左侧target/maven-archiver里,那也有刚打好的包。
2)上传jar包
(1)跳到此目录下:/opt/module/flume-1.8.0/lib
(2)上传此jar到此jar目录中,拖拽上传即可
3)配置新的自定义的拦截器
(1)转到/opt/module/flume-1.8.0/myconf/目录下
(2)创建配置文件
[root@bigdata111 myconf]# vi flume-myInterceptor.conf
(3)添加配置(配置文件如下)、保存离开
#1 agent a1.sources = r1 a1.sinks = k1 a1.channels = c1
#2 source a1.sources.r1.type = exec a1.sources.r1.command = tail -F /opt/plus
#定义拦截器 a1.sources.r1.interceptors = i1 #拦截器类型-IDEA里定义的内部类Builder--右键--》Copy Reference复制--》粘贴(全类名) #注意:下面自定义类名前面符号应该是$,而不是"." #就是粘贴之后要检查并将其改过来 a1.sources.r1.interceptors.i1.type = flume.MyInterceptor$Builder
a1.sinks.k1.type = logger
a1.channels.c1.type = memory a1.channels.c1.capacity = 1000 a1.channels.c1.transactionCapacity = 100
a1.sources.r1.channels = c1 a1.sinks.k1.channel = c1 |
4.执行:
[root@bigdata111 myconf]# flume-ng agent -c ../conf/ -n a1 -f flume-myInterceptor.conf -Dflume.root.logger==INFO,console
5.看到正确结果:
(1)查看检测的plus文件内容:
(2)执行后的logger:
(3)分析:
从这可以看出,通过自定义拦截器已经可以实现:将小写字母转换成大写。
纯数字的Event也会被接收:
比如这里再向plus文件里添加数据:999
[root@bigdata111 opt]# echo 999 >> plus
从logger里能够看到,接收成功。
6.易出现的问题-类找不到,logger报错
查看日志发现问题-类找不到:
这是因为配置文件的全类名前面的符号$被粘贴成了"."因此找不到类,报错。比如下面的例子:
#定义拦截器 a1.sources.r1.interceptors = i1 #拦截器类型-IDEA里定义的内部类Builder--右键--》Copy Reference复制--》粘贴(全类名) #注意:下面自定义类名前面符号应该是$,此处是错误的 #就是粘贴之后要检查并将其改过来 a1.sources.r1.interceptors.i1.type = flume.MyInterceptor.Builder |
接下来解决:
(1)打开.jar包的所在位置-并用压缩软件打开此jar压缩包
(2)按照全类名找到最终的文件,并将其名字复制一下,再重新粘贴到配置文件中。
(3)删除原来上传的jar包、再次生成jar包并重新上传,然后启动执行。