1.四个需求

  需求一:求contentsize的平均值、最小值、最大值

  需求二:请各个不同返回值的出现的数据 ===> wordCount程序

  需求三:获取访问次数超过N次的IP地址

  需求四:获取访问次数最多的前K个endpoint的值 ==> TopN

2.主程序LogAnalyzer.scala

 package com.ibeifeng.bigdata.spark.core.log

 import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext} /**
* Apache日志分析
* Created by ibf on 01/15.
*/
object LogAnalyzer {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("log-analyzer")
.setMaster("local[*]")
.set("spark.eventLog.enabled", "true")
.set("spark.eventLog.dir", "hdfs://hadoop-senior01:8020/spark-history")
val sc = SparkContext.getOrCreate(conf) // ================日志分析具体代码==================
// HDFS上日志存储路径
val path = "/beifeng/spark/access/access.log" // 创建rdd
val rdd = sc.textFile(path) // rdd转换,返回进行后续操作
val apacheAccessLog: RDD[ApacheAccessLog] = rdd
// 过滤数据
.filter(line => ApacheAccessLog.isValidateLogLine(line))
.map(line => {
// 对line数据进行转换操作
ApacheAccessLog.parseLogLine(line)
}) // 对多次时候用的rdd进行cache
apacheAccessLog.cache() // 需求一:求contentsize的平均值、最小值、最大值
/*
* The average, min, and max content size of responses returned from the server.
* */
val contentSizeRDD: RDD[Long] = apacheAccessLog
// 提取计算需要的字段数据
.map(log => (log.contentSize)) // 对重复使用的RDD进行cache
contentSizeRDD.cache() // 开始计算平均值、最小值、最大值
val totalContentSize = contentSizeRDD.sum()
val totalCount = contentSizeRDD.count()
val avgSize = 1.0 * totalContentSize / totalCount
val minSize = contentSizeRDD.min()
val maxSize = contentSizeRDD.max() // 当RDD不使用的时候,进行unpersist
contentSizeRDD.unpersist() // 结果输出
println(s"ContentSize Avg:${avgSize}, Min: ${minSize}, Max: ${maxSize}") // 需求二:请各个不同返回值的出现的数据 ===> wordCount程序
/*
* A count of response code's returned.
* */
val responseCodeResultRDD = apacheAccessLog
// 提取需要的字段数据, 转换为key/value键值对,方便进行reduceByKey操作
// 当连续出现map或者flatMap的时候,将多个map/flatMap进行合并
.map(log => (log.responseCode, 1))
// 使用reduceByKey函数,按照key进行分组后,计算每个key出现的次数
.reduceByKey(_ + _) // 结果输出
println(s"""ResponseCode :${responseCodeResultRDD.collect().mkString(",")}""") // 需求三:获取访问次数超过N次的IP地址
// 需求三额外:对IP地址进行限制,部分黑名单IP地址不统计
/*
* All IPAddresses that have accessed this server more than N times.
* 1. 计算IP地址出现的次数 ===> WordCount程序
* 2. 数据过滤
* */
val blackIP = Array("200-55-104-193.dsl.prima.net.ar", "10.0.0.153", "208-38-57-205.ip.cal.radiant.net")
// 由于集合比较大,将集合的内容广播出去
val broadCastIP = sc.broadcast(blackIP)
val N = 10
val ipAddressRDD = apacheAccessLog
// 过滤IP地址在黑名单中的数据
.filter(log => !broadCastIP.value.contains(log.ipAddress))
// 获取计算需要的IP地址数据,并将返回值转换为Key/Value键值对类型
.map(log => (log.ipAddress, 1L))
// 使用reduceByKey函数进行聚合操作
.reduceByKey(_ + _)
// 过滤数据,要求IP地址必须出现N次以上
.filter(tuple => tuple._2 > N)
// 获取满足条件IP地址, 为了展示方便,将下面这行代码注释
// .map(tuple => tuple._1) // 结果输出
println(s"""IP Address :${ipAddressRDD.collect().mkString(",")}""") // 需求四:获取访问次数最多的前K个endpoint的值 ==> TopN
/*
* The top endpoints requested by count.
* 1. 先计算出每个endpoint的出现次数
* 2. 再进行topK的一个获取操作,获取出现次数最多的前K个值
* */
val K = 10
val topKValues = apacheAccessLog
// 获取计算需要的字段信息,并返回key/value键值对
.map(log => (log.endpoint, 1))
// 获取每个endpoint对应的出现次数
.reduceByKey(_ + _)
// 获取前10个元素, 而且使用我们自定义的排序类
.top(K)(LogSortingUtil.TupleOrdering)
// 如果只需要endpoint的值,不需要出现的次数,那么可以通过map函数进行转换
// .map(_._1) // 结果输出
println(s"""TopK values:${topKValues.mkString(",")}""") // 对不在使用的rdd,去除cache
apacheAccessLog.unpersist() // ================日志分析具体代码================== sc.stop()
}
}

