日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url

简介: 日志分析实战之清洗日志小实例6:获取uri点击量排序并得到最高的url

下面我们开始统计链接的点击量,并做排序。

我们统计记录的时候,为了防止空记录等异常的情况,我们创建一条空记录

val nullObject = AccessLogRecord("", "", "", "", "GET /foo HTTP/1.1", "", "", "", "")

下面我们开始找点击量最高的链接。


首先获取我们想要的uri


val uriCounts = log.map(p.parseRecord(_).getOrElse(nullObject).request)
                  .map(_.split(" ")(1))
                  .filter(_ != "/foo")

上面的代码做一个简单解释:

p.parseRecord(_)解析记录

p.parseRecord(_).getOrElse(nullObject)如何没有取到值,则使用nullObject,也就是我们上面定义的对象

p.parseRecord(_).getOrElse(nullObject).request也就是我们取到uri

.map(_.split(" ")(1))是取到我们过滤的url,过滤掉不想要的版本等信息

 .filter(_ != "/foo")则是再次过滤掉/foo[也就是空记录]

这样就获取了uri,然后我们输出

uriCounts.collect.foreach(print)

c6adf927781e2d36359a90c9ddbef6f3.jpg

下面我们统计点击量



val uriCounts = log.map(p.parseRecord(_).getOrElse(nullObject).request)
                  .map(_.split(" ")(1))
                  .map(uri => (uri, 1))
                  .reduceByKey((a, b) => a + b)


rdd转换为数组




val uriToCount = uriCounts.collect


数组转换为序列并排序



import scala.collection.immutable.ListMap
val uriHitCount = ListMap(uriToCount.toSeq.sortWith(_._2 > _._2):_*)

12db63d9f311b7e591c2d0982b203945.jpg

#############################

这里留下一个问题,如果上面元素不是2,而是为sortWith(_._1 > _._1)是对什么排序

import scala.collection.immutable.ListMap
val uriHitCount = ListMap(uriToCount.toSeq.sortWith(_._1 > _._1):_*)

#############################

3d215861311bc5e15689c4a0f89d9bf5.jpg

输出

uriHitCount.take(10).foreach(println)

90a982b316ddbdf4e37a4b73d552881c.jpg

上面便是排序的结果

点击最高的uri
如果想得出点击最高的uri

uriHitCount.take(1).foreach(println)

563df5644efa45cd8d8a3ec05c4785c2.jpg

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

知识补充:

Scala代码看上去很少,但是内容却是很丰富的。上面用到的相关知识,这里补充,供大家能看懂上面代码


getOrElse:

println(a.get("k1").getOrElse("default")) //根据key读取元素,不存在就替换成默认值


在Spark中写法是:persons.getOrElse("Spark",1000) //如果persons这个Map中包含有Spark,取出它的值,如果没有,值就是1000。


reduce、reduceByKey


reduce(binary_function)

reduce将RDD中元素前两个传给输入函数,产生一个新的return值,新产生的return值与RDD中下一个元素(第三个元素)组成两个元素,再被传给输入函数,直到最后只有一个值为止。


val c = sc.parallelize(1 to 10)
c.reduce((x, y) => x + y)//结果55


具体过程,RDD有1 2 3 4 5 6 7 8 9 10个元素,

1+2=3

3+3=6

6+4=10

10+5=15

15+6=21

21+7=28

28+8=36

36+9=45

45+10=55


reduceByKey(binary_function)

reduceByKey就是对元素为KV对的RDD中Key相同的元素的Value进行binary_function的reduce操作,因此,Key相同


的多个元素的值被reduce为一个值,然后与原RDD中的Key组成一个新的KV对。

val a = sc.parallelize(List((1,2),(1,3),(3,4),(3,6)))

a.reduceByKey((x,y) => x + y).collect

//结果 Array((1,5), (3,10))



Seq


Sequence都有一个预定义的顺序。

scala> Seq(1, 1, 2)

res3: Seq[Int] = List(1, 1, 2)

(注意返回的结果是一个List。Seq是一个trait;List是它的一个实现类。Seq对象是一个工厂对象,正如你所看到


的,它会创建一个List。)


集合之间可以相互进行转换。

def toArray : Array[A]

def toArray [B >: A] (implicit arg0: ClassManifest[B]) : Array[B]

