Форум сайта python.su
0
С помощью библиотеки 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()
#!/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)
home/user# python cur.py access.logОфлайн
43
имя файла не вводится
c = CursesLogViewer(infile)
Офлайн
0
sergeekС одной ошибкой помогло, зато теперь появилось следующее:
имя файла не вводится
Офлайн
0
да, ошибка по невнимательности, метод curses.LINES, но проблема в том, что программа запустилась, но выводит только последнюю строчку логов, а не весь лог целиком.
Офлайн
43
может
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()
Офлайн
0
sergeekспасибо) Только работать начал с python и пока проблемным является все эта идея с отступами, хоть и стараюсь следить.
может
Офлайн
43
Damassk
хорошие иде сами делают отступы, я, например, слежу только за окончанием отступа. И вообще никогда не делал ошибок из-за отступов, не понимаю как они могут создавать проблемы 
Офлайн
0
sergeekЭто все С, с его “пиши как хочу, компилятор все поймет”. тут все-таки структура важна, да и это быстро привыкнется)) стоит пописать недельки 2 и все) а отступы да, по большей части сами задаются, но вот иногда бывают такие казусы)
хорошие иде сами делают отступы, я, например, слежу только за окончанием отступа. И вообще никогда не делал ошибок из-за отступов, не понимаю как они могут создавать проблемы
Офлайн
43
после С бОльшая проблема скорее в том, что палец постоянно будет тянутся к клавише с `;' 
Офлайн
0
sergeekну это одна из проблем))))
после С бОльшая проблема скорее в том, что палец постоянно будет тянутся к клавише с `;'
Офлайн