3.需要的辅助类一(返回匹配的日志)

 package com.ibeifeng.bigdata.spark.core.log

 import scala.util.matching.Regex

 /**
* 64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET /twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846
* Created by ibf on 01/15.
*/
case class ApacheAccessLog(
ipAddress: String, // IP地址
clientId: String, // 客户端唯一标识符
userId: String, // 用户唯一标识符
serverTime: String, // 服务器时间
method: String, // 请求类型/方式
endpoint: String, // 请求的资源
protocol: String, // 请求的协议名称
responseCode: Int, // 请求返回值:比如:200、401
contentSize: Long // 返回的结果数据大小
) /**
* 64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET /twiki/bin/edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846
* on 01/15.
* 提供一些操作Apache Log的工具类供SparkCore使用
*/
object ApacheAccessLog {
// Apache日志的正则
val PARTTERN: Regex =
"""^(\S+) (\S+) (\S+) \[([\w:/]+\s[+\-]\d{4})\] "(\S+) (\S+) (\S+)" (\d{3}) (\d+)""".r /**
* 验证一下输入的数据是否符合给定的日志正则,如果符合返回true;否则返回false
*
* @param line
* @return
*/
def isValidateLogLine(line: String): Boolean = {
val options = PARTTERN.findFirstMatchIn(line) if (options.isEmpty) {
false
} else {
true
}
} /**
* 解析输入的日志数据
*
* @param line
* @return
*/
def parseLogLine(line: String): ApacheAccessLog = {
if (!isValidateLogLine(line)) {
throw new IllegalArgumentException("参数格式异常")
} // 从line中获取匹配的数据
val options = PARTTERN.findFirstMatchIn(line) // 获取matcher
val matcher = options.get // 构建返回值
ApacheAccessLog(
matcher.group(1), // 获取匹配字符串中第一个小括号中的值
matcher.group(2),
matcher.group(3),
matcher.group(4),
matcher.group(5),
matcher.group(6),
matcher.group(7),
matcher.group(8).toInt,
matcher.group(9).toLong
)
}
}

4.需要的辅助类二(自定义的一个二元组的比较器,方便进行TopN)

 package com.ibeifeng.bigdata.spark.core.log

 /**
* Created by ibf on 01/15.
*/
object LogSortingUtil { /**
* 自定义的一个二元组的比较器
*/
object TupleOrdering extends scala.math.Ordering[(String, Int)] {
override def compare(x: (String, Int), y: (String, Int)): Int = {
// 按照出现的次数进行比较,也就是按照二元组的第二个元素进行比较
x._2.compare(y._2)
}
} }

