hadoop学习-海量日志分析(提取KPI指标)

1、Web日志分析

从Web日志中,我们可以获取网站各类页面的PV值(PageView,页面访问量),访问IP;或者是用户停留时间最长的页面等等,更复杂的,可以分析用户行为特征。

在Web日志中,每条日志都代表用户的一次访问行为,以下面的一条日志为例子:

60.208.6.156 - - [18/Sep/2013:06:49:48 +0000] "GET /wp-content/uploads/2013/07/rcassandra.png HTTP/1.0" 200 185524 "http://cos.name/category/software/packages/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
可以 拆分为8个变量:

remote_addr:60.208.6.156//用户IP地址

remote_user:- //用户名称

time_local:[18/Sep/2013:06:49:48 +0000]//记录访问时间

request:"GET /wp-content/uploads/2013/07/rcassandra.png HTTP/1.0"//记录访问的url与http协议

status:200 //记录请求状态,成功是200

body_bytes_sent:185524//记录发给客户端内容的大小

http_referer:"http://cos.name/category/software/packages/"//记录从哪个页面访问过来的

http_user_agent:"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"//记录客户浏览器的信息

2、KPI指标设计

一般的KPI指标可以设置为:

PV:页面访问量统计

IP:页面独立IP访问数量统计

Time:每小时用户访问数量统计

Source:用户来源域名的统计

Brower:用户访问设备的统计

3、hadoop算法实现

PV:页面访问量统计

Map过程:key: request,value: 1

Reduce过程:key:request,value(求和)


IP:页面独立IP访问数量统计

Map过程:key: request,value: remote_addr

Reduce过程:key:request,value(去重再求和)


Time:每小时用户访问数量统计

Map过程:key: time_local,value: 1

Reduce过程:key:time_local,value(求和)


Source:用户来源域名的统计

Map过程:key: http_referer,value: 1

Reduce过程:key:http_referer,value(求和)


Brower:用户访问设备的统计

Map过程:key: http_user_agent,value: 1

Reduce过程:http_user_agent,value(求和)


下面以PV(页面访问量统计)为例,设计MapReduce程序

4、MapReduce程序实现

1).对日志解析

2).Map过程

3).Reduce过程

KPI.java

[java] view plain copy
  1. import java.text.ParseException;  
  2. import java.text.SimpleDateFormat;  
  3. import java.util.Date;  
  4. import java.util.Locale;  
  5.   
  6. public class KPI {  
  7.     private String remote_addr; //ip addr  
  8.     private String remote_user; //user name  
  9.     private String time_local;  
  10.     private String request;  
  11.     private String status;  
  12.     private String body_bytes_sent;  
  13.     private String http_referer;  
  14.     private String http_user_agent;  
  15.     private boolean valid = true;  
  16.       
  17.     public String getRemote_addr() {  
  18.         return remote_addr;  
  19.     }  
  20.   
  21.     public void setRemote_addr(String remote_addr) {  
  22.         this.remote_addr = remote_addr;  
  23.     }  
  24.   
  25.     public String getRemote_user() {  
  26.         return remote_user;  
  27.     }  
  28.   
  29.     public void setRemote_user(String remote_user) {  
  30.         this.remote_user = remote_user;  
  31.     }  
  32.   
  33.     public String getTime_local() {  
  34.         return time_local;  
  35.     }  
  36.   
  37.     public Date getTime_local_Date() throws ParseException {  
  38.         SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.US);  
  39.         return df.parse(this.time_local);  
  40.     }  
  41.       
  42.     public String getTime_local_Date_hour() throws ParseException{  
  43.         SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHH");  
  44.         return df.format(this.getTime_local_Date());  
  45.     }  
  46.   
  47.     public void setTime_local(String time_local) {  
  48.         this.time_local = time_local;  
  49.     }  
  50.   
  51.     public String getRequest() {  
  52.         return request;  
  53.     }  
  54.   
  55.     public void setRequest(String request) {  
  56.         this.request = request;  
  57.     }  
  58.   
  59.     public String getStatus() {  
  60.         return status;  
  61.     }  
  62.   
  63.     public void setStatus(String status) {  
  64.         this.status = status;  
  65.     }  
  66.   
  67.     public String getBody_bytes_sent() {  
  68.         return body_bytes_sent;  
  69.     }  
  70.   
  71.     public void setBody_bytes_sent(String body_bytes_sent) {  
  72.         this.body_bytes_sent = body_bytes_sent;  
  73.     }  
  74.   
  75.     public String getHttp_referer() {  
  76.         return http_referer;  
  77.     }  
  78.       
  79.     public void setHttp_referer(String http_referer) {  
  80.         this.http_referer = http_referer;  
  81.     }  
  82.   
  83.     public String getHttp_user_agent() {  
  84.         return http_user_agent;  
  85.     }  
  86.   
  87.     public void setHttp_user_agent(String http_user_agent) {  
  88.         this.http_user_agent = http_user_agent;  
  89.     }  
  90.   
  91.     public boolean isValid() {  
  92.         return valid;  
  93.     }  
  94.   
  95.     public void setValid(boolean valid) {  
  96.         this.valid = valid;  
  97.     }  
  98.     public void parser(String line){  
  99.         String[] arr = line.split(" ");  
  100.           
  101.         if(arr.length > 11){  
  102.             this.setRemote_addr(arr[0]);  
  103.             this.setRemote_user(arr[1]);  
  104.             this.setTime_local(arr[3]);  
  105.             this.setRequest(arr[6]);  
  106.             this.setStatus(arr[8]);  
  107.             this.setBody_bytes_sent(arr[9]);  
  108.             this.setHttp_referer(arr[10]);  
  109.             this.setHttp_user_agent(arr[11]);  
  110.             this.setValid(true);  
  111.               
  112.             if(Integer.parseInt(this.getStatus()) >= 400){  
  113.                 this.setValid(false);  
  114.             }  
  115.         }  
  116.         else  
  117.         {  
  118.             this.setValid(false);  
  119.         }  
  120.   
  121.     }  
  122. }  
