自定义flume的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.apache.flume.source.ExecSource;
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;

/**

  • 自定义source源
    */
    public class TailFileSourceDemo extends AbstractSource implements Configurable, EventDrivenSource {
    //方便错误日志打印
    private static final Logger logger = LoggerFactory.getLogger(ExecSource.class);

    private String filePath;
    private String posiFile;
    private Long interval;
    private String charset;

    private ExecutorService executorService;
    private FileRunner fileRunner;

    //先调用configure 方法
    @Override
    public void configure(Context context) {
    //日志路径
    filePath = context.getString(“filePath”);
    //偏移量保持文件
    posiFile = context.getString(“posiFile”);
    //多长时间读取一次
    interval = context.getLong(“interval”);
    //字符集
    charset = context.getString(“charset”, “UTF-8”);
    }

    //在configure方法调用之后之后调用,只调用一次
    @Override
    public synchronized void start() {
    //创建一个线程池(只有一个线程)
    executorService = Executors.newSingleThreadExecutor();

     //调用父类的方法拿到channelProcessor
     ChannelProcessor channelProcessor = getChannelProcessor();
    
     //创建一个实现Runnable接口的实现类
     fileRunner = new FileRunner(filePath,posiFile,interval,charset,channelProcessor);
    
     //提交到线程线池
     executorService.submit(fileRunner);
    
     //执行父类的start方法
     super.start();
    

    }

    @Override
    public synchronized void stop() {
    //停掉线程
    fileRunner.setFlag(false);
    //释放线程池
    executorService.shutdown();

     super.stop();
    

    }

    private class FileRunner implements Runnable {
    private String filePath;
    private String posiFile;
    private Long interval;
    private String charset;
    private ChannelProcessor channelProcessor;

     private Long offset = 0L;
    
     private RandomAccessFile raf;
    
     private File offFile;
    
     private Boolean flag = true;
    
    
     public void setFlag(Boolean flag) {
         this.flag = flag;
     }
    
     public FileRunner(String filePath, String posiFile, Long interval, String charset, ChannelProcessor channelProcessor) {
         this.filePath = filePath;
         this.posiFile = posiFile;
         this.interval = interval;
         this.charset = charset;
         this.channelProcessor = channelProcessor;
    
    
         //判断是否有偏移量文件
         offFile = new File(posiFile);
         if(!offFile.exists()){
             //没有就创建
             try {
                 offFile.createNewFile();
             } catch (IOException e) {
                 logger.error("offFile error ....",e);
             }
         }
    
         //如果有偏移量,接着读
         try {
             String offsetStr = FileUtils.readFileToString(offFile);
             if(offsetStr != null && "".equals(offsetStr)){
                 //转换成Long类型
                 offset = Long.parseLong(offsetStr);
             }
         } catch (IOException e) {
             logger.error("offset error ....",e);
         }
    
         //RandomAccessFile的seek跳转到指定的偏移量
         try {
             raf = new RandomAccessFile(filePath, "r");
             //指定偏移量
             raf.seek(offset);
         } catch (FileNotFoundException e) {
             logger.error("raf error ....",e);
         } catch (IOException e) {
             logger.error("seek error ....",e);
         }
     }
    
     @Override
     public void run() {
    
         //不停监听一个文件
         while (flag){
             //读取数据封装成Event
             try {
                 String line = raf.readLine();
                 //读到内容
                 if(line != null){
                 	//转码解决中文乱码问题
                     line = new String(line.getBytes("ISO-8859-1"),charset);
                     //封装成Event
                     Event event = EventBuilder.withBody(line.getBytes());
                     //用ChannelProcessor将数据发送到Channel
                     channelProcessor.processEvent(event);
                     //获取最新偏移量。然后写入到偏移量文件中
                     offset = raf.getFilePointer();
                     FileUtils.writeStringToFile(offFile,offset+"");
                 }else{
                     //没读到睡觉
                     Thread.sleep(interval);
                 }
    
             } catch (IOException e) {
                 e.printStackTrace();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
    

    }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值