彷徨 | 打印日志文件并将其上传存到HDFS中

本文介绍了一个完整的日志管理系统,包括日志生成、采集、上传至HDFS及日志清理过程。系统通过定时任务实现日志文件的自动管理,利用log4j进行日志记录,并将日志文件按需上传至HDFS集群。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在本地打印日志 , 对日志文件进行分析 , 把需要上传的日志文件移动到待上传目录 , 将待上传的日志文件逐个上传到HDFS , 并移动到备份目录 , 定期清理过期备份日志 .


1.首先生产日志文件:

/**
 * 生产日志
 * @author Administrator
 *
 */
public class MoreLog {
	public static void main(String[] args) throws Exception {
		Logger logger = LogManager.getLogger(MoreLog.class);
		System.out.println("开始打印日志了");
		while(true){
			logger.info("张俊杰zhangjunjie张俊杰zhangjunjie张俊杰zhangjunjie");
			Thread.sleep(1);
		}
	}
}

2.启动日志采集和日志清理

/**
 * 启动日志采集
 * 和日志清理
 * @author Administrator
 *
 */

public class StartUp {
	public static void main(String[] args) {
		Timer timer = new Timer();
		//上传
		timer.schedule(new ClollactionTask(), 0, 2*60*1000l);
		
		//清理文件
		timer.schedule(new ClearTask(), 0, 24*60*1000);
	}
}

3.日志采集并上传HDFS

import java.io.File;
import java.io.FilenameFilter;
import java.net.InetAddress;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

/**
 * 日志采集的:
 * 1.从日志目录里面查看哪些需要上传(1.2.3.....)
 * 2.把需要上传的文件移动到待上传文件
 * 3.上传到hdfs上(/log/2018-8-20/xxx.log)
 * 4.将上传完成的日志文件移动到备份目录
 * @author Administrator
 *
 */

public class ClollactionTask extends TimerTask{

	@Override
	public void run() {
		System.out.println("开始执行任务");
		try {
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
			String datetime = format.format(new Date());
			
			// 1:查看哪些文件是需要上传的
			File logDir = new File("e:/testlog/");
			File[] listFiles = logDir.listFiles(new FilenameFilter() {
				// FileNameFilter 是过哪些文件能够获取的
				@Override
				public boolean accept(File dir, String name) {
					return name.startsWith("test.log.");
				}
			});

			// 2:将文件移动到待上传目录
			for (File file : listFiles) {
				// file.renameTo(new File(""));
				FileUtils.moveFileToDirectory(file, new File("e:/waitUpLoad"), true);
			}
			
			//3:将待上传的文件逐个上传到hdfs上,并移动到备份目录
			FileSystem fs = FileSystem.get(new URI("hdfs://hadoop01:9000"), new Configuration(), "root");
			Path detPath = new Path("/log/"+datetime.substring(0, 10));
			//判断待上传的目录是否存在,不存在则创建一个(hdfs上的文件夹)
			boolean exists = fs.exists(detPath);
			if(!exists){
				fs.mkdirs(detPath);
			}
			
			//判断备份目录是否存在
			File backDir = new File("e:/backDir/"+datetime);
			boolean exists2 = backDir.exists();
			if(!exists2){
				backDir.mkdirs();
			}
			
			//得到上传的是哪一个服务上的日志文件
			String hostName = InetAddress.getLocalHost().getHostName();
			
			//4:遍历待上传的目录
			File file = new File("e:/waitUpLoad");
			File[] listFile = file.listFiles();
			for (File f : listFile) {
				//上传到hdfs上
				fs.copyFromLocalFile(new Path(f.getPath()), new Path(detPath,hostName+"_"+f.getName()+"_"+System.currentTimeMillis()));
				
				//cp到备份目录
				FileUtils.moveFileToDirectory(f, backDir, true);
			}
			fs.close();
			
		} catch (Exception e) {
			e.getStackTrace();
		}

	}
	
}

4.清理过期日志

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

import org.apache.commons.io.FileUtils;
/**
 * 清理过期日志
 * @author Administrator
 *
 */
public class ClearTask extends TimerTask {

