Flume自定义source管理偏移量

 package Source;
 import org.apache.commons.io.FileUtils;
import org.apache.flume.Context;
import org.apache.flume.Event;
import org.apache.flume.EventDrivenSource;
import org.apache.flume.channel.ChannelProcessor;
import org.apache.flume.conf.Configurable;
import org.apache.flume.event.EventBuilder;
import org.apache.flume.source.AbstractSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
//自定义一个类defmysouece继承AbstractSource,实现EventDrivenSource, Configurable接口
public class defmysouece extends AbstractSource implements EventDrivenSource, Configurable {
//通过日志提示
    private static final Logger logger = LoggerFactory.getLogger(defmysouece.class);
private String filepath;
private String offsetpath;
private Long time;
private String charset;
private FilepathRunn runner;
private ExecutorService pool;
//重写start方法
@Override
public synchronized void start() {
    //定义一个线程池
     pool = Executors.newSingleThreadExecutor();
    //定义一个线程
    ChannelProcessor channelProcessor = getChannelProcessor();
    runner= new FilepathRunn(this.filepath, offsetpath, time, charset,channelProcessor);
    //将线程扔进线程池
    pool.submit(runner);
    super.start();
}
//重写stop方法
    @Override
    public synchronized void stop() {
        runner.setFlag(false);
        //关闭线程池
        pool.shutdown();
    while (!pool.isTerminated())
    {
        logger.debug("Waiting for exec executor service to stop");
        try {
            pool.awaitTermination(500, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            logger.debug("Interrupted while waiting for exec executor service "
                    + "to stop. Just exiting.");
            Thread.currentThread().interrupt();
        }
    }
    super.stop();
}
@Override
public void configure(Context context) {
    filepath = context.getString("filepath");
    offsetpath = context.getString("offsetpath");
    time = context.getLong("time", 1000L);
    charset = context.getString("Charset", "UTf-8");
}
/************************************************************************************************************
    /**
     * 编写一个内部类
     */
    public static class FilepathRunn implements Runnable {
        private String filepath;
        private String offsetpath;
        private Long time;
        private String charset;
        private ChannelProcessor channelProcessor;
        private long lofs=0L;
        private RandomAccessFile ran;
        private  Event event;
        private File ofsp;
        private boolean flag=true;

    public FilepathRunn(String filepath, String offsetpath, Long time, String charset,ChannelProcessor channelProcessor) {
        this.filepath = filepath;
        this.offsetpath = offsetpath;
        this.time = time;
        this.charset = charset;
        this.channelProcessor=channelProcessor;

        //读取偏移量
        ofsp = new File(offsetpath);
        //判断给路径是否存在
        if (!ofsp.exists())
        {
            try {
                ofsp.createNewFile();
            } catch (IOException e) {
                logger.error("偏移量文件路径"+e);
            }
        }else{
            //得到偏移量
            try {
                String ofspva = FileUtils.readFileToString(ofsp);
                if (!ofspva.equals("")&&ofspva!=null)
                {
                    lofs = Long.parseLong(ofspva);
                }
            } catch (IOException e) {
                logger.error("获取文件中的偏移量"+e);
            }
            //跳到偏移量的位置
            try {
                 ran = new RandomAccessFile(filepath, "r");
                try {
                    ran.seek(lofs);
                } catch (IOException e) {
                    logger.error("跳转到偏移量的位置"+e);
                }
            } catch (FileNotFoundException e) {
                logger.error("原始文件路径"+e);
            }
        }

    }

public void setFlag(boolean flag) {
    this.flag = flag;
}

@Override
    public void run() {
        while (flag)
        {   //读取数据封装成even类
            try {
                String line = ran.readLine();
                if (line !=null)
                {
                    line = new String(line.getBytes("ISO-8859-1"), "utf-8");
                    event = EventBuilder.withBody(line, Charset.forName(charset));
                    //将该类发送给channlprocess
                    channelProcessor.processEvent(event);
                    //更新偏移量
                    long newofs = ran.getFilePointer();
                    FileUtils.writeStringToFile(ofsp,newofs+"");
                }else {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        logger.error("更新偏移量睡眠"+e);
                    }
                }
            } catch (IOException e) {
                logger.error("存放偏移量路径"+e);
            }

        }
    }
}
}

你可能感兴趣的:(Flume)