6-点击流数据分析项目-日志采集到HDFS
参考:
https://blog.csdn.net/tianjun2012/article/details/62424486
在前面的部分已经介绍了关于日志的基本情况,这里不再详解介绍,仅提供生成日志与采集日志的基本方法。
一、shell采集日志
1.基于Java生成日志:
创建pom文件:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.1.2</version>
<!-- <version>1.2.3</version> -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<mainClass>com.mystudy.hadoopPro.APP</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<!-- 可以打 fat 和thin jar-->
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
日志生成:
package edu.sx.loggen;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import java.util.Date;
public class GenerateLog {
public static void main(String[] args) throws InterruptedException {
Logger logger = LogManager.getLogger("testlog");
int i = 0;
while (true){
logger.info(new Date().toString()+"----------------------");
i++;
// Thread.sleep(1);
if(i > 1000000){
break;
}
}
}
}
创建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 = /sx/logs/log/access.log
log4j.appender.testlog.MaxFileSize = 1000KB
log4j.appender.testlog.MaxBackupIndex = 20
log4j.appender.testlog.Encoding = UTF-8
打包或直接运行均可
2.shell脚本采集日志
创建脚本
#!/bin/bash
#set java env
export JAVA_HOME=/export/server/jdk/jdk
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=/export/server/hadoop
export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
#解决的问题
# 1、先将需要上传的文件移动到待上传目录
# 2、在讲文件移动到待上传目录时,将文件按照一定的格式重名名
# /export/software/hadoop.log1 /export/data/click_log/xxxxx_click_log_{date}
#日志文件存放的目录
log_src_dir=/home/hadoop/logs/log/
#待上传文件存放的目录
log_toupload_dir=/home/hadoop/logs/toupload/
#日志文件上传到hdfs的根路径
hdfs_root_dir=/data/clickLog/20170216/
#打印环境变量信息
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
预先创建:
1、日志文件存放的目录
log_src_dir=/home/hadoop/logs/log/
2、待上传文件存放的目录
log_toupload_dir=/home/hadoop/logs/toupload/
3、日志文件上传到hdfs的根路径
hdfs_root_dir=/data/clickLog/20170216/
即可。
3.定期启动脚步采集
日志不可能只采集一次,所以需要时间调度,如每隔一分钟采集一次。
采用crontab进行定期采集:
crontab语法:
crontab [-u username] [-l|-e|-r]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑
查询使用者目前的 crontab 内容:
crontab -l
#每隔五分钟采集一次
*/5 * * * * /root/collectdata.sh
清空使用者目前的 crontab:
crontab -r
crontab -l
no crontab for blue
如果你想删除当前用户的某一个crontab任务,那么使用crontab -e进入编辑器,再删除对应的任务。
转载至:https://blog.csdn.net/tianjun2012/article/details/62424486
二、方法二-flume采集日志
- 新建一个配置文件TaildirSource-hdfs
[hadoop@hadoop-001 lib]$ cd ../
[hadoop@hadoop-001 flume]$ touch job/TaildirSource-hdfs.conf
TaildirSource-hdfs配置文件在的内容为:
agent1.sources = source1
agent1.sinks = sink1
agent1.channels = channel1
#监控一个目录下的多个文件新增的内容
agent1.sources.source1.type = TAILDIR
#通过 json 格式存下每个文件消费的偏移量,避免从头消费
agent1.sources.source1.positionFile = /home/hadoop/taildir_position.json
agent1.sources.source1.filegroups = f1
agent1.sources.source1.filegroups.f1 = /home/hadoop/nginx/logs/access_*.log
agent1.sources.source1.interceptors = i1
agent1.sources.source1.interceptors.i1.type = host
agent1.sources.source1.interceptors.i1.hostHeader = hostname
#配置sink组件为hdfs
agent1.sinks.sink1.type = hdfs
agent1.sinks.sink1.hdfs.path=hdfs://hadoop-001:8020/weblog/flume-collection/%Y-%m-%d/%H-%M_%{hostname}
#指定文件名前缀
agent1.sinks.sink1.hdfs.filePrefix = access_log
#指定每批下沉数据的记录条数
agent1.sinks.sink1.hdfs.batchSize= 100
agent1.sinks.sink1.hdfs.fileType = DataStream
agent1.sinks.sink1.hdfs.writeFormat =Text
#指定下沉文件按1MB大小滚动
agent1.sinks.sink1.hdfs.rollSize = 1048576
#指定下沉文件按1000000条数滚动
agent1.sinks.sink1.hdfs.rollCount = 1000000
#指定下沉文件按30分钟滚动
agent1.sinks.sink1.hdfs.rollInterval = 30
#agent1.sinks.sink1.hdfs.round = true
#agent1.sinks.sink1.hdfs.roundValue = 10
#agent1.sinks.sink1.hdfs.roundUnit = minute
agent1.sinks.sink1.hdfs.useLocalTimeStamp = true
#使用memory类型channel
agent1.channels.channel1.type = memory
agent1.channels.channel1.capacity = 500000
agent1.channels.channel1.transactionCapacity = 600
# Bind the source and sink to the channel
agent1.sources.source1.channels = channel1
agent1.sinks.sink1.channel = channel1
启动flume
- 只能在flume目录下执行此命令
[hadoop@hadoop-001 /]$ cd /home/hadoop/bigdatasoftware/flume
[hadoop@hadoop-001 flume]$ bin/flume-ng agent --conf conf/ --name agent1 --conf-file job/TaildirSource-hdfs.conf -Dflume.root.logger=INFO,console
来源于github上的 hadoop-flume-hdfs-hive-master 项目
总结
本文主要实现日志的采集,由于相关内容前面已经详细介绍过了,这里仅罗列一些实现方法,没有介绍具体的细节