Generator function that returns individual log events. Log events may be split over multiple lines. We use the timestamp regex match as the marker for a new log event.
(source, logfile)
| 142 | |
| 143 | |
| 144 | def get_log_events(source, logfile): |
| 145 | """Generator function that returns individual log events. |
| 146 | |
| 147 | Log events may be split over multiple lines. We use the timestamp |
| 148 | regex match as the marker for a new log event.""" |
| 149 | try: |
| 150 | with open(logfile, 'r', encoding='utf-8') as infile: |
| 151 | event = '' |
| 152 | timestamp = '' |
| 153 | for line in infile: |
| 154 | # skip blank lines |
| 155 | if line == '\n': |
| 156 | continue |
| 157 | # if this line has a timestamp, it's the start of a new log event. |
| 158 | time_match = TIMESTAMP_PATTERN.match(line) |
| 159 | if time_match: |
| 160 | if event: |
| 161 | yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) |
| 162 | timestamp = time_match.group() |
| 163 | if time_match.group(1) is None: |
| 164 | # timestamp does not have microseconds. Add zeroes. |
| 165 | timestamp_micro = timestamp.replace("Z", ".000000Z") |
| 166 | line = line.replace(timestamp, timestamp_micro) |
| 167 | timestamp = timestamp_micro |
| 168 | event = line |
| 169 | # if it doesn't have a timestamp, it's a continuation line of the previous log. |
| 170 | else: |
| 171 | # Add the line. Prefix with space equivalent to the source + timestamp so log lines are aligned |
| 172 | event += " " + line |
| 173 | # Flush the final event |
| 174 | yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) |
| 175 | except FileNotFoundError: |
| 176 | print("File %s could not be opened. Continuing without it." % logfile, file=sys.stderr) |
| 177 | |
| 178 | |
| 179 | def print_logs_plain(log_events, colors): |