分享

日志分析实战之清洗日志小实例5:实现获取不能访问url

问题导读

1.在url中,如何过滤不需要的内容?
2.如何获取404记录并且获取字段?
3.获取不能访问url列表的思路是什么?



about云日志分析实战之清洗日志4:统计网站相关信息
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22900


上篇文章简单的统计了一些信息,下一步希望找到404对应的url。
思路:
1.获取request字段
2.过滤不需要字符
3.实现获取url,并打印输出


1.创建getRequest函数获取request字段
[mw_shl_code=scala,true]// get the `request` field from an access log record
def getRequest(rawAccessLogString: String): Option[String] = {
  val accessLogRecordOption = p.parseRecord(rawAccessLogString)
  accessLogRecordOption match {
    case Some(rec) => Some(rec.request)
    case None => None
  }
}[/mw_shl_code]
2.创建extractUriFromRequest函数
[mw_shl_code=scala,true]// val request = "GET /foo HTTP/1.0"
def extractUriFromRequest(requestField: String) = requestField.split(" ")(1)[/mw_shl_code]
这个目的大家可以猜猜它的作用

获取404页面,并且打印出请求的URL.
[mw_shl_code=scala,true]val distinctRecs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404")
                     .map(getRequest(_))
                     .collect { case Some(requestField) => requestField }
                     .map(extractUriFromRequest(_))
                     .distinct[/mw_shl_code] 实现函数.jpg

[mw_shl_code=scala,true]distinctRecs.count
[/mw_shl_code]
个数为2.jpg

[mw_shl_code=scala,true]distinctRecs.collect().foreach(println(_))
[/mw_shl_code]
输出结果.jpg

3.获取url
[mw_shl_code=scala,true]val distinctRecs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404")
                     .map(getRequest(_))
                     .collect { case Some(requestField) => requestField }
                     .map(extractUriFromRequest(_))
                     .distinct[/mw_shl_code]
通过上面看,其实挺简单。Scala本身是非常简洁的。

相关说明:
上面看似简单,其实有很多需要说明的

val recs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404").map(getRequest(_))
上面得出404对应的url.getRequest是上面我们定义的函数
val distinctRecs = log.filter(line => getStatusCode(p.parseRecord(line)) == "404").map(getRequest(_)).distinct
这里多了distinct是为了去重,下面是直接打印。
distinctRecs.collect().foreach(println(_))。

对于extractUriFromRequest,这个主要为过滤我们不想要的内容。如下面,GET 和HTTP/1.1都不是我们想要的。所以我们取第二个元素即可。
[mw_shl_code=bash,true]GET /foo HTTP/1.0
GET /foo HTTP/1.1[/mw_shl_code]

知识补充:
对于collect() 函数,是比较常见的,但是对于下面内容,是什么意思。
collect { case Some(requestField) => requestField }这个作用,类似map。
##################
更多信息:

在Scala中,当我需要对集合的元素进行转换时,自然而然会使用到map方法。而当我们在对tuple类型的集合或者针对Map进行map操作时,通常更倾向于在map方法中使用case语句,这比直接使用_1与_2更加可读。例如:
[mw_shl_code=scala,true]val languageToCount = Map("Scala" -> 10, "Java" -> 20, "Ruby" -> 5)
languageToCount map { case (_, count) => count + 1 }[/mw_shl_code]

然而对于上述场景,其实我们也可以使用collect方法:
[mw_shl_code=scala,true]languageToCount collect { case (_, count) => count + 1 }
[/mw_shl_code]

参考
http://www.jianshu.com/p/fa2ed7ed391e



相关文章:

日志分析实战之清洗日志小实例1:使用spark&Scala分析Apache日志
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22856

日志分析实战之清洗日志小实例2:导入日志清洗代码并打包
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22862


日志分析实战之清洗日志小实例3:如何在spark shell中导入自定义包
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22881



日志分析实战之清洗日志小实例4:统计网站相关信息
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22900


日志分析实战之清洗日志小实例5:实现获取不能访问url
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22911


日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22928


日志分析实战之清洗日志小实例7:查看样本数据,保存统计数据到文件
http://www.aboutyun.com/forum.php?mod=viewthread&tid=22953


链接:http://pan.baidu.com/s/1pKXn8Ob 密码:yndp


本帖被以下淘专辑推荐:

已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条