Flume拦截器,选择器

flume配置
详解:从一个logfile日志读取,然后在channel端添加拦截器,选择器发往不同的topic主题 从而实现事件的区分

a1.sources = r1
a1.channels = c1 c2
a1.sources.r1.type = TAILDIR
a1.sources.r1.positionFile = /var/log/flume/taildir_position.json
a1.sources.r1.filegroups = f1
a1.sources.r1.filegroups.f1 = /var/log/test1/example.log //监控一个目录 后面用拦截器将body的字段放入到header中,然后用选择器选择对应的header将其发往不同的topic主题
a1.sources.r1.fileHeader = true
a1.sources.r1.channels = c1 c2

#interceptor
a1.sources.r1.interceptors = i1 i2//这里的俩个拦截器分别发往不同的Topic的channel c1 和 c1
a1.sources.r1.interceptors.i1.type = org.apache.flume.interceptor.MyInterceptor$Builder//这里是咱自定义的拦截器,就是将body中的内容放入到header中
a1.sources.r1.interceptors.i2.type = org.apache.flume.sink.solr.morphline.UUIDInterceptor$Builder	//uuid拦截器 用来均匀的发往kafka中的分区
#selector
a1.sources.r1.selector.type = multiplexing//replicating和multiplexing的区别是replicating会将所有的事件复制到所有的channel端,而multiplexing依据指定的header值,将event路由至不同的channel,依据是检查header中的键值对与mapping中的配置的值是否是一致的。
a1.sources.r1.selector.header = topic//这里的header对应代码里的头部,从头部里进行选择,这里是KEY
a1.sources.r1.selector.mapping.topic_start = c1//发往c1的channel,这里是VALUE
a1.sources.r1.selector.mapping.topic_event = c2//发往c2的channel,这里是VALUE

#kafkachannel
a1.channels.c1.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c1.kafka.bootstrap.servers = kafka-1:9092,kafka-2:9092,kafka-3:9092
a1.channels.c1.kafka.topic = topic_start //当header中存在topic_start的话则发往此topic
a1.channels.c1.kafka.consumer.group.id = flume-consumer

a1.channels.c2.type = org.apache.flume.channel.kafka.KafkaChannel
a1.channels.c2.kafka.bootstrap.servers = kafka-1:9092,kafka-2:9092,kafka-3:9092
a1.channels.c2.kafka.topic = topic_event
a1.channels.c2.kafka.consumer.group.id = flume-consumer

package flumeDemo;

import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MyInterceptor implements Interceptor {
    @Override
    public void initialize() {
        //只需要实现处理出来 不需要写具体的方法

    }

@Override//具体的逻辑
public Event intercept(Event event) {

    //1.从body里面拿到数据,后面做关键字判断
    byte[] body = event.getBody();
    //将事件类型转换为UTF-8,我猜测这里应该是avro序列化所以无法直接识别
    String log = new String(body, Charset.forName("UTF-8"));

    //2.获取header
    Map<String, String> headers = event.getHeaders();

    //2.(json) 事件日志
    if (log.contains("start")) {
		//将topic 和topic_start放入头部,以kv键值对的方式,通过选择器发往不同的topic主题
        headers.put("topic", "topic_start");//a1.sources.r1.selector.mapping.topic_start=c1
    } else {

        headers.put("topic", "topic_event");//a1.sources.r1.selector.mapping.topic_event=c2
    }
    return event;
}

@Override//都是套路
public List<Event> intercept(List<Event> events) {
   //多条事件处理
    ArrayList<Event> interceptors=new ArrayList<>();
    for(Event en:events){

        Event intercept = intercept(en);
        if(intercept!=null)//判断事件不为null
        {
            interceptors.add(intercept);
        }
    }
        return interceptors;
}

@Override
public void close() {
    //只需要实现处理出来 不需要写具体的方法

}

public static class Builder implements Interceptor.Builder{
    //实现builder方法,在配置中没有机会修改

    @Override
    public Interceptor build() {
        return new MyInterceptor();
    }

    @Override
    public void configure(Context context) {

        //只需要实现处理出来 不需要写具体的方法
    }
}
}
### Apache Flume 拦截器的使用与配置 #### 什么是拦截器拦截器是 Apache Flume 的一个重要组成部分,主要用于对事件流中的数据进行处理和转换。通过拦截器,可以实现诸如添加元数据、过滤无用的数据、修改事件内容等功能[^1]。 --- #### 常见的内置拦截器及其功能 Flume 提供了一些常用的内置拦截器来简化开发工作: 1. **时间戳拦截器 (TimestampInterceptor)** 时间戳拦截器会自动为每个事件附加当前的时间戳字段。这对于后续基于时间维度分析数据非常有用。 2. **主机名拦截器 (HostInterceptor)** 主机名拦截器会在事件头信息中加入源主机的信息(如 IP 地址或主机名称),便于区分不同来源的数据。 3. **UUID 拦截器 (UuidInterceptor)** UUID 拦截器为每个事件生成唯一的标识符,有助于追踪单个事件在整个流水线中的流动情况。 4. **正则表达式过滤拦截器 (RegexFilterInterceptor)** 正则表达式过滤拦截器可以根据预设的匹配模式筛选符合条件的事件,从而丢弃不需要的日志记录或其他数据。 5. **摩尔斯码拦截器 (MorphlineInterceptor)** MorphlineInterceptor 是一种强大的工具,允许用户编写复杂的 ETL 脚本来执行高级别的日志解析任务。 以上这些标准插件可以直接应用于大多数场景下而无需额外编程支持[^2]。 --- #### 配置拦截器的方法 要启用某个特定类型的拦截器,在 flume-agent.conf 文件里按照如下模板设置即可: ```properties agent.sources.r1.interceptors = i1 agent.sources.r1.interceptors.i1.type = timestamp # 或其他类型比如 host, regex_filter 等 ``` 这里 `i1` 表示第一个使用的拦截器实例名字;`.type` 属性指定了具体采用哪种类别。如果需要同时应用多个,则继续扩展列表项数以及相应参数声明部分。 对于更复杂的情况——例如定制化逻辑或者组合多种行为时,则可能涉及到创建专属类文件并加载至运行环境中去调用它作为新的选项之一参与进来。 --- #### 自定义拦截器的设计思路 当现有的解决方案无法完全适配业务诉求的时候,开发者可以选择自行构建个性化的版本。以下是基本步骤概述: 1. 继承 org.apache.flume.interceptor.Interceptor 接口; 2. 实现 initialize() 方法完成初始化动作; 3. 完成 intercept(Event event) 函数主体用来单独作用于每一个传入对象之上; 4. 如果涉及批量操作的话还需要重写 intercept(List<Event> events); 5. 不忘记释放资源 close(); 下面给出一段简单的例子展示如何增加固定字符串前缀给每条消息体之前的内容片段: ```java public class PrefixAddingInterceptor implements Interceptor { private String prefix; public static class Builder implements Interceptor.Builder { private String prefix; @Override public void configure(Context context) { this.prefix = context.getString("prefix"); } @Override public Interceptor build() { return new PrefixAddingInterceptor(this.prefix); } } private PrefixAddingInterceptor(String prefix){ this.prefix=prefix; } @Override public Event intercept(Event event) { byte[] body=event.getBody(); String oldBody=new String(body); String newBody=this.prefix+oldBody; event.setBody(newBody.getBytes()); return event; } @Override public List<Event> intercept(List<Event> list) { ... } @Override public void close(){} } ``` 之后记得注册该组件并通过适当途径告知系统其存在位置以便动态引入利用起来[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值