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

在实际的开发中,一台服务器产生的日志类型可能有很多种,不同类型的日志可能需要发送到不同的分析系统。

此时会用到 Flume 拓扑结构中的 Multiplexing 结构,Multiplexing的原理是,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel中,所以我们需要自定义一个 Interceptor,为不同类型的 event 的 Header 中的 key 赋予 不同的值。

这里以端口数据模拟日志,以数字(单个)和字母(单个)模拟不同类型的日志,需要自定义 interceptor 区分数字和字母,将其分别发往不同的分析系统(Channel)。

一、创建自定义拦截器

https://flume.apache.org/FlumeUserGuide.html#flume-interceptors

1.引入 pom 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com</groupId>
<artifactId>flume</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>org.apache.flume</groupId>
<artifactId>flume-ng-core</artifactId>
<version>1.9.0</version>
</dependency>
</dependencies> <build>
<plugins>
<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>
</project>

2.编写拦截器类

package interceptor;

import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor; import java.util.List; public class CustomInterceptor implements Interceptor {
@Override
public void initialize() { } // 单个事件拦截
@Override
public Event intercept(Event event) {
byte[] body = event.getBody();
if (body[0] < 'z' && body[0] > 'a') {
// 自定义头信息
event.getHeaders().put("type", "letter");
} else if (body[0] > '0' && body[0] < '9') {
// 自定义头信息
event.getHeaders().put("type", "number");
}
return event;
} // 批量事件拦截
@Override
public List<Event> intercept(List<Event> list) {
for (Event event : list) {
intercept(event);
}
return list;
} @Override
public void close() { } public static class Builder implements Interceptor.Builder {
@Override
public Interceptor build() {
return new CustomInterceptor();
} @Override
public void configure(Context context) {
}
}
}

二、打包测试

1.打包上传

将项目打包。

上传到 flume 的 lib 目录下。

2.编写 flume 配置文件

1.flume1

配置 1 个 netcat source,1 个 sink group(2 个 avro sink),并配置相应的 ChannelSelector 和 interceptor。

# 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 = 127.0.0.1
a1.sources.r1.port = 4444 # 拦截器
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = interceptor.CustomInterceptor$Builder # 选择器
a1.sources.r1.selector.type = multiplexing
a1.sources.r1.selector.header = type
# 与自定义拦截器中设置的头信息对应
a1.sources.r1.selector.mapping.letter = c1
a1.sources.r1.selector.mapping.number = c2 # Describe the sink
a1.sinks.k1.type = avro
a1.sinks.k1.hostname = 127.0.0.1
a1.sinks.k1.port = 4141 a1.sinks.k2.type=avro
a1.sinks.k2.hostname = 127.0.0.1
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 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

2.flume2

配置一个 avro source 和一个 logger sink。

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

3.flume3

配置一个 avro source 和一个 logger sink。

a3.sources = r1
a3.sinks = k1
a3.channels = c1 a3.sources.r1.type = avro
a3.sources.r1.bind = 127.0.0.1
a3.sources.r1.port = 4242 a3.sinks.k1.type = logger a3.channels.c1.type = memory
a3.channels.c1.capacity = 1000
a3.channels.c1.transactionCapacity = 100 a3.sinks.k1.channel = c1
a3.sources.r1.channels = c1

3.测试

flume2 和 flume3 需要先启动,flume1 需要连接 flume2 和 flume3,若先启动 flume1 会报连接不上(也可以无视错误日志,先启动)

cd /opt/apache-flume-1.9.-bin 

bin/flume-ng agent --conf conf/ --name a3 --conf-file /tmp/flume-job/interceptor/flume3 -Dflume.root.logger=INFO,console
bin/flume-ng agent --conf conf/ --name a2 --conf-file /tmp/flume-job/interceptor/flume2 -Dflume.root.logger=INFO,console
bin/flume-ng agent --conf conf/ --name a1 --conf-file /tmp/flume-job/interceptor/flume1 -Dflume.root.logger=INFO,console

向监控端口发送数据。

nc 127.0.0.1 

qwer

