定期将采集的日志发到HDFS,采集完后备份,并定期删除 (five day)

 

首先写代码之前梳理一下流程:

启动一个定时任务:
   1、定时探测日志源目录
   2、获取需要采集的文件
   3、移动这些文件到一个待上传临时目录
   4、遍历待上传目录中各文件,逐一传输到HDFS的目标路径,同时将传输完成的文件移动到备份目录

启动一个定时任务:
   探测备份目录中的备份数据,检查是否已超出最长备份时长,如果超出,则删除
   
   
2、规划各种路径(全都写在配置文件里PropertyHolderLazy.getProps())
1、日志源路径
2、待上传临时目录
3、备份目录

1、HDFS存储路径
2、HDFS中的文件的前缀
3、HDFS中的文件的后缀

建定时任务:

Timer timer = new Timer();

timer.schedule(new CollectTask(), 0, 60*60*1000L);//定时采集
timer.schedule(new BackupCleanTask(), 0, 60*60*1000L);定时清除

获取配置文件里的信息(顺带复习下单例模式[懒汉式/饿汉式]):

为什么用单例模式:许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

基本的实现思路
单例模式要求类能够有返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称)。

//懒汉式——考虑了线程安全
private static Properties prop = null;

	public static Properties getProps() throws Exception {
		if (prop == null) {
			synchronized (PropertyHolderLazy.class) {//
				if (prop == null) {
					prop = new Properties();
					prop.load(PropertyHolderLazy.class.getClassLoader().getResourceAsStream("collect.properties"));
				}
			}
		}
		return prop;
	}

//饿汉式
private static Properties prop = new Properties();

	static {
		try {
			prop.load(PropertyHolderHungery.class.getClassLoader().getResourceAsStream("collect.properties"));
		} catch (Exception e) {

		}
	}

	public static Properties getProps() throws Exception {

		return prop;
	}

定时采集: 

public class CollectTask extends TimerTask {

	@Override
	public void run() {

		/**
		 * ——定时探测日志源目录 ——获取需要采集的文件 ——移动这些文件到一个待上传临时目录
		 * ——遍历待上传目录中各文件,逐一传输到HDFS的目标路径,同时将传输完成的文件移动到备份目录
		 */
		try {
			// 获取配置参数
			Properties props = PropertyHolderLazy.getProps(); 

			// 构造一个log4j日志对象
			Logger logger = Logger.getLogger("logRollingFile");

			// 获取本次采集时的日期
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH");
			String day = sdf.format(new Date());

			File srcDir = new File(props.getProperty(Constants.LOG_SOURCE_DIR));

			// 列出日志源目录中需要采集的文件
			File[] listFiles = srcDir.listFiles(new FilenameFilter() {

				@Override
				public boolean accept(File dir, String name) {
					if (name.startsWith(props.getProperty(Constants.LOG_LEGAL_PREFIX))) {
						return true;
					}
					return false;
				}
			});

			// 记录日志
			logger.info("探测到如下文件需要采集:" + Arrays.toString(listFiles));

			// 将要采集的文件移动到待上传临时目录
			File toUploadDir = new File(props.getProperty(Constants.LOG_TOUPLOAD_DIR));
			for (File file : listFiles) {
				FileUtils.moveFileToDirectory(file, toUploadDir, true);
			}

			// 记录日志
			logger.info("上述文件移动到了待上传目录" + toUploadDir.getAbsolutePath());

			// 构造一个HDFS的客户端对象

			FileSystem fs = FileSystem.get(new URI(props.getProperty(Constants.HDFS_URI)), new Configuration(), "root");
			File[] toUploadFiles = toUploadDir.listFiles();

			// 检查HDFS中的日期目录是否存在,如果不存在,则创建
			Path hdfsDestPath = new Path(props.getProperty(Constants.HDFS_DEST_BASE_DIR) + day);
			if (!fs.exists(hdfsDestPath)) {
				fs.mkdirs(hdfsDestPath);
			}

			// 检查本地的备份目录是否存在,如果不存在,则创建
			File backupDir = new File(props.getProperty(Constants.LOG_BACKUP_BASE_DIR) + day + "/");
			if (!backupDir.exists()) {
				backupDir.mkdirs();
			}

			for (File file : toUploadFiles) {
				// 传输文件到HDFS并改名access_log_
				Path destPath = new Path(hdfsDestPath + "/" + UUID.randomUUID() + props.getProperty(Constants.HDFS_FILE_SUFFIX));
				fs.copyFromLocalFile(new Path(file.getAbsolutePath()), destPath);

				// 记录日志
				logger.info("文件传输到HDFS完成:" + file.getAbsolutePath() + "-->" + destPath);

				// 将传输完成的文件移动到备份目录
				FileUtils.moveFileToDirectory(file, backupDir, true);

				// 记录日志
				logger.info("文件备份完成:" + file.getAbsolutePath() + "-->" + backupDir);

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

 

定时清除(24h)

public class BackupCleanTask extends TimerTask {

	@Override
	public void run() {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH");
		long now = new Date().getTime();
		try {
			// 探测本地备份目录
			File backupBaseDir = new File("d:/logs/");
			File[] dayBackDir = backupBaseDir.listFiles();

			// 判断备份日期子目录是否已超24小时
			for (File dir : dayBackDir) {
				long time = sdf.parse(dir.getName()).getTime();
				if(now-time>24*60*60*1000L){
					FileUtils.deleteDirectory(dir);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

(主要是java基础,和HDFS相关不大)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值