flume之自定义拦截器

在flume接收数据时,有时候数据很杂乱,可以通过自定义拦截器,对数据进行拦截或者处理,这样就可以简单的对数据进行数据清洗了,下面是一个自定义的拦截器,把数据通过拦截器变成json格式的数据

在定义拦截器时可以参数官方给定的拦截器进行编写,比如TimestampInterceptor

import com.alibaba.fastjson.JSONObject;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JsonInterceptor  implements org.apache.flume.interceptor.Interceptor {

    private String[] schema; //元数据 id,name,age
    private String separator;//数据的分割符

    public  JsonInterceptor(String schema,String separator){
        this.separator = separator;
        //字段名以 都逗号分割
        this.schema = schema.split("[,]");
    }

    @Override
    public void initialize() {
        //什么都不做
    }

    @Override
    public Event intercept(Event event) {
        //传递引用,对数据进行修改在传给 events
        Map<String,String> tuple =  new LinkedHashMap<>(); //LinkedhashMap是有序的
        String line = new String(event.getBody());
        final String[] datas = line.split(separator);//对传的数据进行切分后再变换成json格式
        for(int i= 0 ;i<schema.length;i++){
            String key = schema[i];
            String value = datas[i];
            tuple.put(key,value);
        }

        //通过fastJson 把Map类型转换成Json格式的数据
        final String json = JSONObject.toJSONString(tuple);
        //重新复制event的Body
        event.setBody(json.getBytes());
        return event;
    }

    @Override
    public List<Event> intercept(List<Event> events) {  //这个方法是在source传数据 进行批量传输,一条一条传输会直接调用上面的方法
        for(Event e : events){
            intercept(e);//传递的是引用,所以此处的events中的改变了原数据,所以不用接收返回值
        }
        return events;//返回就是把对原始的event进行处理后返回
    }

    @Override
    public void close() {

    }

    /*
    Interceptor.builder的生名周期是
    构造器 -> configure -> builder
     */
    public static class Builder implements Interceptor.Builder{
        private String fields;
        private String separator;
        @Override
        public Interceptor build() {
            //在build创建JsonInterceptor 的实例
            return new JsonInterceptor(fields,separator);
        }

        /*configure 方法 读取配置文件
          配置文件的属性
          1、数据的分割符
          2、字段的名字
          3、数据的分割符
         */
        @Override
        public void configure(Context context) {
            fields = context.getString("fields");
            separator = context.getString("separator");

        }
    }


}


配置文件


#定义agent名, source、channel、sink的名称
a0.sources = r1
a0.channels = c1

#具体定义source
a0.sources.r1.type =exec
a0.sources.r1.command = tail -F /data/logs.txt


#拦截器,拦截器是配置在source后面的
a0.sources.r1.interceptors = i1
#$Builder 相当于一个内部类,new 一个内部类
a0.sources.r1.interceptors.i1.type = com.yt.flume.source.JsonInterceptor$Builder
#都有哪些字段名,字段名用什么分割
a0.sources.r1.interceptors.i1.fields = id,name,age
#分隔符是什么,数据的分割符
a0.sources.r1.interceptors.i1.separator = ,

a0.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a0.channels.c1.brokerList = bigdata01:9092,bigdata02:9092,bigdata03:9092
a0.channels.c1.zookeeperConnect=192.168.136.150:2181
a0.channels.c1.topic = userJson1
#false表示是以纯文本的形式写进入的,true是以event的形式写进入的,以event写进入时,会出现乱码, 默认是true
a0.channels.c1.parseAsFlumeEvent = false
a0.sources.r1.channels = c1

在flume中执行

/home/bigdata/install/apache-flume-1.5.0-cdh5.3.6-bin/bin/flume-ng agent --conf conf/ --name a0  --conf-file /home/bigdata/install/apache-flume-1.5.0-cdh5.3.6-bin/job/kafkacannel.conf  -Dflume.root.logger==INFO,console

开启kafka的消费者

kafka-console-consumer.sh --bootstrap-server 192.168.136.150:9092,192.168.136.151:9092,192.168.136.152:9092 --topic userJson1 --from-beginning

手动增加文件内容

echo "1,laoli,36">> /data/logs.txt

可以看到如下结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Lu_Xiao_Yue/article/details/85226615