一、需求背景
最近项目有这样一个需求,分别采集不同应用不同机器上的日志,在做日志清洗后存入DB,数据库表字段需要存当前日志的来源,比如,来自于哪个项目,该项目的哪台机器,由于我们使用的是flume来做日志采集,故去翻flume的官网,发现有拦截器可以支持我的需求,一个是主机拦截器,可以在source之后配置,在header里面拼上ip信息,另一个是static拦截器,可以自定义key和value,这样的话我们就可以自定义该日志信息来源于哪个项目了;
测试后发现,在设置了多个拦截器后,消息的头信息里面的确包含了ip和项目信息,但是kafka收到的消息只有消息的body部分,没有header信息,一番折腾后,决定自定义一个flume拦截器,用来拦截event信息,将里面的头信息和body信息取出来然后统一拼接到body里面,经过测试,完美解决了我的需求。
二、实战
如何自定义flume拦截器 ? 建一个maven工程,导入flume-core包,然后实现interceptor接口,先看代码
package com.flume.schedule;
import java.util.List;
import java.util.Map;
import org.apache.flume.Event;
import org.apache.flume.interceptor.Interceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Charsets;
public class FlumeInterceptor implements Interceptor {
private Logger logger = LoggerFactory.getLogger(FlumeInterceptor.class);
@Override
public void close() {
}
@Override
public void initialize() {
}
@Override
public Event intercept(Event event) {
StringBuilder builder = new StringBuilder();
Map<String,String> headerMap = event.getHeaders();
String ip = "";
String projectName = "";
if(null != headerMap && !headerMap.isEmpty()) {
ip = headerMap.get("host");
projectName = headerMap.get("projectname");
builder.append("ip:" + ip + ";projectname:" + projectName);
}
byte[] byteBody = event.getBody();
String body = new String(byteBody,Charsets.UTF_8);
builder.append(";body:" + body);
event.setBody(builder.toString().trim().getBytes());
logger.info("拼接后的body信息:" + builder.toString().trim());
return event;
}
@Override
public List<Event> intercept(List<Event> events) {
for(final Event event : events) {
intercept(event);
}
return events;