flume写hdfs使用日志里的时间作为文件目录

在使用flume采集日志写入hdfs的时候,可以通过

a1.sinks.k1.hdfs.path = /flume/events/%y-%m-%d/%H%M/%S

配置目录名称为日期,默认情况下会使用系统时间,但是在日志采集过程中经常会发生延迟情况,比如23:59的日志00:01才采集完,那这个时候本来是前一天的日志就会被写入第二天的目录里,后续ETL的过程中就会发生误差,这个时候我们会想,能不能使用日志里的时间字段来作为hdfs的文件目录呢?配置拦截器,在 headers 里添加 timestamp 可以实现这个功能。
首先创建一个maven项目,pom.xml添加依赖:

<dependency>
     <groupId>org.apache.flume</groupId>
     <artifactId>flume-ng-core</artifactId>
     <version>1.7.0</version>
</dependency>

这里flume实际使用的是什么版本就写什么版本,我用的是1.7
然后创建 TimestampInterceptor.java

package com.flume;

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

import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TimestampInterceptor implements Interceptor {
    @Override
    public void initialize() {

    }

    @Override
    public Event intercept(Event event) {
        String log=new String(event.getBody(), Charset.forName("UTF-8"));
        Map<String, String> headers = event.getHeaders();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String timestamp;
        String[] split = log.split("\\|");
        try {
			// 这里假设日志格式为 2020-01-01 00:00:00|a|b|c|d
            timestamp=String.valueOf(sdf.parse(split[0]).getTime());
            headers.put("timestamp",timestamp);
            return event;
        } catch (ParseException e) {
            return null;
        }
    }

    @Override
    public List<Event> intercept(List<Event> list) {
        List<Event> list1=new ArrayList<>();
        for (Event event : list) {
            Event event1=intercept(event);
            if(event1!=null) list1.add(event1);
        }
        return list1;
    }

    @Override
    public void close() {

    }

    public static class Builder implements Interceptor.Builder{

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

        @Override
        public void configure(Context context) {

        }
    }
}

将项目打成jar包,上传到flume的lib目录下
在flume的配置文件里添加拦截器

#interceptor
a1.sources.r2.interceptors = i1
a1.sources.r2.interceptors.i1.type = com.flume.TimestampInterceptor$Builder

这样就大功告成了!

猜你喜欢

转载自blog.csdn.net/weixin_42473019/article/details/105585370