使用正则表达式解析损坏的 Apache 日志
Parsing corrupt Apache logs using regex
我正在编写一个 Python 3.7.2 程序来解析 Apache 日志以查找所有成功的响应代码。我现在已经编写了正则表达式,它将所有正确的 Apache 日志条目解析为 [origin] [date/time] [HTML method/file/protocol] [response code] 和 [file size] 的单个元组] 然后我只是检查响应代码是否为 3xx。问题是有几个条目已损坏,有些损坏到无法读取,所以我在程序的不同部分将它们删除。 method/protocol 项上的几个只是缺少结束 "(引号),导致每次我解析该行时它都会抛出错误。我想我需要对 " OR 空格使用 RegEx Or 表达式,但是似乎将引号分成不同的元组项而不是寻找说,"GET 613.html HTTP/1.0" OR "GET 613.html HTTP/1.0 我是正则表达式的新手并且完全被难住了,任何人都可以解释什么我做错了吗?
我应该注意到日志中的一些信息已经被清除,它只显示 'local' 或 'remote' 而不是原始 IP,并且 OS/browser 信息被完全删除。
这是适用于有效条目的相关元组项的正则表达式:“(.*)?”我也试过:
"(.*)?("|\s) - 创建另一个元组项并仍然抛出错误
这是日志条目的片段,包括最后一个缺少的条目,它正在关闭“
本地 - - [27/Oct/1994:18:47:03 -0600] "GET index.html HTTP/1.0" 200 3185
本地 - - [27/Oct/1994:18:48:53 -0600] "GET index.html HTTP/1.0" 404 -
本地 - - [27/Oct/1994:18:49:55 -0600] "GET index.html HTTP/1.0" 303 3185
本地 - - [27/Oct/1994:18:50:25 -0600] "GET 612.html HTTP/1.0" 404 -
本地 - - [27/Oct/1994:18:50:41 -0600] "GET index.html HTTP/1.0" 200 388
local - - [27/Oct/1994:18:50:52 -0600] "GET 613.html HTTP/1.0 303 728
regex = '([(\w+)]+) - - \[(.*?)\] "(.*)?" (\d+) (\S+)'
import re
with open("validlogs.txt") as validlogs:
i = 0
array = []
successcodes = 0
for line in validlogs:
array.append(line)
loglength = len(array)
while (i < loglength):
line = re.match(regex, array[i]).groups()
if(line[3].startswith("3")):
successcodes+=1
i+=1
print("Number of successcodes: ", successcodes)
解析上面的日志响应应该给出 Number of success codes: 2
相反,我得到:追溯(最近一次通话):
文件 "test.py",第 24 行,位于
line = re.match(regex, array[i]).groups()
AttributeError: 'NoneType' 对象没有属性 'groups'
因为(我相信)正则表达式正在明确寻找 " 并且无法处理缺少它的行条目。
所以我最初使用 re.match 和 ([(\w+)]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)
以及 Try:
/ Except: continue
代码来解析所有实际匹配模式的日志。由于 ~750,000 行中的 ~100,000 行不符合正确的 Apache 日志模式,我最终将我的代码更改为 re.search 并使用更小的段。
例如:
with open("./http_access_log.txt") as logs:
for line in logs:
if re.search('\s*(30\d)\s\S+', line): #Checking for 30x redirect codes
redirectCounter += 1
我读到 re.match 比 re.search 快,但我觉得能够准确捕获最可能的日志条目(这处理了大约 2000 行以外的所有行,其中大部分有没有可用信息)更重要。
我正在编写一个 Python 3.7.2 程序来解析 Apache 日志以查找所有成功的响应代码。我现在已经编写了正则表达式,它将所有正确的 Apache 日志条目解析为 [origin] [date/time] [HTML method/file/protocol] [response code] 和 [file size] 的单个元组] 然后我只是检查响应代码是否为 3xx。问题是有几个条目已损坏,有些损坏到无法读取,所以我在程序的不同部分将它们删除。 method/protocol 项上的几个只是缺少结束 "(引号),导致每次我解析该行时它都会抛出错误。我想我需要对 " OR 空格使用 RegEx Or 表达式,但是似乎将引号分成不同的元组项而不是寻找说,"GET 613.html HTTP/1.0" OR "GET 613.html HTTP/1.0 我是正则表达式的新手并且完全被难住了,任何人都可以解释什么我做错了吗?
我应该注意到日志中的一些信息已经被清除,它只显示 'local' 或 'remote' 而不是原始 IP,并且 OS/browser 信息被完全删除。
这是适用于有效条目的相关元组项的正则表达式:“(.*)?”我也试过:
"(.*)?("|\s) - 创建另一个元组项并仍然抛出错误
这是日志条目的片段,包括最后一个缺少的条目,它正在关闭“
本地 - - [27/Oct/1994:18:47:03 -0600] "GET index.html HTTP/1.0" 200 3185
本地 - - [27/Oct/1994:18:48:53 -0600] "GET index.html HTTP/1.0" 404 -
本地 - - [27/Oct/1994:18:49:55 -0600] "GET index.html HTTP/1.0" 303 3185
本地 - - [27/Oct/1994:18:50:25 -0600] "GET 612.html HTTP/1.0" 404 -
本地 - - [27/Oct/1994:18:50:41 -0600] "GET index.html HTTP/1.0" 200 388
local - - [27/Oct/1994:18:50:52 -0600] "GET 613.html HTTP/1.0 303 728
regex = '([(\w+)]+) - - \[(.*?)\] "(.*)?" (\d+) (\S+)'
import re
with open("validlogs.txt") as validlogs:
i = 0
array = []
successcodes = 0
for line in validlogs:
array.append(line)
loglength = len(array)
while (i < loglength):
line = re.match(regex, array[i]).groups()
if(line[3].startswith("3")):
successcodes+=1
i+=1
print("Number of successcodes: ", successcodes)
解析上面的日志响应应该给出 Number of success codes: 2 相反,我得到:追溯(最近一次通话): 文件 "test.py",第 24 行,位于 line = re.match(regex, array[i]).groups() AttributeError: 'NoneType' 对象没有属性 'groups'
因为(我相信)正则表达式正在明确寻找 " 并且无法处理缺少它的行条目。
所以我最初使用 re.match 和 ([(\w+)]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+)
以及 Try:
/ Except: continue
代码来解析所有实际匹配模式的日志。由于 ~750,000 行中的 ~100,000 行不符合正确的 Apache 日志模式,我最终将我的代码更改为 re.search 并使用更小的段。
例如:
with open("./http_access_log.txt") as logs:
for line in logs:
if re.search('\s*(30\d)\s\S+', line): #Checking for 30x redirect codes
redirectCounter += 1
我读到 re.match 比 re.search 快,但我觉得能够准确捕获最可能的日志条目(这处理了大约 2000 行以外的所有行,其中大部分有没有可用信息)更重要。