def toBuffer [B >: A] : Buffer[B]

def toIndexedSeq [B >: A] : IndexedSeq[B]

def toIterable : Iterable[A]

def toIterator : Iterator[A]

def toList : List[A]

def toMap [T, U] (implicit ev: <:<[A, (T, U)]) : Map[T, U]

def toSeq : Seq[A]

def toSet [B >: A] : Set[B]

def toStream : Stream[A]

def toString () : String

def toTraversable : Traversable[A]


我们可以把一个Map转换成一个数组,然后得到一个键值对数组。


scala> Map(1 -> 2).toArray

res41: Array[(Int, Int)] = Array((1,2))


sortWith

排序操作(sorted, sortWith, sortBy)根据不同的条件对序列元素进行排序。更多排序内容推荐参考

Scala的map实现key和value排序及各种排序比较等知识讨论

http://www.aboutyun.com/forum.php?mod=viewthread&tid=22942

相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
8月前
|
运维 安全 数据可视化
日志审查安排工具实战攻略:中小团队如何通过日志审查安排工具建立可控、安全的审查机制?
在审计敏感时代,日志审查安排工具成为安全运维与合规管理的关键利器。它实现审查任务的流程化、周期化与可视化,支持多系统协作、责任到人,确保“可控、可查、可追”的日志治理。工具如板栗看板、Asana、Monday 等提供任务调度、问题闭环与合规对接能力,助力企业构建高效、透明的日志审查体系,提升安全与合规水平。
|
存储 运维 监控
超越传统模型:从零开始构建高效的日志分析平台——基于Elasticsearch的实战指南
【10月更文挑战第8天】随着互联网应用和微服务架构的普及,系统产生的日志数据量日益增长。有效地收集、存储、检索和分析这些日志对于监控系统健康状态、快速定位问题以及优化性能至关重要。Elasticsearch 作为一种分布式的搜索和分析引擎,以其强大的全文检索能力和实时数据分析能力成为日志处理的理想选择。
1014 6
|
9月前
|
人工智能 运维 监控
Aipy实战:分析apache2日志中的网站攻击痕迹
Apache2日志系统灵活且信息全面,但安全分析、实时分析和合规性审计存在较高技术门槛。为降低难度,可借助AI工具如aipy高效分析日志,快速发现攻击痕迹并提供反制措施。通过结合AI与学习技术知识,新手运维人员能更轻松掌握复杂日志分析任务,提升工作效率与技能水平。
|
存储 算法 Go
go语言并发实战——日志收集系统(七) etcd的介绍与简单使用
go语言并发实战——日志收集系统(七) etcd的介绍与简单使用
229 0
|
Java 程序员 应用服务中间件
「测试线排查的一些经验-中篇」&& 调试日志实战
「测试线排查的一些经验-中篇」&& 调试日志实战
263 1
「测试线排查的一些经验-中篇」&& 调试日志实战
|
Java Maven Spring
超实用的SpringAOP实战之日志记录
【11月更文挑战第11天】本文介绍了如何使用 Spring AOP 实现日志记录功能。首先概述了日志记录的重要性及 Spring AOP 的优势,然后详细讲解了搭建 Spring AOP 环境、定义日志切面、优化日志内容和格式的方法,最后通过测试验证日志记录功能的准确性和完整性。通过这些步骤,可以有效提升系统的可维护性和可追踪性。
498 1
|
数据采集 机器学习/深度学习 存储
使用 Python 清洗日志数据
使用 Python 清洗日志数据
384 2
|
监控 Go
go语言并发实战——日志收集系统(八) go语言操作etcd以及利用watch实现对键值的监控
go语言并发实战——日志收集系统(八) go语言操作etcd以及利用watch实现对键值的监控
302 1
go语言并发实战——日志收集系统(八) go语言操作etcd以及利用watch实现对键值的监控
|
XML Java Maven
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)
这篇文章是Spring5框架的入门到实战教程,介绍了Spring5的新功能——整合日志框架Log4j2,包括Spring5对日志框架的通用封装、如何在项目中引入Log4j2、编写Log4j2的XML配置文件,并通过测试类展示了如何使用Log4j2进行日志记录。
Spring5入门到实战------16、Spring5新功能 --整合日志框架(Log4j2)