大数据技术之Flume 企业开发案例——自定义 Interceptor(8)

目录

自定义 Interceptor

1)案例需求

2)需求分析

3)实现步骤

创建一个 Maven 项目,并引入以下依赖。

定义 CustomInterceptor 类并实现 Interceptor 接口。

编辑 flume 配置文件

分别在 hadoop12,hadoop13,hadoop14 上启动 flume 进程,注意先后顺序。

在 hadoop12 使用 netcat 向 localhost:44444 发送字母和数字。

观察 hadoop13 和 hadoop14 打印的日志。


自定义 Interceptor

1)案例需求

使用 Flume 采集服务器本地日志,需要按照日志类型的不同,将不同种类的日志发往不同的分析系统。

2)需求分析

在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。此时会用到 Flume 拓扑结构中的 Multiplexing 结构,Multiplexing 的原理是,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel 中。所以我们需要自定义一个 Interceptor,为不同类型的 event 的 Header 中的 key 赋予不同的值。

在该案例中,我们以端口数据模拟日志,以是否包含“lzl”模拟不同类型的日志,我们需要自定义 interceptor 区分数据中是否包含“lzl”,将其分别发往不同的分析系统(Channel)。

3)实现步骤

  1. 创建一个 Maven 项目,并引入以下依赖。
    
        org.apache.flume
        flume-ng-core
        1.9.0
    
  2. 定义 CustomInterceptor 类并实现 Interceptor 接口。
    package com.lzl.interceptor;
    
    import org.apache.flume.Context;
    import org.apache.flume.Event;
    import org.apache.flume.interceptor.Interceptor;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    public class TypeInterceptor implements Interceptor {
    
        // 声明一个存放事件的集合
        private List addHeaderEvents;
    
        @Override
        public void initialize() {
            // 初始化存放事件的集合
            addHeaderEvents = new ArrayList<>();
        }
    
        // 单个事件拦截
        @Override
        public Event intercept(Event event) {
            // 1. 获取事件中的头信息
            Map headers = event.getHeaders();
            // 2. 获取事件中的 body 信息
            String body = new String(event.getBody());
            // 3. 根据 body 中是否有"lzl"来决定添加怎样的头信息
            if (body.contains("lzl")) {
                // 4. 添加头信息
                headers.put("type", "first");
            } else {
                // 4. 添加头信息
                headers.put("type", "second");
            }
            return event;
        }
    
        // 批量事件拦截
        @Override
        public List intercept(List events) {
            // 1. 清空集合
            addHeaderEvents.clear();
            // 2. 遍历 events
            for (Event event : events) {
                // 3. 给每一个事件添加头信息
                addHeaderEvents.add(intercept(event));
            }
            // 4. 返回结果
            return addHeaderEvents;
        }
    
        @Override
        public void close() {
        }
    
        public static class Builder implements Interceptor.Builder {
    
            @Override
            public Interceptor build() {
                return new TypeInterceptor();
            }
    
            @Override
            public void configure(Context context) {
            }
    
        }
    
    }
  3. 编辑 flume 配置文件

    hadoop12 上的 Flume1 配置 1 个 netcat source,1 个 sink group(2 个 avro sink),并配置相应的 ChannelSelectorinterceptor

    # Name the components on this agent
    a1.sources = r1
    a1.sinks = k1 k2
    a1.channels = c1 c2
    
    # Describe/configure the source
    a1.sources.r1.type = netcat
    a1.sources.r1.bind = localhost
    a1.sources.r1.port = 44444
    a1.sources.r1.interceptors = i1
    a1.sources.r1.interceptors.i1.type = com.lzl.flume.interceptor.TypeInterceptor$Builder
    a1.sources.r1.selector.type = multiplexing
    a1.sources.r1.selector.header = type
    a1.sources.r1.selector.mapping.first = c1
    a1.sources.r1.selector.mapping.second = c2
    
    # Describe the sink
    a1.sinks.k1.type = avro
    a1.sinks.k1.hostname = hadoop13
    a1.sinks.k1.port = 4141
    a1.sinks.k2.type=avro
    a1.sinks.k2.hostname = hadoop14
    a1.sinks.k2.port = 4242
    
    # Use a channel which buffers events in memory
    a1.channels.c1.type = memory
    a1.channels.c1.capacity = 1000
    a1.channels.c1.transactionCapacity = 100
    
    # Use a channel which buffers events in memory
    a1.channels.c2.type = memory
    a1.channels.c2.capacity = 1000
    a1.channels.c2.transactionCapacity = 100
    
    # Bind the source and sink to the channel
    a1.sources.r1.channels = c1 c2
    a1.sinks.k1.channel = c1
    a1.sinks.k2.channel = c2

    hadoop13 上的 Flume4 配置一个 avro source 和一个 logger sink

    a1.sources = r1
    a1.sinks = k1
    a1.channels = c1
    
    a1.sources.r1.type = avro
    a1.sources.r1.bind = hadoop13
    a1.sources.r1.port = 4141
    
    a1.sinks.k1.type = logger
    
    a1.channels.c1.type = memory
    a1.channels.c1.capacity = 1000
    a1.channels.c1.transactionCapacity = 100
    
    a1.sinks.k1.channel = c1
    a1.sources.r1.channels = c1

    hadoop14 上的 Flume3 配置一个 avro source 和一个 logger sink

    a1.sources = r1
    a1.sinks = k1
    a1.channels = c1
    
    a1.sources.r1.type = avro
    a1.sources.r1.bind = hadoop14
    a1.sources.r1.port = 4242
    
    a1.sinks.k1.type = logger
    
    a1.channels.c1.type = memory
    a1.channels.c1.capacity = 1000
    a1.channels.c1.transactionCapacity = 100
    
    a1.sinks.k1.channel = c1
    a1.sources.r1.channels = c1
  4. 分别在 hadoop12,hadoop13,hadoop14 上启动 flume 进程,注意先后顺序。
  5. 在 hadoop12 使用 netcat 向 localhost:44444 发送字母和数字。
  6. 观察 hadoop13 和 hadoop14 打印的日志。

你可能感兴趣的:(Flume,flume,大数据)