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自定义source管理偏移量
最新推荐文章于 2024-01-16 22:03:09 发布