	@Override
	public void run() {
		try {		
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
			Date nowdate = new Date();
			
			File file = new File("E:/backDir");
			File[] listFiles = file.listFiles();
			
			for (File dir : listFiles) {
				String name = dir.getName();
				Date dirdate = format.parse(name);
				if(nowdate.getTime() - dirdate.getTime() > 24*60*60*1000) {
					FileUtils.deleteDirectory(dir);
				}				
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
}

附:log4j配置文件

log4j.rootLogger =ALL,systemOut,logRollingFile
#log4j.rootLogger =ALL,systemOut,logFile,logDailyFile,logRollingFile,logMail,logDB 
#\u8F93\u51FA\u5230\u63A7\u5236\u53F0 
log4j.appender.systemOut = org.apache.log4j.ConsoleAppender 
log4j.appender.systemOut.layout = org.apache.log4j.PatternLayout 
log4j.appender.systemOut.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
log4j.appender.systemOut.Threshold = DEBUG 
log4j.appender.systemOut.ImmediateFlush = TRUE 
log4j.appender.systemOut.Target = System.out 

#\u8F93\u51FA\u5230\u6587\u4EF6 
log4j.appender.logFile = org.apache.log4j.FileAppender 
log4j.appender.logFile.layout = org.apache.log4j.PatternLayout 
log4j.appender.logFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
log4j.appender.logFile.Threshold = WARN 
log4j.appender.logFile.ImmediateFlush = TRUE 
log4j.appender.logFile.Append = TRUE 
log4j.appender.logFile.File = ../Struts2/WebRoot/log/File/log4j_Struts.log 
log4j.appender.logFile.Encoding = UTF-8 

#\u6309DatePattern\u8F93\u51FA\u5230\u6587\u4EF6 
log4j.appender.logDailyFile = org.apache.log4j.DailyRollingFileAppender 
log4j.appender.logDailyFile.layout = org.apache.log4j.PatternLayout 
log4j.appender.logDailyFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
log4j.appender.logDailyFile.Threshold = DEBUG 
log4j.appender.logDailyFile.ImmediateFlush = TRUE 
log4j.appender.logDailyFile.Append = TRUE 
log4j.appender.logDailyFile.File = ../Struts2/WebRoot/log/DailyFile/log4j_Struts 
log4j.appender.logDailyFile.DatePattern = '.'yyyy-MM-dd-HH-mm'.log' 
log4j.appender.logDailyFile.Encoding = UTF-8 

#\u8BBE\u5B9A\u6587\u4EF6\u5927\u5C0F\u8F93\u51FA\u5230\u6587\u4EF6 
log4j.appender.logRollingFile = org.apache.log4j.RollingFileAppender 
log4j.appender.logRollingFile.layout = org.apache.log4j.PatternLayout 
log4j.appender.logRollingFile.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n 
log4j.appender.logRollingFile.Threshold = DEBUG 
log4j.appender.logRollingFile.ImmediateFlush = TRUE 
log4j.appender.logRollingFile.Append = TRUE 
log4j.appender.logRollingFile.File = e:/testlog/test.log
log4j.appender.logRollingFile.MaxFileSize = 1MB 
log4j.appender.logRollingFile.MaxBackupIndex = 50 
log4j.appender.logRollingFile.Encoding = UTF-8 

#\u7528Email\u53D1\u9001\u65E5\u5FD7 
log4j.appender.logMail = org.apache.log4j.net.SMTPAppender 
log4j.appender.logMail.layout = org.apache.log4j.HTMLLayout 
log4j.appender.logMail.layout.LocationInfo = TRUE 
log4j.appender.logMail.layout.Title = Struts2 Mail LogFile 
log4j.appender.logMail.Threshold = DEBUG 
log4j.appender.logMail.SMTPDebug = FALSE 
log4j.appender.logMail.SMTPHost = SMTP.163.com 
log4j.appender.logMail.From = xly3000@163.com 
log4j.appender.logMail.To = xly3000@gmail.com 
#log4j.appender.logMail.Cc = xly3000@gmail.com 
#log4j.appender.logMail.Bcc = xly3000@gmail.com 
log4j.appender.logMail.SMTPUsername = xly3000 
log4j.appender.logMail.SMTPPassword = 1234567 
log4j.appender.logMail.Subject = Log4j Log Messages 
#log4j.appender.logMail.BufferSize = 1024 
#log4j.appender.logMail.SMTPAuth = TRUE 

#\u5C06\u65E5\u5FD7\u767B\u5F55\u5230MySQL\u6570\u636E\u5E93 
log4j.appender.logDB = org.apache.log4j.jdbc.JDBCAppender 
log4j.appender.logDB.layout = org.apache.log4j.PatternLayout 
log4j.appender.logDB.Driver = com.mysql.jdbc.Driver 
log4j.appender.logDB.URL = jdbc:mysql://127.0.0.1:3306/xly 
log4j.appender.logDB.User = root 
log4j.appender.logDB.Password = 123456 
log4j.appender.logDB.Sql = INSERT INTOT_log4j(project_name,create_date,level,category,file_name,thread_name,line,all_category,message)values('Struts2','%d{yyyy-MM-ddHH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

 

<think>好的,我现在需要帮助用户解决如何将HDFS中的文件下载到Linux系统中,且重命名。让我先回忆一下相关的Hadoop命令。用户提到要下载文件另外命名,所以需要用到hdfs dfs -get或者hadoop fs -get命令。这两个命令基本上是一样的,但需要确认用户的环境是否配置正确。 首先,用户需要知道源文件在HDFS中的路径,比如/user/data/input.txt,以及目标路径在Linux本地,比如/home/user/output.txt。基本的命令结构应该是hdfs dfs -get [HDFS源路径] [Linux目标路径]。这里需要注意的是,如果目标路径是一个目录,文件会被下载到该目录下保持原名;如果是文件名,就会重命名。所以用户需要指定目标文件名而不是目录。 接下来,我得检查是否有权限问题。用户可能需要确保他们对HDFS中的文件有读取权限,否则命令会失败。另外,HDFS服务必须正常运行,客户端配置正确,能够连接到NameNode和DataNode。 然后,考虑网络和存储空间。下载大文件时,要确保Linux本地有足够的存储空间,否则会出错。还有,如果文件很大,下载可能需要一些时间,用户需要耐心等待。 另外,是否有其他方法?比如使用hdfs dfs -copyToLocal命令,这和-get是类似的,同样适用。用户可能需要注意命令的兼容性,不同Hadoop版本是否有差异,但通常这两个命令都可以用。 测试步骤也很重要。下载完成后,用户应该检查本地文件是否存在,用ls -l查看文件大小和权限,或者用md5sum比对HDFS和本地文件的哈希值,确保文件完整无误。 最后,如果用户遇到问题,比如命令找不到,可能需要检查Hadoop的环境变量是否配置,或者是否以正确的用户身份执行命令。还有常见的错误信息,比如文件不存在、权限拒绝等,需要根据具体提示进行排查。 总结一下,步骤应该是:1. 确认HDFS文件路径;2. 执行get或copyToLocal命令,指定目标文件名;3. 验证下载结果。同时提醒用户注意权限、存储空间和网络连接的问题。</think>要将HDFS中的文件下载到Linux本地文件系统重命名,可通过以下步骤实现: --- ### **步骤1:确认HDFS文件路径** 首先需要明确待下载文件在HDFS中的完整路径,例如: $$ \text{HDFS路径:/user/data/input.txt} $$ --- ### **步骤2:使用`hdfs dfs -get`命令下载重命名** 通过Hadoop的`-get`命令将文件下载到本地,直接指定新名称: ```bash hdfs dfs -get /user/data/input.txt /home/user/output.txt ``` - **参数解释**: - `/user/data/input.txt`: HDFS中的源文件路径 - `/home/user/output.txt`: Linux本地目标路径及新文件名 --- ### **步骤3:验证下载结果** 检查本地文件是否成功下载重命名: ```bash ls -l /home/user/output.txt # 查看文件属性 cat /home/user/output.txt # 查看文件内容(可选) ``` --- ### **注意事项** 1. **权限问题**: - 确保当前用户对HDFS文件有读取权限。 - 若无权限,需联系管理员或使用`hdfs dfs -chmod`调整权限。 2. **路径格式**: - HDFS路径需以绝对路径(如`/user/data/input.txt`)形式指定。 - 本地路径可以是绝对路径或相对路径(如`./output.txt`)。 3. **网络存储**: - 确保Linux本地有足够存储空间。 - 若文件较大,下载可能耗时较长。 --- ### **替代方案:`hdfs dfs -copyToLocal`** `-copyToLocal`命令`-get`功能相同,语法一致: ```bash hdfs dfs -copyToLocal /user/data/input.txt /home/user/output.txt ``` --- ### **常见错误排查** 1. **文件不存在**: ```bash get: No such file or directory ``` - 检查HDFS路径是否正确,使用`hdfs dfs -ls`确认文件存在性。 2. **权限拒绝**: ```bash Permission denied: user=root, access=READ ``` - 使用`hdfs dfs -chmod`修改权限,或联系HDFS管理员。 3. **本地路径无效**: - 确保本地目标目录存在(若不存在,先执行`mkdir -p /home/user`)。 --- ### **总结** 通过`hdfs dfs -get`或`hdfs dfs -copyToLocal`命令,可高效将HDFS文件下载到本地重命名。操作前需确认权限、路径和存储空间,完成后建议校验文件完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值