shell脚本定时采集日志数据到hdfs
参考:https://blog.csdn.net/gcxzflgl/article/details/80725567
java程序模拟产生日志的过程
package com.dtds.study.log4j; import java.util.Date; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; public class CreateLog { public static void main(String[] args) throws Exception{ Logger logger = LogManager.getLogger("testlog"); int i = 0; while(true){ logger.info(new Date().toString() + "-----------------------------"); i++; Thread.sleep(500); if(i>1000000){ break; } } } }
该程序模拟产生日志,程序正常运行需要配置log4j.properties文件,在src/下新建log4j.properties,内容如下:
log4j.rootLogger=INFO,testlog log4j.appender.testlog = org.apache.log4j.RollingFileAppender log4j.appender.testlog.layout = org.apache.log4j.PatternLayout log4j.appender.testlog.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n log4j.appender.testlog.Threshold = INFO log4j.appender.testlog.ImmediateFlush = TRUE log4j.appender.testlog.Append = TRUE log4j.appender.testlog.File = /root/testLogSrcData/access.log log4j.appender.testlog.MaxFileSize = 10KB log4j.appender.testlog.MaxBackupIndex = 20
写一个shell脚本,我们把它命名为:upLoadFileToHdfs.sh,脚本定时将产生的日志放到hdfs上面,内容如下:
#!/bin/bash #set java env export JAVA_HOME=/gcx/jdk1.7.0_45 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH #set hadoop env export HADOOP_HOME=/gcx/hadoop-2.6.4 export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH #版本1的问题: #虽然上传到Hadoop集群上了,但是原始文件还在。如何处理? #日志文件的名称都是xxxx.log1,再次上传文件时,因为hdfs上已经存在了,会报错。如何处理? #如何解决版本1的问题 # 1、先将需要上传的文件移动到待上传目录 # 2、在讲文件移动到待上传目录时,将文件按照一定的格式重名名 # /export/software/hadoop.log1 /export/data/click_log/xxxxx_click_log_{date} #日志文件存放的目录 log_src_dir=/root/hadoop/logs/log/ #待上传文件存放的目录 log_toupload_dir=/root/hadoop/logs/toupload/ #日志文件上传到hdfs的根路径 hdfs_root_dir=/root/hadoopData/logs/ #打印环境变量信息 echo "envs: hadoop_home: $HADOOP_HOME" #读取日志文件的目录,判断是否有需要上传的文件 echo "log_src_dir:"$log_src_dir ls $log_src_dir | while read fileName do if [[ "$fileName" == access.log.* ]]; then # if [ "access.log" = "$fileName" ];then date=`date +%Y_%m_%d_%H_%M_%S` #将文件移动到待上传目录并重命名 #打印信息 echo "moving $log_src_dir$fileName to $log_toupload_dir"xxxxx_click_log_$fileName"$date" mv $log_src_dir$fileName $log_toupload_dir"xxxxx_click_log_$fileName"$date #将待上传的文件path写入一个列表文件willDoing echo $log_toupload_dir"xxxxx_click_log_$fileName"$date >> $log_toupload_dir"willDoing."$date fi done #找到列表文件willDoing ls $log_toupload_dir | grep will |grep -v "_COPY_" | grep -v "_DONE_" | while read line do #打印信息 echo "toupload is in file:"$line #将待上传文件列表willDoing改名为willDoing_COPY_ mv $log_toupload_dir$line $log_toupload_dir$line"_COPY_" #读列表文件willDoing_COPY_的内容(一个一个的待上传文件名) ,此处的line 就是列表中的一个待上传文件的path cat $log_toupload_dir$line"_COPY_" |while read line do #打印信息 echo "puting...$line to hdfs path.....$hdfs_root_dir" hadoop fs -put $line $hdfs_root_dir done mv $log_toupload_dir$line"_COPY_" $log_toupload_dir$line"_DONE_" done
如果想周期性运行该脚本,可以配置crontab服务,执行crontab -e,加入一行:
*/1 * * * * sh /root/uploadFileToHdfs.sh //该语句表示每1分钟执行一次脚本,更多规则详询百度