Выделяем поля из логов nginx на python

Jan 01, 2010 18:30


Для анализа логов nginx мне понадобилось регулярное выражение, которое бы корректно разделяло запись на отдельные поля. Немного по-колдовав над логом, я понял, что наилучший способ разобраться в формате лога - это выцепить его из конфигурации сервера.

Кроме очевидного плюса - выделение полей с учетом всех разделителей и кавычек, использование формата позволяет получить именованные поля.

Вот код, который у меня получился, возможно пригодится.

import re # формат из конфигурации nginx FORMAT = '$remote_addr - $remote_user [$time_local] "$request" $status' + \ ' $bytes_sent "$http_referer"' + \ ' "$http_user_agent" "$gzip_ratio" "$cookie" $hostname' # выражение, описывающее переменную в конфигурации логов nginx TOKEN = '\$([a-z\_]+)' # возможные скобки и кавычки вокруг переменных в конфигурации логов nginx POSSIBLE_QUOTES = ('[]', '"', '\'') def get_matcher(format): quotes = re.escape(''.join(POSSIBLE_QUOTES)) pat = format for token in re.findall(TOKEN, format): res = re.search('([%s]?)(\$%s)([%s]?)' % \ (quotes, token, quotes), format).groups() if not res: continue elif res[0] <> res[2]: tq = res[0] + res[2] tq_escaped = '\%s|\%s' % (res[0], res[2]) else: tq = res[0] tq_escaped = '\%s' % res[0] tq = re.escape(tq) tq_escaped = re.escape(tq_escaped) if not tq: ftoken = '\$%s' % (token) ptoken = '(?P<' + token + '>[^\ ]*)' else: ftoken = '[%s]\$%s[%s]' % (tq, token, tq) ptoken = '[%s](?P<%s>(?:%s|[^%s])*)[%s]' % (tq, token, tq_escaped, tq, tq) pat = re.sub(ftoken, ptoken, pat) patc = re.compile(pat) def matcher(line): return patc.match(line) return matcher def main(): f = file('access_log') matcher = get_matcher(FORMAT) for line in f: print matcher(line).groupdict()
Возможно кому-нибудь будет полезным

UPD: Немного поправил код, чтобы он корректно работал с записями, в которых встречаются поля вида: “some text with escaped \” qoute”
--
Этот, а также другие мои посты по it-тематике вы можете прочитать здесь

python, Разработка

Previous post Next post
Up