Форум сайта python.su
0
В питоне новичек. Использую CentOS 5.7 и python 2.4 (обновить python не проблема).
Пишу парсер логов.
Задача:
1) рекурсивно парсить файлы в директории и всех вложенных директориях.
2) при нахождении нужного шаблона, введенного в качестве аргумента скрипту вручную, подниматься и парсить несколько строк выше, чтобы получить дату и время события в логе (такова структура лога).
dir = '/var/log/mysoft/'
for root, dirs, files in os.walk(dir):
for name in files:
fullname = os.path.join(root, name)
fh = open(fullname)
for line in fh.readlines():
if re.search(sys.argv[1], line):
print fullname
print line
Офлайн
25
1. readlines - не самый оптимальный вариант. Лучше избегать его.
2. зачем os.walk? логи могут быть в поддиректориях?
3. лучше всего - дайте пример лога
Офлайн
0
s0rgИзбегать в пользу чего?
1. readlines - не самый оптимальный вариант. Лучше избегать его.
s0rgДа, могут.
2. зачем os.walk? логи могут быть в поддиректориях?
s0rg
3. лучше всего - дайте пример лога
Date: 29.01.2012 10:16
java.lang.NullPointerException
hirondelle.electricity.main.home.Spending.validateState(Spending.java:93)
hirondelle.electricity.main.home.Spending.<init>(Spending.java:37)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at
hirondelle.web4j.model.ModelCtorUtil.buildModelObject(Unknown Source)
at hirondelle.web4j.model.ModelFromRequest.build(Unknown
Source)
at
hirondelle.electricity.main.home.SpendingAction.validateUserInput(SpendingAc
tion.java:45)
at
hirondelle.web4j.action.ActionTemplateListAndEdit.execute(Unknown Source)
at
hirondelle.web4j.Controller.checkOwnershipThenExecuteAction(Unknown Source)
at hirondelle.web4j.Controller.processRequest(Unknown
Source)
at hirondelle.web4j.Controller.doPost(Unknown Source)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
Офлайн
253
гораздо быстрее будет просто read
и поиск нужного вам места в полученной строке регулярным выражением. Если надо более аккуратно делать - то выкусить потом кусок вокруг найденного места и распарсить его по человечески например с использованием pyparsing или регулярками.
Это будет хорошо работать если логи маленькие (те лезут в оперативку), но судя по всему у вас они такие.
Если таких действий в дальнейшем будет много логичнее засосать все в базу данных, например в mongodb http://www.slideshare.net/WombatNation/logging-app-behavior-to-mongo-db
Офлайн
857
lomachlicense()
python 2.4 (обновить python не проблема)
2.4 2.3 2004 PSF yes
Офлайн
0
doza_andУ меня логи как раз не маленькие с различными уровнями вложенности.
гораздо быстрее будет просто read
и поиск нужного вам места в полученной строке регулярным выражением. Если надо более аккуратно делать - то выкусить потом кусок вокруг найденного места и распарсить его по человечески например с использованием pyparsing или регулярками.
Это будет хорошо работать если логи маленькие (те лезут в оперативку), но судя по всему у вас они такие.
Если таких действий в дальнейшем будет много логичнее засосать все в базу данных, например в mongodb http://www.slideshare.net/WombatNation/logging-app-behavior-to-mongo-db
Офлайн
25
lomachВам тогда нужно посмотреть в сторону inotify (он точно есть в Twisted)
пишутся очень интенсивно.
#!/usr/bin/env python
#coding: utf8
LOG_EXAMPLE='''Date: 29.01.2012 10:16
java.lang.NullPointerException
hirondelle.electricity.main.home.Spending.validateState(Spending.java:93)
hirondelle.electricity.main.home.Spending.<init>(Spending.java:37)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at hirondelle.web4j.model.ModelCtorUtil.buildModelObject(Unknown Source)
at hirondelle.web4j.model.ModelFromRequest.build(Unknown Source)
at hirondelle.electricity.main.home.SpendingAction.validateUserInput(SpendingAction.java:45)
at hirondelle.web4j.action.ActionTemplateListAndEdit.execute(Unknown Source)
at hirondelle.web4j.Controller.checkOwnershipThenExecuteAction(Unknown Source)
at hirondelle.web4j.Controller.processRequest(Unknown Source)
at hirondelle.web4j.Controller.doPost(Unknown Source)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
'''.splitlines()
def simple_parser(log, needle):
last_date = None
for line in log:
line = line.strip()
if line:
if line.startswith('Date:'):
last_date = line
elif (needle in line) and (last_date is not None):
return (last_date, line)
return (None, None)
print simple_parser(LOG_EXAMPLE, 'Spending.java:93')
#output: ('Date: 29.01.2012 10:16', 'hirondelle.electricity.main.home.Spending.validateState(Spending.java:93)')
Офлайн
0
py.user.next
Вы меня пристыдили. Обновил python до версии 2.7.2.
Проблему решили с использованием “grep -B -A”.
Не знаю, насколько это грязный хак, но работает.
Всем спасибо за помощь.
Отредактировано (Фев. 25, 2012 10:48:19)
Офлайн