KPI类可以解析每一条日志记录,并存储相应信息。


KPIPV.java

[java] view plain copy
  1. import java.io.IOException;  
  2. import java.util.Iterator;  
  3.   
  4. import org.apache.hadoop.conf.Configuration;  
  5. import org.apache.hadoop.fs.Path;  
  6. import org.apache.hadoop.io.Text;  
  7. import org.apache.hadoop.mapreduce.Job;  
  8. import org.apache.hadoop.mapreduce.Mapper;  
  9. import org.apache.hadoop.mapreduce.Reducer;  
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
  12. import org.apache.hadoop.util.GenericOptionsParser;  
  13. import org.apache.hadoop.io.IntWritable;  
  14.   
  15.   
  16. public class KPIPV {  
  17.       
  18.     public static class MapClass   
  19.         extends Mapper<Object, Text, Text, IntWritable> {  
  20.           
  21.         private final static IntWritable one = new IntWritable(1);  
  22.         private Text word = new Text();   
  23.         public void map(Object key, Text value,  
  24.                         Context context ) throws IOException,  
  25.                         InterruptedException {  
  26.             KPI kpi = new KPI();  
  27.             kpi.parser(value.toString());  
  28.             if (kpi.isValid()){  
  29.                 word.set(kpi.getRequest());  
  30.                 context.write(word,one);  
  31.             }  
  32.         }  
  33.     }  
  34.       
  35.     public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {  
  36.           
  37.         public void reduce(Text key, Iterable<IntWritable> values,  
  38.                            Context context) throws IOException,InterruptedException {  
  39.                              
  40.             int count = 0;  
  41.             for (IntWritable val : values) {  
  42.                 count += val.get();  
  43.             }  
  44.             context.write(key, new IntWritable(count));  
  45.         }  
  46.     }  
  47.       
  48.     public static void main(String[] args) throws Exception {   
  49.         Configuration conf = new Configuration();  
  50.           
  51.         String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();  
  52.         if(otherArgs.length != 2){  
  53.             System.err.println("Usage: KPI <in> <out>");  
  54.             System.exit(2);  
  55.         }  
  56.           
  57.         Job job = new Job(conf, "KPIPV");  
  58.         job.setJarByClass(KPIPV.class);  
  59.         job.setMapperClass(MapClass.class);  
  60.         //job.setCombinerClass(Reduce.class);  
  61.         job.setReducerClass(Reduce.class);  
  62.           
  63.         //job.setInputFormat(KeyValueTextInputFormat.class);  
  64.         //job.setOutputFormat(TextOutputFormat.class);  
  65.         job.setOutputKeyClass(Text.class);  
  66.         job.setOutputValueClass(IntWritable.class);  
  67.         FileInputFormat.setInputPaths(job, new Path(otherArgs[0]));  
  68.         FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));  
  69.         System.exit(job.waitForCompletion(true) ? 0 : 1);  
  70.     }  
  71. }  
本例采用的数据源为个人网站的Web日志(由 bsspirit提供),大家也可以通过 百度统计获得某个网站的日志。

5、eclipse启动程序

设置输入 输出目录

hdfs://localhost:9000/user/root/access.log.10 hdfs://localhost:9000/user/root/output9

6、结果输出

/r-rserve-nodejs/?cf_action=sync_comments&amp;post_id=1769<span style="white-space:pre">	</span>5
/r-rserve-nodejs/feed/<span style="white-space:pre">	</span>1
/r-rstudio-server/<span style="white-space:pre">	</span>2
/r-rstudio-server/?cf_action=sync_comments&amp;post_id=1506<span style="white-space:pre">	</span>2
/rhadoop-demo-email/<span style="white-space:pre">	</span>3
/rhadoop-demo-email/?cf_action=sync_comments&amp;post_id=308<span style="white-space:pre">	</span>1
/rhadoop-hadoop<span style="white-space:pre">	</span>2
/rhadoop-hadoop/<span style="white-space:pre">	</span>10
/rhadoop-hadoop/?cf_action=sync_comments&amp;post_id=87<span style="white-space:pre">	</span>2
/rhadoop-hadoop/feed/<span style="white-space:pre">	</span>1
/rhadoop-hbase-rhase/<span style="white-space:pre">	</span>4
/rhadoop-hbase-rhase/?cf_action=sync_comments&amp;post_id=97<span style="white-space:pre">	</span>2
/rhadoop-hbase-rhase/feed/<span style="white-space:pre">	</span>1
/rhadoop-java-basic/<span style="white-space:pre">	</span>3

源代码及数据:https://github.com/y521263/Hadoop_in_Action

参考资料:

http://blog.fens.me/hadoop-mapreduce-log-kpi/

你可能感兴趣的:(hadoop学习-海量日志分析(提取KPI指标))