Анализ поврежденных журналов Apache с помощью регулярных выражений - PullRequest
0 голосов
/ 08 февраля 2019

Я пишу программу на Python 3.7.2 для анализа журналов Apache в поисках всех успешных кодов ответов.У меня прямо сейчас написано регулярное выражение, которое будет анализировать все правильные записи в журнале Apache на отдельные кортежи [origin] [date / time] [HTML метод / файл / протокол] [код ответа] и [размер файла], а затем я просто проверяючтобы увидеть, если код ответа 3xx.Проблема в том, что есть несколько поврежденных записей, некоторые настолько повреждены, что их невозможно прочитать, поэтому я удалил их в другой части программы.Некоторые просто пропускают закрывающую "(кавычку) на элементе метода / протокола, заставляя его выдавать ошибку каждый раз, когда я анализирую эту строку. Я думаю, что мне нужно использовать выражение RegEx Or для" ИЛИ пробела, но это кажетсяразбить цитату на другой элемент кортежа вместо поиска, скажем, "GET 613.html HTTP / 1.0" ИЛИ "GET 613.html HTTP / 1.0 Я новичок в регулярных выражениях и полностью озадачен, может кто-нибудь объяснить, что я делаюнеправильно?

Следует отметить, что в журналах очищена некоторая информация, вместо IP-адреса источника отображается только «локальный» или «удаленный», а информация об ОС / браузере полностью удаляется.

Это регулярное выражение для соответствующего элемента кортежа, который работает с действительными записями: «(. *)?» Я также пробовал:

»(. *)? (« | \ S) - создает другойэлемент кортежа и по-прежнему выдает ошибку

Вот фрагмент записей журнала, включая последнюю запись, в которой отсутствует закрывающаяся запись "

local - - [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 388local - - [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)

При анализе ответов журнала, приведенных выше, должно быть получено Количество кодов успеха: 2Вместо этого я получаю: Traceback (последний вызов был последним): файл «test.py», строка 24, в строке = re.match (regex, array [i]). Groups () AttributeError: «Объект NoneType» не имеет атрибута »groups '

, потому что (я полагаю) регулярное выражение явно ищет "и не может обработать запись строки, которая его пропускает.

1 Ответ

0 голосов
/ 15 февраля 2019

Итак, я изначально использовал re.match с ([(\w+)]+) - - \[(.*?)\] "(.*?)" (\d+) (\d+) с кодом Try: / Except: continue для анализа всех журналов, которые на самом деле соответствовали шаблону.Поскольку ~ 100 000 из ~ 750 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 строк, большинство из которых не имеют полезной информации), было большеважно.

...