024 关于spark中日志分析案例的更多相关文章

  1. 日志分析_使用shell完整日志分析案例

    一.需求分析 1. 日志文件每天生成一份(需要将日志文件定时上传至hdfs) 2. 分析日志文件中包含的字段:访问IP,访问时间,访问URL,访问状态,访问流量 3. 现在有"昨日" ...

  2. Spark离线日志分析,连接Spark出现报错

    首先,我的代码是这样的 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object ...

  3. 大数据学习day20-----spark03-----RDD编程实战案例(1 计算订单分类成交金额,2 将订单信息关联分类信息,并将这些数据存入Hbase中,3 使用Spark读取日志文件,根据Ip地址,查询地址对应的位置信息

    1 RDD编程实战案例一 数据样例 字段说明: 其中cid中1代表手机,2代表家具,3代表服装 1.1 计算订单分类成交金额 需求:在给定的订单数据,根据订单的分类ID进行聚合,然后管理订单分类名称, ...

  4. spark SQL学习(综合案例-日志分析)

    日志分析 scala> import org.apache.spark.sql.types._ scala> import org.apache.spark.sql.Row scala&g ...

  5. Spark SQL慕课网日志分析(1)--系列软件(单机)安装配置使用

    来源: 慕课网 Spark SQL慕课网日志分析_大数据实战 目标: spark系列软件的伪分布式的安装.配置.编译 spark的使用 系统: mac 10.13.3 /ubuntu 16.06,两个 ...

  6. Hadoop学习笔记—20.网站日志分析项目案例(一)项目介绍

    网站日志分析项目案例(一)项目介绍:当前页面 网站日志分析项目案例(二)数据清洗:http://www.cnblogs.com/edisonchou/p/4458219.html 网站日志分析项目案例 ...

  7. Hadoop学习笔记—20.网站日志分析项目案例(二)数据清洗

    网站日志分析项目案例(一)项目介绍:http://www.cnblogs.com/edisonchou/p/4449082.html 网站日志分析项目案例(二)数据清洗:当前页面 网站日志分析项目案例 ...

  8. Hadoop学习笔记—20.网站日志分析项目案例(三)统计分析

    网站日志分析项目案例(一)项目介绍:http://www.cnblogs.com/edisonchou/p/4449082.html 网站日志分析项目案例(二)数据清洗:http://www.cnbl ...

  9. 通过grep来进行日志分析,grep -C和配合awk实际对catalina.out使用案例

    本文介绍通过grep来进行日志分析,主要介绍grep -C和配合awk实际对catalina.out使用案例 grep可以对日志文件进行筛选,统计,查询,快速定位bug. 首先,你的日志需要比较规范, ...

随机推荐

  1. THUWC2019爆零记

    Day -1 现在在机房里,准备敲敲板子什么的. 今天晚上放假诶,要好好睡一下.好好睡是不可能的,这辈子不可能的. Day 0 现在在酒店,\(lwh\)神仙在超越,我打了个\(treap\)的板子就 ...

  2. 【BZOJ3139】[HNOI2013]比赛(搜索)

    [BZOJ3139][HNOI2013]比赛(搜索) 题面 BZOJ 洛谷 题解 双倍经验

  3. NOIP2018 Day0 回首向来萧瑟处,也无风雨也无晴

    回首向来萧瑟处,也无风雨也无晴 NOIP2018 Day0 感想  by HGOI ljc20020730 Back ground: /* HGOI 陈功杰让我们写初赛总结?! (考这么烂还要写总结? ...

  4. 洛谷 P1144 最短路计数 解题报告

    P1144 最短路计数 题目描述 给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\).问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含2个正 ...

  5. 使用Rider写一个C#的Hello World程序

    1. 安装Rider 首先到Jetbrains官网下载Rider:https://www.jetbrains.com/rider/ 然后到IntelliJ IDEA 注册码获得注册码. 2. 安装do ...

  6. 【CF884D】Boxes And Balls k叉哈夫曼树

    题目大意:给定一个大小为 N 的集合,每次可以从中挑出 2 个或 3 个数进行合并,合并的代价是几个数的权值和,求将这些数合并成 1 个的最小代价是多少. 引理:K 叉哈夫曼树需要保证 \((n-1) ...

  7. linux command ------ netstat

    netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表.实际的网络连接以及每一个网络接口设备的状态信息. 语法选项 netstat [选项] -a或--all:显示所有连线中的 ...

  8. Excel:公式应用技巧汇总

    1.合并单元格添加序号:=MAX(A$1:A1)+1 不重复的个数: 公式1:{=SUM(1/COUNTIF(A2:A8,A2:A8))} 公式2:{=SUM(--(MATCH(A2:A8,A2:A8 ...

  9. Spring RedisTemplate操作-ZSet操作(6)

    @Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...

  10. 模拟jQuery中的ready方法及实现按需加载css,js

    一.ready函数的实现 经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码,涉及到的模块比较多,(水平有限)代码比较难看懂:自己结合 ...