需要使用spark来提取特定消息

时间:2016-07-23 18:18:21

标签: scala apache-spark

我很新兴。我试图从以下错误日志中提取日期和错误消息

  

11月11日09:44:53 www httpd [1933]:[错误] [客户端10.2.23.89](36)文件名太长

     

11月11日09:49:38 www httpd [2728]:[错误] [客户端10.2.23.128](36)文件名太长

     

11月11日10:14:23 www httpd [4530]:[错误] [客户端10.2.23.243](36)文件名太长

     

11月11日10:15:24 www httpd [4630]:[错误] [客户端10.2.23.42](36)文件名太长

     

11月11日12:05:07 www httpd [12062]:[错误] [客户端10.2.23.148](36)文件名太长

这是我在scala shell中使用的脚本

val inputfile = sc.textFile("hdfs://localhost:8020/kirthi/errorlog.txt")

val elog = inputfile.map(line => (line.substring(0, 6),line.substring(65, 83)))

elog.collect()

这是我得到的输出,但它并不像预期的那样。在所有元组中都没有完全提取消息。由于每行日志的长度不同。

 Array[(String, String)] = Array((Nov 11,File name too long), (Nov 11,)File name too lon), (Nov 11,)File name too lon), (Nov 11,File name too long), (Nov 11,6)File name too lo))

但我希望输出如下所示

Array[(String, String)] = Array((Nov 11,File name too long), (Nov 11,File name too long), (Nov 11,File name too long), (Nov 11,File name too long), (Nov 11,File name too long))

如果我增加子串的长度,我就会遇到超出边界期望错误的数组。

1 个答案:

答案 0 :(得分:1)

解析文本的一种明显方法是使用正则表达式,当然。在这种情况下,假设这些日志记录的结​​构总是如下:

<date: MMM dd HH:mm:ss> www httpd[<number>]: [<level>] [client <IP>] (<number>)<text>

您可以使用以下内容:

val regex = "(\\w+ \\d+) [0-9:]+ www httpd\\[\\d+\\]: \\[\\w+\\] \\[.+\\] \\(\\d+\\)(.+)$".r

匹配此结构,并将捕获日期部分和结尾处的文本,例如使用模式匹配:

val elog = inputfile.map { case regex(date, text) => (date, text) } 

P.S。这不是一个Spark问题(假设您可以将集群中的所有数据收集到驱动程序应用程序中,那么Spark部分就是正确的。)