如何使用spark读取每个日志行以匹配正则表达式模式?

时间:2016-08-11 08:04:41

标签: python apache-spark pyspark

以下程序抛出错误

from pyparsing import Regex, re
from pyspark import SparkContext
sc = SparkContext("local","hospital")
LOG_PATTERN ='(?P<Case_ID>[^ ;]+);(?P<Event_ID>[^ ;]+);(?P<Date_Time>[^ ;]+);(?P<Activity>[^;]+);(?P<Resource>[^ ;]+);(?P<Costs>[^ ;]+)'
logLine=sc.textFile("C:\TestLogs\Hospital.log").cache()
#logLine='1;35654423;30-12-2010:11.02;register request;Pete;50'
for line in logLine.readlines():
    match = re.search(LOG_PATTERN,logLine)
    Case_ID = match.group(1)
    Event_ID = match.group(2)
    Date_Time = match.group(3)
    Activity = match.group(4)
    Resource = match.group(5)
    Costs = match.group(6)
    print Case_ID
    print Event_ID  
    print Date_Time
    print Activity
    print Resource
    print Costs

错误:

  

Traceback(最近一次调用最后一次):文件   “C:/Spark/spark-1.6.1-bin-hadoop2.4/bin/hospital2.py”,第7行,在          对于logLine.readlines()中的行:AttributeError:'RDD'对象没有属性'readlines'

如果我添加open函数来读取文件,则会出现以下错误:

  

Traceback(最近一次调用最后一次):文件   “C:/Spark/spark-1.6.1-bin-hadoop2.4/bin/hospital2.py”,第7行,在          f = open(logLine,“r”)TypeError:强制转换为Unicode:需要字符串或缓冲区,找到RDD

似乎无法弄清楚如何逐行阅读并提取与模式匹配的单词。 此外,如果我只通过一个日志logLine='1;35654423;30-12-2010:11.02;register request;Pete;50'它也可以。我是新手,只知道python的基础知识。请帮忙。

2 个答案:

答案 0 :(得分:2)

你正在混淆。 这条线

logLine=sc.textFile("C:\TestLogs\Hospital.log")

创建RDD,RDD没有readlines()方法。 请在此处查看RDD API:

http://spark.apache.org/docs/latest/api/python/pyspark.html#pyspark.RDD

您可以使用collect()逐行检索RDD的内容。 readlines()是标准Python文件API的一部分,但在使用Spark中的文件时通常不需要它。 您只需使用textFile()加载文件,然后使用RDD API处理它,请参阅上面的链接。

答案 1 :(得分:1)

正如Matei所回答的那样,readlines()是Python API而sc.textFile将创建一个RDD,因此RDD没有属性readlines()的错误。

如果必须使用Spark API处理文件,可以在为模式创建的RDD上使用过滤器API,然后可以根据分隔符拆分输出。

如下例子:

    logLine = sc.textFile("C:\TestLogs\Hospital.log")
    logLine_Filtered = logLine.filter(lambda x: "LOG_PATTERN" in x)
    logLine_output  = logLine_Filtered(lambda a: a.split("<delimiter>")[0], a.split("<delimiter>")[1].....).collect()
logLine_output.first()

数据帧会更好