Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 24, 2012 15:09:47

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

С помощью библиотеки curses нужно реализовать чтение журналов сервера Apache. Для этого мы используем вспомогательную программу. Ее код ниже и она работает так, как надо. Пример содержания логов Apache можно посмотреть на вики.

#!/usr/bin/env python
import sys
import re
log_line_re = re.compile(r'''(?P<remote_host>\S+) #IP ADRESS
							\s+ #whitespace
							\S+ #remote logname
							\s+ #whitespace
							\S+ #remote user
							\s+ #whitespace
							\[[^\[\]]+\] #time
							\s+ #whitespace
							"[^"]+" #first line of request
							\s+ #whitespace
							(?P<status>\d+)
							\s+ #whitespace
							(?P<bytes_sent>-|\d+)
							\s+ #whitespace
							''', re.VERBOSE)
def dictify_logline(line):
	m = log_line_re.match(line)
	if m:
		groupdict = m.groupdict()
		if groupdict['bytes_sent'] == '-':
			groupdict['bytes_sent'] = '0'
		return groupdict
	else:
		return {'remote_host': None,
				'status': None,
				'bytes_sent': 0
		}
def generate_log_report(logfile):
	report_dict = {}
	for line in logfile:
		line_dict = dictify_logline(line)
		print line_dict
		try:
			bytes_sent = int(line_dict['bytes_sent'])
		except ValueError:
			continue
		report_dict.setdefault(line_dict['remote_host'], []).append(bytes_sent)
	return report_dict
if __name__ == "__main__":
	if not len(sys.argv) > 1:
		print __doc__ 
		sys.exit(1)
	infile_name = sys.argv[1]
	try:
		infile = open(infile_name, 'r')
	except IOError:
		print "You must specify a valid file parse"
		print __doc__
		sys.exit(1)
	log_report = generate_log_report(infile)
	print log_report
	infile.close()

А вот программа с библиотекой curses и ошибки, которые выдаются. Может кто сможет помочь с этим и объяснить в чем причина проблемы?

#!/usr/bin/env python
import curses
from pre import dictify_logline
import sys
import operator
class CursesLogViewer(object):
	def __init__(self, logfile=None):
		self.screen = curses.initscr()
		self.curr_topline = 0
		self.logfile = logfile
		self.loglines = []
	def page_up(self):
		self.curr_topline = self.curr_topline - (2 * curses.LINE)
		if self.curr_topline < 0:
			self.curr_topline = 0
		self.draw_loglines()
	def page_down(self):
		self.draw_loglines()
	def top(self):
		self.curr_topline = 0
		self.draw_loglines()
	def sortby(self, field):
		self.loglines.sort(key=operator.itemgetter(field))
		self.top()
	def set_logfile(self, logfile):
		self.logfile = logfile
		self.load_loglines()
	def load_loglines(self):
		self.loglines = []
		logfile = open(self.logfile, 'r')
		for i, line in enumerate(logfile):
			line_dict = dictify_logline(line)
		self.loglines.append((i + 1, line_dict['remote_host'], line_dict['status'], int(line_dict['bytes_sent']), line.rstrip()))
		logfile.close()
		self.draw_loglines()
	def draw_loglines(self):
		self.screen.clear()
		status_col = 4
		bytes_col = 6
		remote_host_col = 16
		status_start = 0
		bytes_start = 4
		remote_host_start = 10
		lines_start = 26
		logline_cols = curses.COLS-status_col-bytes_col-remote_host_col-1
		for i in range(curses.LINE):
			c = self.curr_topline
			try:
				 curr_line = self.loglines[c]
			except IndexError:
				break
			self.screen.addstr(i, status_start, str(curr_line[2]))
			self.screen.addstr(i, bytes_start, str(curr_line[3]))
			self.screen.addstr(i, remote_host_start, str(curr_line[1]))
			self.screen.addstr(i, lines_start, str(curr_line[4]), logline_cols)
			self.curr_topline += 1
		self.screen.refresh()
	def main_loop(self, stdscr):
		stdscr.clear()
		self.load_loglines()
		while True:
			c = self.screen.getch()
			try:
				c = chr(c)
			except ValueError:
				continue
			if c == 'd':
				self.page_down()
			elif c == 'u':
				self.page_up()
			elif c == 't':
				self.top()
			elif c == 'b':
				self.sortby(3)
			elif c == 'h':
				self.sortby(1)
			elif c == 's':
				self.sortby(2)
			elif c == 'r':
				self.sortby(0)
			elif c == 'q':
				break
