- 3-网站日志分析案例-MapReduce执行日志清洗
- 准备环境:
- 1.数据介绍
- 2.基于IDEA创建Maven工程
- 3.日志清洗
- 创建日志清洗类
- 创建MR
- 导入HDFS
- 4.问题解决
- 问题1:
- 问题2:
- 总结
Linux环境
Windows环境
均做了调试
本文代码是基于window开发,因为数据量较大时,相比虚拟机,本地运行更顺畅些,还不是没钱买服务器。。。
1.1 数据情况回顾
参考:https://www.cnblogs.com/edisonchou/p/4449082.html
该论坛数据有两部分:
(1)历史数据约56GB,统计到2012-05-29。这也说明,在2012-05-29之前,日志文件都在一个文件里边,采用了追加写入的方式。
(2)自2013-05-30起,每天生成一个数据文件,约150MB左右。这也说明,从2013-05-30之后,日志文件不再是在一个文件里边。
图2展示了该日志数据的记录格式,其中每行记录有5部分组成:访问者IP、访问时间、访问资源、访问状态(HTTP状态码)、本次访问流量。
图2 日志记录数据格式
1.2 要清理的数据
(1)根据前面的关键指标的分析,我们所要统计分析的均不涉及到访问状态(HTTP状态码)以及本次访问的流量,于是我们首先可以将这两项记录清理掉;
(2)根据日志记录的数据格式,我们需要将日期格式转换为平常所见的普通格式如20150426这种,于是我们可以写一个类将日志记录的日期进行转换;
(3)由于静态资源的访问请求对我们的数据分析没有意义,于是我们可以将"GET /staticsource/"开头的访问记录过滤掉,又因为GET和POST字符串对我们也没有意义,因此也可以将其省略掉;
工程位于G:ideaprojectetl下,Maven的GAV坐标为
edu.sx etl 1.0-SNAPSHOT
在Maven工程下的pom.xm中的标签下配置hadoop依赖,注意标签
org.apache.hadoop hadoop-client 2.7.3 org.apache.hadoop hadoop-common 2.7.3 org.apache.hadoop hadoop-hdfs 2.7.3 org.apache.hadoop hadoop-mapreduce-client-core 2.7.3 org.apache.hbase hbase-client 1.1.2 org.apache.hbase hbase-server 1.1.2
添加打包插件
org.apache.maven.plugins maven-jar-plugin 2.6 com.mystudy.hadoopPro.APP org.apache.maven.plugins maven-assembly-plugin 3.1.1 jar-with-dependencies UTF-8 make-assembly package single
右键pom.xml文件–maven–reload project
会在external libraries中看到新导入的依赖
edu.sx.etl.LogParser
package edu.sx.etl;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class LogParser {
public static final SimpleDateFormat FORMAT = new SimpleDateFormat(
"d/MMM/yyyy:HH:mm:ss", Locale.ENGLISH);
public static final SimpleDateFormat dateformat1 = new SimpleDateFormat(
"yyyyMMddHHmmss");
public static void main(String[] args) throws ParseException {
final String S1 = "27.19.74.143 - - [30/May/2013:17:38:20 +0800] "GET /static/image/common/faq.gif HTTP/1.1" 200 1127";
LogParser parser = new LogParser();
final String[] array = parser.parse(S1);
System.out.println("样例数据: " + S1);
System.out.format(
"解析结果: ip=%s, time=%s, url=%s, status=%s, traffic=%s",
array[0], array[1], array[2], array[3], array[4]);
}
private Date parseDateFormat(String string) {
Date parse = null;
try {
parse = FORMAT.parse(string);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
public String[] parse(String line) {
String ip = parseIP(line);
String time = parseTime(line);
String url = parseURL(line);
String status = parseStatus(line);
String traffic = parseTraffic(line);
return new String[] { ip, time, url, status, traffic };
}
private String parseTraffic(String line) {
final String trim = line.substring(line.lastIndexOf(""") + 1)
.trim();
String traffic = trim.split(" ")[1];
return traffic;
}
private String parseStatus(String line) {
final String trim = line.substring(line.lastIndexOf(""") + 1)
.trim();
String status = trim.split(" ")[0];
return status;
}
private String parseURL(String line) {
final int first = line.indexOf(""");
final int last = line.lastIndexOf(""");
String url = line.substring(first + 1, last);
return url;
}
private String parseTime(String line) {
final int first = line.indexOf("[");
final int last = line.indexOf("+0800]");
String time = line.substring(first + 1, last).trim();
Date date = parseDateFormat(time);
return dateformat1.format(date);
}
private String parseIP(String line) {
String ip = line.split("- -")[0].trim();
return ip;
}
}
创建MR
edu.sx.etl.LogCleanJob
package edu.sx.etl;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class LogCleanJob {
private static boolean deleteDir(File dir){
if (dir.isDirectory()) {
String[] children = dir.list();
//递归删除目录中的子目录下
for (int i=0; i {
LogParser logParser = new LogParser();
Text outputValue = new Text();
protected void map(
LongWritable key,
Text value,
Context context)
throws java.io.IOException, InterruptedException {
final String[] parsed = logParser.parse(value.toString());
// step1.过滤掉静态资源访问请求
if (parsed[2].startsWith("GET /static/")
|| parsed[2].startsWith("GET /uc_server")) {
return;
}
// step2.过滤掉开头的指定字符串
if (parsed[2].startsWith("GET /")) {
parsed[2] = parsed[2].substring("GET /".length());
} else if (parsed[2].startsWith("POST /")) {
parsed[2] = parsed[2].substring("POST /".length());
}
// step3.过滤掉结尾的特定字符串
if (parsed[2].endsWith(" HTTP/1.1")) {
parsed[2] = parsed[2].substring(0, parsed[2].length()
- " HTTP/1.1".length());
}
// step4.只写入前三个记录类型项
outputValue.set(parsed[0] + "t" + parsed[1] + "t" + parsed[2]);
context.write(key, outputValue);
}
}
static class MyReducer extends
Reducer {
protected void reduce(
LongWritable k2,
java.lang.Iterable v2s,
org.apache.hadoop.mapreduce.Reducer.Context context)
throws java.io.IOException, InterruptedException {
for (Text v2 : v2s) {
context.write(v2, NullWritable.get());
}
};
}
}
导入HDFS
清洗后的数据位于d:hadoopoutput中,将文件上传到linux中的hdfs上,路径为/sx/cleandlog
hadoop fs -mkdir /sx/cleandlog hadoop fs -put part-r-00000 /sx/cleandlog4.问题解决 问题1:
(null) entry in command string: null chmod 0700 G:
解决办法:
将hadoop/bin下的hadoop.dll和winutils.exe拷贝到C:WindowsSystem32下,然后重新加载IDEA项目,再次打开,运行即可解决此异常
使用idea本地运行mapreduce程序,控制台log4j日志没有打印出来,可以这样解决
解决办法:
我们的项目中没有找到log4j.properties或者log4j.xml等默认的配置文件。
在这里插入图片描述
解决:
加上一个 log4j.properties 文件,在 官网上 copy 一个例子过来:
# Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n总结
本文网站日志分析案例中的第3部分。本文主要实现日志的清洗,将54w条日志数据进行清洗,清洗后得到17w条数据。



