2 Parsers for P2P logging information.
4 Built on previous work by Adriana Draghici, Razvan Deaconescu
7 2011, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro
16 import storage # Use *Message classes.
19 # Logging code heavily inspired by Logging HOWTO documentation:
20 # http://docs.python.org/dev/howto/logging.html#configuring-logging
23 # Create logger; default logging level is DEBUG.
24 logger = logging.getLogger(__name__)
25 logger.setLevel(logging.DEBUG)
27 # Create console handler and set level to ERROR.
28 ch = logging.StreamHandler()
29 ch.setLevel(logging.DEBUG)
32 formatter = logging.Formatter('%(filename)s:%(lineno)s - %(levelname)s: %(message)s')
34 # Add formatter to console handler.
35 ch.setFormatter(formatter)
37 # Add console handler to logger.
40 class SessionLogParser(object):
42 Top-level class for parsing log file(s) for a given BitTorrent session.
45 def __init__(self, path):
47 # parsing: file currently being parsed
50 def get_next_message(self):
52 Find next message in log file/folder. May be status, peer status
54 Return None when all logs have been parsed.
58 def get_current_parsing_filename():
59 """Return the name of the log file being currently parsed."""
63 class LibtorrentLogParser(SessionLogParser):
65 libtorrent-rasterbar log folder parser.
68 def __init__(self, path, priority=None):
70 If priority == "verbose" parse verbose log files first. Else, parse
73 super(LibtorrentLogParser, self).__init__(path)
75 # to_parse: list of files to be parsed
76 # have_parsed: list of files that have been parsed
80 self.f = None # handler to file being parsed
82 for entry in os.listdir(self.path):
83 entry_path = os.path.join(self.path, entry)
84 if os.path.isfile(entry_path):
85 # TODO: If entry is file and name is IP_PORT.log add it to list.
87 self.to_parse.append(entry_path)
89 status_file_path = os.path.join(self.path, "status.log")
90 # TODO: Check if status file exists and is a file.
92 # List functions as a stack. First files go to the end.
93 if priority == "verbose":
94 self.to_parse.insert(0, status_file_path)
96 self.to_parse.append(status_file_path)
100 def open_next_file(self):
102 Open next log file from to_parse list.
103 Update have_parsed and parsing accordingly.
105 if self.parsing is None: # first call
109 self.have_parsed.append(parsing)
111 parsing = self.to_parse.pop()
112 self.f = open(parsing, 'r')
114 # TODO: Log this information somewhere for snapshotting purpose.
115 # In case an error occurs parsing would resume from that point.
117 def is_status_log_line(self):
120 def is_peer_status_log_line(self):
123 def is_verbose_log_line(self):
126 def parse_status_log_line(self):
129 def parse_peer_status_log_line(self):
132 def parse_verbose_log_line(self):
135 def parse_log_line(self, line):
136 """Parse a log line and establish its type.
138 Type may be status, verbose or peer status.
139 Return message in line, in case of message line, or None in case
140 of no message line."""
142 # Check log line type and call appropriate method.
143 if self.is_status_log_line(line):
144 return self.parse_status_log_line(line)
145 elif self.is_peer_status_log_line(line):
146 return self.parse_peer_status_log_line(line)
147 elif self.is_verbose_log_line(line):
148 return self.parse_verbose_log_line(line)
150 # Return None in case of unknown/non-existent message type line.
153 def get_next_message(self):
155 Go through all files in libtorrent log folder and parse them.
156 Return the next message available or None when all log files have
160 while True: # Find first message.
161 while True: # Find first available file.
162 line = self.f.readline()
166 # end of file reached
168 self.open_next_file()
169 except IndexError, e:
170 # In case of no more files, return None.
175 msg = self.parse_log_line(line)
177 # Go around in case line is bogus (msg is None).
181 # Caller has to distinguish between message types.
185 class TriblerLogParser(SessionLogParser):
187 Tribler log file parser.
190 def __init__(self, path):
191 super(TriblerLogParser, self).__init__(path)
193 def get_next_message(self):
195 Go through Tribler log file. All log messages (verbose, status)
196 are stored in the same file.
197 Return the next message available or None when all messages have