日志数据操作--json转成表格式

该博客介绍了如何使用SparkSQL从日志数据中提取信息。首先,通过split函数以符号'|'分割日志,然后利用get_json_object提取JSON字段,如'cm'、'ap'、'et'等,并进一步解析'cm'中的各项详细信息,如'ln'、'sv'等。最后,使用explode函数展开'et'列中的数组数据,展示完整信息。

日志处理流程,json转成表类型格式。

日志数据前有一时间戳,后面才是json格式数据。

导入SPARKSQL所需要的包
scala> import spark.implicits._
import spark.implicits._

scala> import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions._

scala> import org.apache.spark.sql._
import org.apache.spark.sql._

scala> import org.apache.spark.sql.types._
import org.apache.spark.sql.types._

 val rdd=sc.textFile("hdfs:///app/op.log")--读取数据
 val json=rdd.map(x=>x.split('|')).map(x=>(x(0),x(1))).map(x=>x._2)--符号“|”前后分割开。前面为时间戳,后面为日志数据。
 val df=json.toDF--转换成df
 val obj=df.select(get_json_object($"value","$.cm").alias("cm"))
 
 得到日志的表头,起别名
 val obj=df.select(get_json_object($"value","$.cm").alias("cm"),
				   get_json_object($"value","$.ap").alias("ap"),
				   get_json_object($"value","$.et").alias("et"))
 “cm”列里数据较多。都取出来。	
 val obj1=obj.select($"ap",
						   get_json_object($"cm","$.ln").alias("ln"),
						   get_json_object($"cm","$.sv").alias("sv"),
						   get_json_object($"cm","$.os").alias("os"),
						   get_json_object($"cm","$.g").alias("g"),
						   get_json_object($"cm","$.mid").alias("mid"),
						   get_json_object($"cm","$.nw").alias("nw"),
						   get_json_object($"cm","$.l").alias("l"),
						   get_json_object($"cm","$.vc").alias("vc"),
						   get_json_object($"cm","$.hw").alias("hw"),
						   get_json_object($"cm","$.ar").alias("ar"),
						   get_json_object($"cm","$.uid").alias("uid"),
						   get_json_object($"cm","$.t").alias("t"),
						   get_json_object($"cm","$.la").alias("la"),
						   get_json_object($"cm","$.md").alias("md"),
						   get_json_object($"cm","$.vn").alias("vn"),
						   get_json_object($"cm","$.ba").alias("ba"),
						   get_json_object($"cm","$.sr").alias("sr"),
					 $"et")
 将“et”列的数据取出来
 val obj2=obj1.select($"ap",$"ln",$"sv",$"os",$"g",$"mid",$"nw",$"l",$"vc",$"hw",$"ar",$"uid",$"t",$"la",$"md",$"vn",$"ba",$"sr",
						from_json($"et",ArrayType(StructType(StructField("ett",StringType)::
									  StructField("en",StringType)::
									  StructField("kv",StringType)::Nil))).alias("events")
					 )
 obj2.select($"ap",$"ln",$"sv",$"os",$"g",$"mid",$"nw",$"l",$"vc",$"hw",$"ar",$"uid",$"t",$"la",$"md",$"vn",$"ba",$"sr",
			 explode($"events")).show
 
 val obj3=obj2.select(explode($"events").alias("events")).show(false)
*/(1)访问量分析: a. 创建转换日志的工具类 AccessLogUtils,实现将 JSON 格式的字符串转 换为 AccessLog 对象。 b. 读取日志文件。日志文件中每行数据为 JSON 字符串,可以使用工具类 将 JSON 字符串转换为 AccessLog 对象。 c. 计算 PV。将上一步生成的 DataStream 转化为 Table 对象,执行 SQL 语句进行分组汇总,按照日期进行汇总,统计每组数据的数量,也就是 PV。 (2)异常日志分析 在日志中可以对异常情况进行分析。 a. 根据 HTTP 协议响应的状态码判断是否是异常日志。 正常返回结果的状态码是 200,服务器异常返回的状态码是 500,客户端请 求 URL 出现错误的状态码是 404。查询状态码是 500 的日志,也就是服务器 异常的日志,对于异常日志要实时监控处理。 b. 根据用户请求的响应时间判断是否是异常日志。定义响应时间超过 1 秒 就是异常日志。 (3)聚合分析 a. 连接 MySQL 数据库,创建数据,并保存分析结果。对日志的响应时 间进行聚合分析,统计每日最小响应时间、最大响应时间及平均响应时间. b. 对日志的流量进行聚合分析,统计每小时总的字节数、平均字节数。 c. 对每日响应时间进行分析。按照日期进行分组统计,计算响应时间的最小 值、最大值和平均值。 c. 以小时为单位对日志的流量进行统计。 e.将以上聚合结果写入 log_time 中。 //从文件中读取数据 val stream: DataStream[String] = env.readTextFile("data/access.log") //转换为 AccessLog 对象 val stream2: DataStream[AccessLog] = stream.map(json => { AccessLogUtils.read(json) })// 创建环境 val tableEnv = StreamTableEnvironment.create(env) // 将 DataStream 转换 val table = tableEnv.fromDataStream(stream2) //打印输出 schema table.printSchema() //创建临时 tableEnv.createTemporaryView("access_log", table) //计算每日 PV val table2 = tableEnv.sqlQuery("select createDate, " + "count(*) as logCount " + "from access_log " + "group by createDate ") //打印输出流 tableEnv.toChangelogStream(table2).print()//状态码是500的数据 val table2 = tableEnv.sqlQuery("select * " + "from access_log " + "where status=500 ") //响应时间过长 val table3 = tableEnv.sqlQuery("select * " + "from access_log " + "where responseTime>1 ")
06-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值