可以看到不同的内容被发送到不同的 flume 了,拦截器代码中只定义数字和小写字母,发送其它的内容不会被 flume1 转发。

Flume-自定义 Interceptor(拦截器)的更多相关文章

  1. struts2自定义Interceptor拦截器

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  2. flume中的拦截器

    Flume中的拦截器(interceptor),用户Source读取events发送到Sink的时候,在events header中加入一些有用的信息,或者对events的内容进行过滤,完成初步的数据 ...

  3. SpringMVC 自定义一个拦截器

    自定义一个拦截器方法,实现HandlerInterceptor方法 public class FirstInterceptor implements HandlerInterceptor{ /** * ...

  4. Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例

    利用Spring的拦截器可以在处理器Controller方法执行前和后增加逻辑代码,了解拦截器中preHandle.postHandle和afterCompletion方法执行时机. 自定义一个拦截器 ...

  5. SpringMvc中Interceptor拦截器用法

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...

  6. springMVC3学习(七)--Interceptor拦截器

    Spring为我们提供了:org.springframework.web.servlet.HandlerInterceptor接口, org.springframework.web.servlet.h ...

  7. SpringBoot-SpringMvc的Interceptor拦截器配置

    Interceptor拦截器实现对每一个用户请求处理前后的业务处理,比如我们需要对用户请求进行响应时间的记录,需要记录请求从开始到结束所耗的时间,这时我们就需要用到拦截器了 下面我们以记录请求处理时间 ...

  8. Mybatis自定义SQL拦截器

    本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...

  9. springmvc自定义的拦截器以及拦截器的配置

    一.自定义拦截器 Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口. 二.HandlerIn ...

  10. SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

随机推荐

  1. 关于reduce

    arr.reduce( callback,[initialValue]) reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素 callback (执行数组中每个值 ...

  2. Vue子父组件方法互调

    讲干货,不啰嗦,大家在做vue开发过程中经常遇到父组件需要调用子组件方法或者子组件需要调用父组件的方法的情况,现做一下总结,希望对大家有所帮助. 父组件调用子组件方法: 1.设置子组件的ref,父组件 ...

  3. 部署在SAP Cloud Platform CloudFoundry环境的应用如何消费SAP Leonardo机器学习API

    Jerry的前一篇文章 如何在Web应用里消费SAP Leonardo的机器学习API 里介绍的例子是Neo测试环境的Web应用消费sandbox版本的机器学习API,url如下: https://s ...

  4. rarcrack破解rar密码

    kail系统里没有rarcrack工具,需要先在linux安装rarcrack,安装方式如下:apt-get install rarcrack可以对设置密码的压缩包zar直接进行破解,不用字典,直接进 ...

  5. IDEA部署项目到远程服务器

    一.idea安装阿里插件Alibaba Cloud Toolkit 二.添加Host 三.应用部署 四.修改源程序重新部署 五.查看实时日志 欲买桂花同载酒,终不似,少年游

  6. 【Day4】5.Request对象之Http Post请求案例分析

    import urllib.parse as up import urllib.request as ur import json word = input('请输入要翻译的中文') data = { ...

  7. ORACLE SQL性能优化汇总

    ORACLE SQL语句共享 Oracle SQL语句具备共享特性,为了不让ORACLE数据库重复解析相同的简单单表SQL语句,ORACLE在SGA系统共享区域内SBP共享池内存放的SQL语句将被所有 ...

  8. ubuntu---记录.简单一句话安装tf

    卸载 sudo pip3 uninstall tensorflow sudo pip3 uninstall tensorflow-gpu sudo pip3 uninstall tensorflow- ...

  9. Nginx的简单了解与使用

    一.产生背景 我们日常生活中经常遇到的问题 这是几年前的12306,现在的12306基本上不会出现这样的问题了 上述场景产生的主要 2 大原因:1.巨大流量2.单台服务器资源和能力有限在海量并发的环境 ...

  10. 如果简化stm32中printf函数的使用——首先重定向

    STM32单片机极简方法 使用宏定义 代替复杂的重定向printf()函数,实现串口打印.(HAL库例程)https://blog.csdn.net/wu10188/article/details/9 ...