if __name__ == "__main__":
	infile = sys.argv[1]
	c = CursesLogViewer()
	curses.wrapper(c.main_loop)

Ошибка следующая:

root@debianhome/user# python cur.py access.log
Traceback (most recent call last):
File “cur.py”, line 88, in <module>
curses.wrapper(c.main_loop)
File “/usr/lib/python2.6/curses/wrapper.py”, line 43, in wrapper
return func(stdscr, *args, **kwds)
File “cur.py”, line 62, in main_loop
self.load_loglines()
File “cur.py”, line 32, in load_loglines
logfile = open(self.logfile, ‘r’)
TypeError: coercing to Unicode: need string or buffer, NoneType found

Офлайн

#2 Дек. 24, 2012 15:28:55

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

имя файла не вводится

c = CursesLogViewer(infile)

Офлайн

#3 Дек. 24, 2012 16:08:38

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

sergeek
имя файла не вводится
С одной ошибкой помогло, зато теперь появилось следующее:

Traceback (most recent call last):
File “cur.py”, line 88, in <module>
curses.wrapper(c.main_loop)
File “/usr/lib/python2.6/curses/wrapper.py”, line 43, in wrapper
return func(stdscr, *args, **kwds)
File “cur.py”, line 62, in main_loop
self.load_loglines()
File “cur.py”, line 37, in load_loglines
self.draw_loglines()
File “cur.py”, line 48, in draw_loglines
for i in range(curses.LINE):
AttributeError: ‘module’ object has no attribute ‘LINE’

Офлайн

#4 Дек. 24, 2012 16:16:34

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

да, ошибка по невнимательности, метод curses.LINES, но проблема в том, что программа запустилась, но выводит только последнюю строчку логов, а не весь лог целиком.

Офлайн

#5 Дек. 24, 2012 17:11:09

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

может

def load_loglines(self):
		self.loglines = []
		logfile = open(self.logfile, 'r')
		for i, line in enumerate(logfile):
			line_dict = dictify_logline(line)
		self.loglines.append((i + 1, line_dict['remote_host'], line_dict['status'], int(line_dict['bytes_sent']), line.rstrip()))
		logfile.close()
		self.draw_loglines()
заменить на
def load_loglines(self):
        self.loglines = []
        logfile = open(self.logfile, 'r')
        for i, line in enumerate(logfile):
                line_dict = dictify_logline(line)
                self.loglines.append((i + 1, line_dict['remote_host'], line_dict['status'], int(line_dict['bytes_sent']), line.rstrip()))
        logfile.close()
        self.draw_loglines()

Офлайн

#6 Дек. 24, 2012 17:47:32

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

sergeek
может
спасибо) Только работать начал с python и пока проблемным является все эта идея с отступами, хоть и стараюсь следить.

Офлайн

#7 Дек. 24, 2012 18:01:46

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

Damassk
хорошие иде сами делают отступы, я, например, слежу только за окончанием отступа. И вообще никогда не делал ошибок из-за отступов, не понимаю как они могут создавать проблемы

Офлайн

#8 Дек. 24, 2012 18:23:44

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

sergeek
хорошие иде сами делают отступы, я, например, слежу только за окончанием отступа. И вообще никогда не делал ошибок из-за отступов, не понимаю как они могут создавать проблемы
Это все С, с его “пиши как хочу, компилятор все поймет”. тут все-таки структура важна, да и это быстро привыкнется)) стоит пописать недельки 2 и все) а отступы да, по большей части сами задаются, но вот иногда бывают такие казусы)

Офлайн

#9 Дек. 24, 2012 18:47:02

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

после С бОльшая проблема скорее в том, что палец постоянно будет тянутся к клавише с `;'

Офлайн

#10 Дек. 24, 2012 19:07:47

Damassk
Зарегистрирован: 2012-12-24
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с библиотекой curses. Задача анализа журналов сервера Apache.

sergeek
после С бОльшая проблема скорее в том, что палец постоянно будет тянутся к клавише с `;'
ну это одна из проблем))))

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version