解析多行日志文件条目的正确spark | scala技术是什么? SQL跟踪文本文件:
# createStatement call (thread 132053, con-id 422996) at 2015-07-24 12:39:47.076339
# con info [con-id 422996, tx-id 47, cl-pid 50593, cl-ip 10.32.50.24, user: SAPABA, schema: SAPABA]
cursor_140481797152768_c22996 = con_c22996.cursor()
# begin PreparedStatement_execute (thread 132053, con-id 422996) at 2015-07-24 12:39:47.076422
# con info [con-id 422996, tx-id 47, cl-pid 50593, cl-ip 10.32.50.24, user: SAPABA, schema: SAPABA]
cursor_140481797152768_c22996.execute("SELECT DISTINCT blah blah blah")
# end PreparedStatement_execute (thread 132053, con-id 422996) at 2015-07-24 12:39:47.077706
每条记录由三行组成;每种记录类型的属性(例如createStatement
和PreparedStatement
)都不同。
我想逐行读取文件,确定记录类型,然后为每条记录创建一个数据帧行:
示例:
insert into prepared_statements values (132053,422996, '2015-07-24 12:39:47.076422','SELECT DISTINCT blah blah blah')
为了实现这一点,我需要检查每一行以确定它是哪种记录类型,然后读取接下来的两行以获取该记录类型的属性。另外,行格式根据记录的不同而不同,所以我需要有条件地检查每行三行的开始,以确定记录类型。是否有解析多行记录的火花技术?
答案 0 :(得分:3)
这是一个有效的解决方案,基于将每一行与下一个空行的索引进行匹配,然后按这些索引进行分组,将每个“逻辑记录”的行组合在一起。
假设输入在rdd
:
val indexedRows: RDD[(String, Long)] = rdd.zipWithIndex().cache()
val emptyRowIndices = indexedRows.filter(_._1.isEmpty).values.collect().sorted
val withIndexOfNextGap: RDD[(String, Long)] = indexedRows
.filter(!_._1.isEmpty)
.mapValues(i => emptyRowIndices.find(_ > i).getOrElse(0)) // finds lowest index of empty line greater than current line index
val logicalRecords: RDD[Iterable[String]] = withIndexOfNextGap.map(_.swap).groupByKey().values
logicalRecords.map(f) // f maps each Iterable[String] into whatever you need
请注意,此解决方案有一些注意事项: